Bug 1521187 - Add a dependency on derive_more. r=emilio
authorBobby Holley <bobbyholley@gmail.com>
Fri, 18 Jan 2019 12:32:22 -0800
changeset 514865 c229457d7726bd03b056d3e5921c1cc008459fbc
parent 514864 3bf9f045d452667c73dca317118fb56202437c41
child 514866 79fe3ef6306d5afb1feb69c323b62a932f9fd95d
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs1521187
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1521187 - Add a dependency on derive_more. r=emilio Differential Revision: https://phabricator.services.mozilla.com/D17028
Cargo.lock
gfx/wr/Cargo.lock
gfx/wr/webrender_api/Cargo.toml
servo/components/selectors/Cargo.toml
servo/components/style/Cargo.toml
third_party/rust/derive_more/.cargo-checksum.json
third_party/rust/derive_more/CHANGELOG.md
third_party/rust/derive_more/Cargo.toml
third_party/rust/derive_more/LICENSE
third_party/rust/derive_more/README.md
third_party/rust/derive_more/src/add_assign_like.rs
third_party/rust/derive_more/src/add_like.rs
third_party/rust/derive_more/src/constructor.rs
third_party/rust/derive_more/src/deref.rs
third_party/rust/derive_more/src/deref_mut.rs
third_party/rust/derive_more/src/display.rs
third_party/rust/derive_more/src/from.rs
third_party/rust/derive_more/src/from_str.rs
third_party/rust/derive_more/src/index.rs
third_party/rust/derive_more/src/index_mut.rs
third_party/rust/derive_more/src/into.rs
third_party/rust/derive_more/src/lib.rs
third_party/rust/derive_more/src/mul_assign_like.rs
third_party/rust/derive_more/src/mul_like.rs
third_party/rust/derive_more/src/not_like.rs
third_party/rust/derive_more/src/try_into.rs
third_party/rust/derive_more/src/utils.rs
third_party/rust/rustc_version/.cargo-checksum.json
third_party/rust/rustc_version/Cargo.toml
third_party/rust/rustc_version/README.md
third_party/rust/rustc_version/src/lib.rs
third_party/rust/semver-0.6.0/.cargo-checksum.json
third_party/rust/semver-0.6.0/Cargo.toml
third_party/rust/semver-0.6.0/LICENSE-APACHE
third_party/rust/semver-0.6.0/LICENSE-MIT
third_party/rust/semver-0.6.0/README.md
third_party/rust/semver-0.6.0/src/lib.rs
third_party/rust/semver-0.6.0/src/version.rs
third_party/rust/semver-0.6.0/src/version_req.rs
third_party/rust/semver-0.6.0/tests/deprecation.rs
third_party/rust/semver-0.6.0/tests/regression.rs
third_party/rust/semver/.cargo-checksum.json
third_party/rust/semver/Cargo.toml
third_party/rust/semver/README.md
third_party/rust/semver/src/lib.rs
third_party/rust/semver/src/version.rs
third_party/rust/semver/src/version_req.rs
third_party/rust/semver/tests/serde.rs
toolkit/library/rust/shared/Cargo.toml
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -731,16 +731,27 @@ version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "darling_core 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 0.15.24 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "derive_more"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.24 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "devd-rs"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1108,17 +1119,17 @@ dependencies = [
  "mp4parse_capi 0.11.2",
  "netwerk_helper 0.0.1",
  "nserror 0.1.0",
  "nsstring 0.1.0",
  "prefs_parser 0.0.1",
  "profiler_helper 0.1.0",
  "rkv 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rsdparsa_capi 0.1.0",
- "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "u2fhid 0.2.3",
  "webrender_bindings 0.1.0",
  "xpcom 0.1.0",
 ]
 
 [[package]]
 name = "gl_generator"
 version = "0.10.0"
@@ -2180,20 +2191,20 @@ source = "registry+https://github.com/ru
 
 [[package]]
 name = "rustc-demangle"
 version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "rustc_version"
-version = "0.2.1"
+version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "ryu"
 version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -2219,17 +2230,17 @@ name = "scopeguard"
 version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "scroll"
 version = "0.9.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "scroll_derive 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "scroll_derive"
 version = "0.9.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
@@ -2239,16 +2250,17 @@ dependencies = [
 ]
 
 [[package]]
 name = "selectors"
 version = "0.21.0"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "cssparser 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "servo_arc 0.1.1",
  "smallvec 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2259,16 +2271,24 @@ dependencies = [
 name = "semver"
 version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "semver"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "semver-parser"
 version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "serde"
 version = "1.0.80"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2428,16 +2448,17 @@ version = "0.0.1"
 dependencies = [
  "app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "arrayvec 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bindgen 0.43.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "cssparser 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "fallible 0.0.1",
  "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "hashglobe 0.1.0",
  "indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3027,16 +3048,17 @@ name = "webrender_api"
 version = "0.58.0"
 dependencies = [
  "app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "dwrote 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)",
  "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "wr_malloc_size_of 0.0.1",
@@ -3264,16 +3286,17 @@ dependencies = [
 "checksum cstr-macros 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0472c17c83d3ec1af32fb6ee2b3ad56ae0b6e69355d63d1d30602055c34324a8"
 "checksum cubeb 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8a3502aafa1bf95c524f65d2ba46d8741700c6a8a9543ea52c6da3d8b69a2896"
 "checksum cubeb-backend 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdcac95519416d9ec814db2dc40e6293e7da25b906023d93f48b87f0587ab138"
 "checksum cubeb-core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37f7b20f757a4e4b6aa28863236551bff77682dc6db192eba15af615492b5445"
 "checksum cubeb-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "653b9e245d35dbe2a2da7c4586275cee75ff656ddeb02d4a73b4afdfa6d67502"
 "checksum darling 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f593353cad5af2df6d54810de2b61aa8acba5b5fbc70b0d75e7cc5bdd80aca73"
 "checksum darling_core 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "168c246e87e727d58575d9b4595491010627f0cdc910e3e6ea3b36db2b9a9d9a"
 "checksum darling_macro 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "99c4eff4bcbeaf6a22578012ff79c95910338668278d1901e528bd34a22f575d"
+"checksum derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f57d78cf3bd45270dad4e70c21ec77a960b36c7a841ff9db76aaa775a8fb871"
 "checksum devd-rs 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e7c9ac481c38baf400d3b732e4a06850dfaa491d1b6379a249d9d40d14c2434c"
 "checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a"
 "checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"
 "checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c"
 "checksum dirs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "88972de891f6118092b643d85a0b28e0678e0f948d7f879aa32f2d5aafe97d2a"
 "checksum docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d8acd393692c503b168471874953a2531df0e9ab77d0b6bbc582395743300a4a"
 "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
 "checksum dtoa-short 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "068d4026697c1a18f0b0bb8cfcad1b0c151b90d8edb9bf4c235ad68128920d1d"
@@ -3397,25 +3420,26 @@ dependencies = [
 "checksum regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75ecf88252dce580404a22444fc7d626c01815debba56a7f4f536772a5ff19d3"
 "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db"
 "checksum regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1ac0f60d675cc6cf13a20ec076568254472551051ad5dd050364d70671bf6b"
 "checksum rkv 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "663e50c3b2454387726a83b01629892824dcf113c0471841ea4bc9b5929eb75e"
 "checksum ron 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "da06feaa07f69125ab9ddc769b11de29090122170b402547f64b86fe16ebc399"
 "checksum runloop 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d79b4b604167921892e84afbbaad9d5ad74e091bf6c511d9dbfb0593f09fabd"
 "checksum rust-ini 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8a654c5bda722c699be6b0fe4c0d90de218928da5b724c3e467fc48865c37263"
 "checksum rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "76d7ba1feafada44f2d38eed812bd2489a03c0f5abb975799251518b68848649"
-"checksum rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9743a7670d88d5d52950408ecdb7c71d8986251ab604d4689dd2ca25c9bca69"
+"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
 "checksum ryu 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "fd0568787116e13c652377b6846f5931454a363a8fdf8ae50463ee40935b278b"
 "checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637"
 "checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d"
 "checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
 "checksum scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c79eb2c3ac4bc2507cda80e7f3ac5b88bd8eae4c0914d5663e6a8933994be918"
 "checksum scroll 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2f84d114ef17fd144153d608fba7c446b0145d038985e7a8cc5d08bb0ce20383"
 "checksum scroll_derive 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1aa96c45e7f5a91cb7fabe7b279f02fea7126239fc40b732316e8b6a2d0fcb"
 "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
+"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
 "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
 "checksum serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "15c141fc7027dd265a47c090bf864cf62b42c4d228bbcf4e51a0c9e2b0d3f7ef"
 "checksum serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)" = "adb6e51a6b3696b301bc221d785f898b4457c619b51d7ce195a6d20baecb37b3"
 "checksum serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)" = "<none>"
 "checksum serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "44dd2cfde475037451fa99b7e5df77aa3cfd1536575fa8e7a538ab36dcde49ae"
 "checksum sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0"
 "checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d"
 "checksum simd 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0048b17eb9577ac545c61d85c3559b41dfb4cbea41c9bd9ca6a4f73ff05fda84"
--- a/gfx/wr/Cargo.lock
+++ b/gfx/wr/Cargo.lock
@@ -322,16 +322,27 @@ name = "deflate"
 version = "0.7.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "derive_more"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.17 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "digest"
 version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -758,17 +769,17 @@ dependencies = [
  "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "malloc_size_of_derive"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 0.15.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "matches"
 version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -862,17 +873,17 @@ version = "0.1.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "num-derive"
 version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 0.15.17 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "num-integer"
 version = "0.1.38"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1051,33 +1062,33 @@ dependencies = [
  "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "deflate 0.7.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "inflate 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "proc-macro2"
-version = "0.4.6"
+version = "0.4.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "quick-error"
 version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "quote"
 version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rand"
 version = "0.3.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1178,31 +1189,52 @@ dependencies = [
 name = "ron"
 version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "rustc_version"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "safe-transmute"
 version = "0.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "scoped_threadpool"
 version = "0.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "scopeguard"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "semver"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "semver-parser"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
 name = "serde"
 version = "1.0.80"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)",
 ]
 
 [[package]]
@@ -1213,17 +1245,17 @@ dependencies = [
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "serde_derive"
 version = "1.0.80"
 source = "git+https://github.com/servo/serde?branch=deserialize_from_enums9#e0cc925c259cb74ce41377e4fe02713adfa6d836"
 dependencies = [
- "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 0.15.17 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "serde_json"
 version = "1.0.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1326,27 +1358,27 @@ name = "strsim"
 version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "syn"
 version = "0.15.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "synstructure"
 version = "0.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 0.15.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "tempfile"
 version = "3.0.2"
@@ -1623,16 +1655,17 @@ name = "webrender_api"
 version = "0.58.0"
 dependencies = [
  "app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "dwrote 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.19.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "ipc-channel 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)",
  "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1844,16 +1877,17 @@ dependencies = [
 "checksum crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "bd66663db5a988098a89599d4857919b3acf7f61402e61365acfd3919857b9be"
 "checksum crossbeam-channel 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6c0a94250b0278d7fc5a894c3d276b11ea164edc8bf8feb10ca1ea517b44a649"
 "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
 "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
 "checksum crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30fecfcac6abfef8771151f8be4abc9e4edc112c2bcb233314cafde2680536e9"
 "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
 "checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015"
 "checksum deflate 0.7.18 (registry+https://github.com/rust-lang/crates.io-index)" = "32c8120d981901a9970a3a1c97cf8b630e0fa8c3ca31e75b6fd6fd5f9f427b31"
+"checksum derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f57d78cf3bd45270dad4e70c21ec77a960b36c7a841ff9db76aaa775a8fb871"
 "checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c"
 "checksum dlib 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "77e51249a9d823a4cb79e3eca6dcd756153e8ed0157b6c04775d04bf1b13b76a"
 "checksum downcast-rs 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "18df8ce4470c189d18aa926022da57544f31e154631eb4cfe796aea97051fe6c"
 "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
 "checksum dwrote 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d2ea0fd88d96838ce5ed30326338cc04a0eb4cff10e3e15d188d74112777103"
 "checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
 "checksum env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0e6e40ebb0e66918a37b38c7acab4e10d299e0463fe2af5d29b9cc86710cfd2a"
 "checksum euclid 0.19.4 (registry+https://github.com/rust-lang/crates.io-index)" = "dbbf962bb6f877239a34491f2e0a12c6b824f389bc789eb90f1d70d4780b0727"
@@ -1927,34 +1961,37 @@ dependencies = [
 "checksum pathfinder_font_renderer 0.5.0 (git+https://github.com/pcwalton/pathfinder?branch=webrender)" = "<none>"
 "checksum pathfinder_gfx_utils 0.2.0 (git+https://github.com/pcwalton/pathfinder?branch=webrender)" = "<none>"
 "checksum pathfinder_partitioner 0.2.0 (git+https://github.com/pcwalton/pathfinder?branch=webrender)" = "<none>"
 "checksum pathfinder_path_utils 0.2.0 (git+https://github.com/pcwalton/pathfinder?branch=webrender)" = "<none>"
 "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
 "checksum pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "110d5ee3593dbb73f56294327fe5668bcc997897097cbc76b51e7aed3f52452f"
 "checksum plane-split 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9b1d9a84aa3bbc2dafd06856bdb1dc333eb1d442ad8987b9d596c7344b3ed969"
 "checksum png 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9adebf7fb91ccf5eac9da1a8e00e83cb8ae882c3e8d8e4ad59da73cb8c82a2c9"
-"checksum proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "effdb53b25cdad54f8f48843d67398f7ef2e14f12c1b4cb4effc549a6462a4d6"
+"checksum proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)" = "d3797b7142c9aa74954e351fc089bbee7958cebbff6bf2815e7ffff0b19f547d"
 "checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4"
 "checksum quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e44651a0dc4cdd99f71c83b561e221f714912d11af1a4dff0631f923d53af035"
 "checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1"
 "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
 "checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
 "checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2"
 "checksum rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80e811e76f1dbf68abf87a759083d34600017fc4e10b6bd5ad84a700f9dba4b1"
 "checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8"
 "checksum redox_syscall 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "0a12d51a5b5fd700e6c757f15877685bfa04fd7eb60c108f01d045cafa0073c2"
 "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
 "checksum regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75ecf88252dce580404a22444fc7d626c01815debba56a7f4f536772a5ff19d3"
 "checksum regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1ac0f60d675cc6cf13a20ec076568254472551051ad5dd050364d70671bf6b"
 "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
 "checksum ron 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "da06feaa07f69125ab9ddc769b11de29090122170b402547f64b86fe16ebc399"
+"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
 "checksum safe-transmute 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9604873ffe1980bc1f179103704a65c8aca141c248d9e52b7af95ff10578166e"
 "checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
 "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
+"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
+"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
 "checksum serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "15c141fc7027dd265a47c090bf864cf62b42c4d228bbcf4e51a0c9e2b0d3f7ef"
 "checksum serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)" = "adb6e51a6b3696b301bc221d785f898b4457c619b51d7ce195a6d20baecb37b3"
 "checksum serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)" = "<none>"
 "checksum serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f3ad6d546e765177cf3dded3c2e424a8040f870083a0e64064746b958ece9cb1"
 "checksum servo-fontconfig 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a088f8d775a5c5314aae09bd77340bc9c67d72b9a45258be34c83548b4814cd9"
 "checksum servo-fontconfig-sys 4.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "38b494f03009ee81914b0e7d387ad7c145cafcd69747c2ec89b0e17bb94f303a"
 "checksum servo-freetype-sys 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4ccb6d0d32d277d3ef7dea86203d8210945eb7a45fba89dd445b3595dd0dfc"
 "checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c"
--- a/gfx/wr/webrender_api/Cargo.toml
+++ b/gfx/wr/webrender_api/Cargo.toml
@@ -12,16 +12,17 @@ ipc = ["ipc-channel"]
 serialize = []
 deserialize = []
 
 [dependencies]
 app_units = "0.7"
 bincode = "1.0"
 bitflags = "1.0"
 byteorder = "1.2.1"
+derive_more = "0.13"
 ipc-channel = {version = "0.11.0", optional = true}
 euclid = { version = "0.19.4", features = ["serde"] }
 malloc_size_of_derive = "0.1"
 serde = { version = "=1.0.80", features = ["rc"] }
 serde_derive = { version = "=1.0.80", features = ["deserialize_in_place"] }
 serde_bytes = "0.10"
 time = "0.1"
 wr_malloc_size_of = { version = "0.0.1", path = "../wr_malloc_size_of" }
--- a/servo/components/selectors/Cargo.toml
+++ b/servo/components/selectors/Cargo.toml
@@ -18,16 +18,17 @@ path = "lib.rs"
 
 [features]
 bench = []
 
 [dependencies]
 bitflags = "1.0"
 matches = "0.1"
 cssparser = "0.25"
+derive_more = "0.13"
 log = "0.4"
 fxhash = "0.2"
 phf = "0.7.18"
 precomputed-hash = "0.1"
 servo_arc = { version = "0.1", path = "../servo_arc" }
 smallvec = "0.6"
 thin-slice = "0.1.0"
 
--- a/servo/components/style/Cargo.toml
+++ b/servo/components/style/Cargo.toml
@@ -26,16 +26,17 @@ gecko_debug = []
 [dependencies]
 app_units = "0.7"
 arrayvec = "0.4.6"
 atomic_refcell = "0.1"
 bitflags = "1.0"
 byteorder = "1.0"
 cssparser = "0.25"
 crossbeam-channel = { version = "0.3", optional = true }
+derive_more = "0.13"
 new_debug_unreachable = "1.0"
 encoding_rs = {version = "0.8", optional = true}
 euclid = "0.19"
 fallible = { path = "../fallible" }
 fxhash = "0.2"
 hashglobe = { path = "../hashglobe" }
 html5ever = {version = "0.22", optional = true}
 indexmap = "1.0"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/derive_more/.cargo-checksum.json
@@ -0,0 +1,1 @@
+{"files":{"CHANGELOG.md":"8dd6b99908dd99a77f73de68804735d44c7e5d2164cec1661d74c6da97348824","Cargo.toml":"7fa9a84baf9411a5d9b3f5ed32571ac14f5dd0d92b045e5db13216c8a7ae86f1","LICENSE":"8a35369f3ca263b3c62fbb5032947e53b6bfebc6c8a4d1bb982de1c069f6fba5","README.md":"239e573158b39cb25609bfe6281fc50f7b34ed87e6ba602aa8e8df53309850b0","src/add_assign_like.rs":"eac655e68e5b1af22bb93825814969be9fd8877ce2c3ded01656809afe8f0e45","src/add_like.rs":"2ca7dd6fd22b29a374310ff59dd4186f8e8e0c044b0cded951406ae4b3edcdb3","src/constructor.rs":"6a434160d3841445876bc76edd55a81ea5f4b6016f288d8d8d89d407c9b50db7","src/deref.rs":"921a44cc335ca76109a1f921152602abee9bdc72503e31985cf8d6ee67c3676e","src/deref_mut.rs":"67c0d22344c9a0f7ee25e68af7b55930dbd661b810a8dc1b8915c622ea933494","src/display.rs":"24e26eb561c1e6a019bfb82d5c071577976ad74108c38eba3cc3659fc725fbea","src/from.rs":"c86e2a90fedbcd132e4d71694a3bf6ee21475a28f44b9421af1b737956c16302","src/from_str.rs":"cb47df454bf4ec27f1fce1cd5224bca47d745822cd8083a6eb99c989c11b1db8","src/index.rs":"b9999b321c0c87c8516c91bfd92cb74f9d13f830301a6fe760f798665885601f","src/index_mut.rs":"5e41bdc106a48dade5d7696a19b174bcdbd8bc86152375941c49684c9d861e4b","src/into.rs":"4b561410460c13b51f168f9544bbf73912e11a6af6152fae8925f059a7fe004d","src/lib.rs":"5c2d1a965fbcd67deabf27394ce85a6772321c3011ab646281274a39f9e6b5ee","src/mul_assign_like.rs":"7c9e11288f7296d2854a167749232e748467cd2a2859bea7bef10f26d4c91584","src/mul_like.rs":"bac8745c58850e47d583d3f8be2886b13424abcb8fadcfcdd63b9dfb458f61b8","src/not_like.rs":"ed4fa1201aac47673e9f7842bb184747beddea195a7cedaaf56716751e9b732c","src/try_into.rs":"18992d9aa567960f5616b020e78bbd6e56191c799d88bcd379ce837a600bd169","src/utils.rs":"843a3bac04601d2f6158fbd27f9e1c54987ee4801dddb069fbe4436a4b89660f"},"package":"3f57d78cf3bd45270dad4e70c21ec77a960b36c7a841ff9db76aaa775a8fb871"}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/third_party/rust/derive_more/CHANGELOG.md
@@ -0,0 +1,106 @@
+# Change Log
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](http://keepachangelog.com/)
+and this project adheres to [Semantic Versioning](http://semver.org/).
+
+## 0.13.0 - 2018-10-19
+- Updated to `syn` v0.15
+- Extended Display-like derives to support custom formats
+
+## 0.12.0 - 2018-09-19
+
+### Changed
+- Updated to `syn` v0.14, `quote` v0.6 and `proc-macro2` v0.4
+
+## 0.11.0 - 2018-05-12
+
+### Changed
+- Updated to latest version of `syn` and `quote`
+
+### Fixed
+- Changed some URLs in the docs so they were correct on crates.io and docs.rs
+- The `Result` type is now referenced in the derives using its absolute path
+  (`::std::result::Result`) to make sure that the derives don't accidentally use
+  another `Result` type that is in scope.
+
+## 0.10.0 - 2018-03-29
+
+### Added
+- Allow deriving of `TryInto`
+- Allow deriving of `Deref`
+- Allow deriving of `DerefMut`
+
+## 0.9.0 - 2018-03-18
+
+### Added
+- Allow deriving of `Display`, `Binary`, `Octal`, `LowerHex`, `UpperHex`, `LowerExp`, `UpperExp`, `Pointer`
+- Allow deriving of `Index`
+- Allow deriving of `IndexMut`
+
+### Fixed
+- Allow cross crate inlining of derived methods
+
+### Internal changes
+- Fix most `clippy` warnings
+
+## 0.8.0 - 2018-03-10
+
+### Added
+- Allow deriving of `FromStr`
+
+### Changed
+- Updated to latest version of `syn` and `quote`
+
+## 0.7.1 - 2018-01-25
+
+### Fixed
+- Add `#[allow(missing_docs)]` to the Constructor definition
+
+### Internal changes
+- Run `rustfmt` on the code
+
+
+## 0.7.0 - 2017-07-25
+
+### Changed
+- Changed code to work with newer version of the `syn` library.
+
+## 0.6.2 - 2017-04-23
+
+### Changed
+- Deriving `From`, `Into` and `Constructor` now works for empty structs.
+
+
+## 0.6.1 - 2017-03-08
+
+### Changed
+- The `new()` method that is created when deriving `Constructor` is now public.
+  This makes it a lot more useful.
+
+
+## 0.6.0 - 2017-02-20
+
+### Added
+
+- Derives for `Into`, `Constructor` and `MulAssign`-like
+
+### Changed
+
+- `From` is now derived for enum variants with multiple fields.
+
+### Fixed
+
+- Derivations now support generics.
+
+
+## 0.5.0 - 2017-02-02
+
+### Added
+
+- Lots of docs.
+- Derives for `Neg`-like and `AddAssign`-like.
+
+### Changed
+- `From` can now be derived for structs with multiple fields.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/derive_more/Cargo.toml
@@ -0,0 +1,47 @@
+# 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
+#
+# 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]
+name = "derive_more"
+version = "0.13.0"
+authors = ["Jelte Fennema <github-tech@jeltef.nl>"]
+include = ["src/**/*.rs", "Cargo.toml", "LICENSE", "README.md", "CHANGELOG.md"]
+description = "Adds #[derive(x)] macros for more traits"
+documentation = "https://jeltef.github.io/derive_more/derive_more/"
+readme = "README.md"
+keywords = ["derive", "Add", "From", "Constructor", "implementation"]
+categories = ["development-tools", "development-tools::procedural-macro-helpers"]
+license = "MIT"
+repository = "https://github.com/JelteF/derive_more"
+
+[lib]
+name = "derive_more"
+proc-macro = true
+[dependencies.proc-macro2]
+version = "0.4.19"
+
+[dependencies.quote]
+version = "0.6"
+
+[dependencies.syn]
+version = "0.15"
+features = ["extra-traits"]
+[build-dependencies.rustc_version]
+version = "0.2.2"
+
+[features]
+nightly = []
+[badges.appveyor]
+repository = "JelteF/derive_more"
+
+[badges.travis-ci]
+repository = "JelteF/derive_more"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/derive_more/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Jelte Fennema
+
+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.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/derive_more/README.md
@@ -0,0 +1,184 @@
+# `derive_more`
+
+[![Build Status](https://api.travis-ci.org/JelteF/derive_more.svg?branch=master)](https://travis-ci.org/JelteF/derive_more)
+[![Latest Version](https://img.shields.io/crates/v/derive_more.svg)](https://crates.io/crates/derive_more)
+[![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)](https://jeltef.github.io/derive_more/derive_more/)
+[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/JelteF/derive_more/master/LICENSE)
+
+Rust has lots of builtin traits that are implemented for its basic types, such as [`Add`],
+[`Not`] or [`From`].
+However, when wrapping these types inside your own structs or enums you lose the
+implementations of these traits and are required to recreate them.
+This is especially annoying when your own structures are very simple, such as when using the
+commonly advised newtype pattern (e.g. `MyInt(i32)`).
+
+This library tries to remove these annoyances and the corresponding boilerplate code.
+It does this by allowing you to derive lots of commonly used traits for both structs and enums.
+
+## Example code
+
+By using this library the following code just works:
+
+
+```rust
+#[macro_use]
+extern crate derive_more;
+
+#[derive(Debug, Eq, PartialEq, From, Add)]
+struct MyInt(i32);
+
+#[derive(Debug, Eq, PartialEq, From, Into, Constructor, Mul)]
+struct Point2D {
+    x: i32,
+    y: i32,
+}
+
+#[derive(Debug, Eq, PartialEq, From, Add)]
+enum MyEnum {
+    Int(i32),
+    UnsignedInt(u32),
+    Nothing,
+}
+
+fn main() {
+    let my_11 = MyInt(5) + 6.into();
+    assert_eq!(MyInt(11), MyInt(5) + 6.into());
+    assert_eq!(Point2D { x: 5, y: 6 } * 10, (50, 60).into());
+    assert_eq!((5, 6), Point2D { x: 5, y: 6 }.into());
+    assert_eq!(Point2D { x: 5, y: 6 }, Point2D::new(5, 6));
+    assert_eq!(MyEnum::Int(15), (MyEnum::Int(8) + 7.into()).unwrap())
+}
+```
+
+## The derivable traits
+
+Below are all the traits that you can derive using this library.
+Some trait derivations are so similar that the further documentation will only show a single one
+of them.
+You can recognize these by the "-like" suffix in their name.
+The trait name before that will be the only one that is used throughout the further
+documentation.
+
+**NOTE**: You still have to derive each trait separately. So `#[derive(Mul)]` doesn't
+automatically derive `Div` as well. To derive both you should do `#[derive(Mul, Div)]`
+
+### Conversion traits
+These are traits that are used to convert automatically between types.
+
+1. [`From`]
+2. [`Into`]
+3. [`FromStr`]
+4. [`TryInto`] (nightly-only as of writing)
+
+### Formatting traits
+These traits are used for converting a struct to a string in different ways.
+
+1. `Display`-like, contains [`Display`], [`Binary`], [`Octal`], [`LowerHex`], [`UpperHex`],
+   [`LowerExp`], [`UpperExp`], [`Pointer`]
+
+### Operators
+These are traits that can be used for operator overloading.
+
+1. [`Index`]
+2. [`Deref`]
+3. `Not`-like, contains [`Not`] and [`Neg`]
+4. `Add`-like, contains [`Add`], [`Sub`], [`BitAnd`], [`BitOr`] and [`BitXor`]
+5. `Mul`-like, contains [`Mul`], [`Div`], [`Rem`], [`Shr`] and [`Shl`]
+6. [`IndexMut`]
+7. [`DerefMut`]
+8. `AddAssign`-like, contains [`AddAssign`], [`SubAssign`], [`BitAndAssign`], [`BitOrAssign`]
+   and [`BitXorAssign`]
+9. `MulAssign`-like, contains [`MulAssign`], [`DivAssign`], [`RemAssign`], [`ShrAssign`] and
+   [`ShlAssign`]
+
+### Static methods
+These don't derive traits, but derive static methods instead.
+
+1. `Constructor`, this derives a `new` method that can be used as a constructor. This is very
+   basic if you need more customization for your constructor, check out the [`derive-new`] crate.
+
+
+## Generated code
+
+It is important to understand what code gets generated when using one of the derives from this
+crate.
+That is why the links below explain what code gets generated for a trait for each group from
+before.
+
+1. [`#[derive(From)]`](https://jeltef.github.io/derive_more/derive_more/from.html)
+2. [`#[derive(Into)]`](https://jeltef.github.io/derive_more/derive_more/into.html)
+3. [`#[derive(FromStr)]`](https://jeltef.github.io/derive_more/derive_more/from_str.html)
+4. [`#[derive(TryInto)]`](https://jeltef.github.io/derive_more/derive_more/try_into.html)
+5. [`#[derive(Display)]`](https://jeltef.github.io/derive_more/derive_more/display.html)
+6. [`#[derive(Index)]`](https://jeltef.github.io/derive_more/derive_more/index_op.html)
+7. [`#[derive(Deref)]`](https://jeltef.github.io/derive_more/derive_more/deref.html)
+8. [`#[derive(Not)]`](https://jeltef.github.io/derive_more/derive_more/not.html)
+9. [`#[derive(Add)]`](https://jeltef.github.io/derive_more/derive_more/add.html)
+10. [`#[derive(Mul)]`](https://jeltef.github.io/derive_more/derive_more/mul.html)
+11. [`#[derive(IndexMut)]`](https://jeltef.github.io/derive_more/derive_more/index_mut.html)
+12. [`#[derive(DerefMut)]`](https://jeltef.github.io/derive_more/derive_more/deref_mut.html)
+13. [`#[derive(AddAssign)]`](https://jeltef.github.io/derive_more/derive_more/add_assign.html)
+14. [`#[derive(MulAssign)]`](https://jeltef.github.io/derive_more/derive_more/mul_assign.html)
+15. [`#[derive(Constructor)]`](https://jeltef.github.io/derive_more/derive_more/constructor.html)
+
+If you want to be sure what code is generated for your specific type I recommend using the
+[`cargo-expand`] utility.
+This will show you your code with all macros and derives expanded.
+
+## Installation
+
+This library requires Rust 1.15 or higher, so this needs to be installed.
+Then add the following to `Cargo.toml`:
+
+```toml
+[dependencies]
+derive_more = "0.13.0"
+```
+
+And this to the top of your Rust file:
+
+```rust
+#[macro_use]
+extern crate derive_more;
+```
+
+[`cargo-expand`]: https://github.com/dtolnay/cargo-expand
+[`derive-new`]: https://github.com/nrc/derive-new
+[`From`]: https://doc.rust-lang.org/core/convert/trait.From.html
+[`Into`]: https://doc.rust-lang.org/core/convert/trait.Into.html
+[`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html
+[`TryInto`]: https://doc.rust-lang.org/core/convert/trait.TryInto.html
+[`Display`]: https://doc.rust-lang.org/std/fmt/trait.Display.html
+[`Binary`]: https://doc.rust-lang.org/std/fmt/trait.Binary.html
+[`Octal`]: https://doc.rust-lang.org/std/fmt/trait.Octal.html
+[`LowerHex`]: https://doc.rust-lang.org/std/fmt/trait.LowerHex.html
+[`UpperHex`]: https://doc.rust-lang.org/std/fmt/trait.UpperHex.html
+[`LowerExp`]: https://doc.rust-lang.org/std/fmt/trait.LowerExp.html
+[`UpperExp`]: https://doc.rust-lang.org/std/fmt/trait.UpperExp.html
+[`Pointer`]: https://doc.rust-lang.org/std/fmt/trait.Pointer.html
+[`Index`]: https://doc.rust-lang.org/std/ops/trait.Index.html
+[`Deref`]: https://doc.rust-lang.org/std/ops/trait.Deref.html
+[`Not`]: https://doc.rust-lang.org/std/ops/trait.Not.html
+[`Neg`]: https://doc.rust-lang.org/std/ops/trait.Neg.html
+[`Add`]: https://doc.rust-lang.org/std/ops/trait.Add.html
+[`Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html
+[`BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html
+[`BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html
+[`BitXor`]: https://doc.rust-lang.org/std/ops/trait.BitXor.html
+[`Mul`]: https://doc.rust-lang.org/std/ops/trait.Mul.html
+[`Div`]: https://doc.rust-lang.org/std/ops/trait.Div.html
+[`Rem`]: https://doc.rust-lang.org/std/ops/trait.Rem.html
+[`Shr`]: https://doc.rust-lang.org/std/ops/trait.Shr.html
+[`Shl`]: https://doc.rust-lang.org/std/ops/trait.Shl.html
+[`IndexMut`]: https://doc.rust-lang.org/std/ops/trait.IndexMut.html
+[`DerefMut`]: https://doc.rust-lang.org/std/ops/trait.DerefMut.html
+[`AddAssign`]: https://doc.rust-lang.org/std/ops/trait.AddAssign.html
+[`SubAssign`]: https://doc.rust-lang.org/std/ops/trait.SubAssign.html
+[`BitAndAssign`]: https://doc.rust-lang.org/std/ops/trait.BitAndAssign.html
+[`BitOrAssign`]: https://doc.rust-lang.org/std/ops/trait.BitOrAssign.html
+[`BitXorAssign`]: https://doc.rust-lang.org/std/ops/trait.BitXorAssign.html
+[`MulAssign`]: https://doc.rust-lang.org/std/ops/trait.MulAssign.html
+[`DivAssign`]: https://doc.rust-lang.org/std/ops/trait.DivAssign.html
+[`RemAssign`]: https://doc.rust-lang.org/std/ops/trait.RemAssign.html
+[`ShrAssign`]: https://doc.rust-lang.org/std/ops/trait.ShrAssign.html
+[`ShlAssign`]: https://doc.rust-lang.org/std/ops/trait.ShlAssign.html
new file mode 100644
--- /dev/null
+++ b/third_party/rust/derive_more/src/add_assign_like.rs
@@ -0,0 +1,36 @@
+use add_like::{struct_exprs, tuple_exprs};
+use proc_macro2::{Span, TokenStream};
+use syn::{Data, DeriveInput, Fields, Ident};
+use utils::{add_extra_ty_param_bound_op, named_to_vec, unnamed_to_vec};
+
+pub fn expand(input: &DeriveInput, trait_name: &str) -> TokenStream {
+    let trait_ident = Ident::new(trait_name, Span::call_site());
+    let method_name = trait_name.to_string();
+    let method_name = method_name.trim_right_matches("Assign");
+    let method_name = method_name.to_lowercase();
+    let method_ident = Ident::new(&(method_name.to_string() + "_assign"), Span::call_site());
+    let input_type = &input.ident;
+
+    let generics = add_extra_ty_param_bound_op(&input.generics, &trait_ident);
+    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
+
+    let exprs = match input.data {
+        Data::Struct(ref data_struct) => match data_struct.fields {
+            Fields::Unnamed(ref fields) => tuple_exprs(&unnamed_to_vec(fields), &method_ident),
+            Fields::Named(ref fields) => struct_exprs(&named_to_vec(fields), &method_ident),
+            _ => panic!(format!("Unit structs cannot use derive({})", trait_name)),
+        },
+
+        _ => panic!(format!("Only structs can use derive({})", trait_name)),
+    };
+
+    quote!(
+        impl#impl_generics ::std::ops::#trait_ident for #input_type#ty_generics #where_clause {
+            #[inline]
+            fn #method_ident(&mut self, rhs: #input_type#ty_generics) {
+                #(#exprs;
+                  )*
+            }
+        }
+    )
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/derive_more/src/add_like.rs
@@ -0,0 +1,158 @@
+use proc_macro2::{Span, TokenStream};
+use quote::ToTokens;
+use std::iter;
+use syn::{Data, DataEnum, DeriveInput, Field, Fields, Ident, Index};
+use utils::{
+    add_extra_type_param_bound_op_output, field_idents, named_to_vec, numbered_vars, unnamed_to_vec,
+};
+
+pub fn expand(input: &DeriveInput, trait_name: &str) -> TokenStream {
+    let trait_ident = Ident::new(trait_name, Span::call_site());
+    let method_name = trait_name.to_lowercase();
+    let method_ident = Ident::new(&method_name, Span::call_site());
+    let input_type = &input.ident;
+
+    let generics = add_extra_type_param_bound_op_output(&input.generics, &trait_ident);
+    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
+
+    let (output_type, block) = match input.data {
+        Data::Struct(ref data_struct) => match data_struct.fields {
+            Fields::Unnamed(ref fields) => (
+                quote!(#input_type#ty_generics),
+                tuple_content(input_type, &unnamed_to_vec(fields), &method_ident),
+            ),
+            Fields::Named(ref fields) => (
+                quote!(#input_type#ty_generics),
+                struct_content(input_type, &named_to_vec(fields), &method_ident),
+            ),
+            _ => panic!(format!("Unit structs cannot use derive({})", trait_name)),
+        },
+        Data::Enum(ref data_enum) => (
+            quote!(::std::result::Result<#input_type#ty_generics, &'static str>),
+            enum_content(input_type, data_enum, &method_ident),
+        ),
+
+        _ => panic!(format!(
+            "Only structs and enums can use derive({})",
+            trait_name
+        )),
+    };
+
+    quote!(
+        impl#impl_generics ::std::ops::#trait_ident for #input_type#ty_generics #where_clause {
+            type Output = #output_type;
+            #[inline]
+            fn #method_ident(self, rhs: #input_type#ty_generics) -> #output_type {
+                #block
+            }
+        }
+    )
+}
+
+fn tuple_content<T: ToTokens>(
+    input_type: &T,
+    fields: &[&Field],
+    method_ident: &Ident,
+) -> TokenStream {
+    let exprs = tuple_exprs(fields, method_ident);
+    quote!(#input_type(#(#exprs),*))
+}
+
+pub fn tuple_exprs(fields: &[&Field], method_ident: &Ident) -> Vec<TokenStream> {
+    let mut exprs = vec![];
+
+    for i in 0..fields.len() {
+        let i = Index::from(i);
+        // generates `self.0.add(rhs.0)`
+        let expr = quote!(self.#i.#method_ident(rhs.#i));
+        exprs.push(expr);
+    }
+    exprs
+}
+
+fn struct_content(input_type: &Ident, fields: &[&Field], method_ident: &Ident) -> TokenStream {
+    // It's safe to unwrap because struct fields always have an identifier
+    let exprs = struct_exprs(fields, method_ident);
+    let field_names = field_idents(fields);
+
+    quote!(#input_type{#(#field_names: #exprs),*})
+}
+
+pub fn struct_exprs(fields: &[&Field], method_ident: &Ident) -> Vec<TokenStream> {
+    let mut exprs = vec![];
+
+    for field in fields {
+        // It's safe to unwrap because struct fields always have an identifier
+        let field_id = field.ident.as_ref().unwrap();
+        // generates `x: self.x.add(rhs.x)`
+        let expr = quote!(self.#field_id.#method_ident(rhs.#field_id));
+        exprs.push(expr)
+    }
+    exprs
+}
+
+fn enum_content(input_type: &Ident, data_enum: &DataEnum, method_ident: &Ident) -> TokenStream {
+    let mut matches = vec![];
+    let mut method_iter = iter::repeat(method_ident);
+
+    for variant in &data_enum.variants {
+        let subtype = &variant.ident;
+        let subtype = quote!(#input_type::#subtype);
+
+        match variant.fields {
+            Fields::Unnamed(ref fields) => {
+                // The patern that is outputted should look like this:
+                // (Subtype(left_vars), TypePath(right_vars)) => Ok(TypePath(exprs))
+                let size = unnamed_to_vec(fields).len();
+                let l_vars = &numbered_vars(size, "l_");
+                let r_vars = &numbered_vars(size, "r_");
+                let method_iter = method_iter.by_ref();
+                let matcher = quote!{
+                    (#subtype(#(#l_vars),*),
+                     #subtype(#(#r_vars),*)) => {
+                        ::std::result::Result::Ok(#subtype(#(#l_vars.#method_iter(#r_vars)),*))
+                    }
+                };
+                matches.push(matcher);
+            }
+            Fields::Named(ref fields) => {
+                // The patern that is outputted should look like this:
+                // (Subtype{a: __l_a, ...}, Subtype{a: __r_a, ...} => {
+                //     Ok(Subtype{a: __l_a.add(__r_a), ...})
+                // }
+                let field_vec = named_to_vec(fields);
+                let size = field_vec.len();
+                let field_names = &field_idents(&field_vec);
+                let l_vars = &numbered_vars(size, "l_");
+                let r_vars = &numbered_vars(size, "r_");
+                let method_iter = method_iter.by_ref();
+                let matcher = quote!{
+                    (#subtype{#(#field_names: #l_vars),*},
+                     #subtype{#(#field_names: #r_vars),*}) => {
+                        ::std::result::Result::Ok(#subtype{#(#field_names: #l_vars.#method_iter(#r_vars)),*})
+                    }
+                };
+                matches.push(matcher);
+            }
+            Fields::Unit => {
+                let message = format!("Cannot {}() unit variants", method_ident.to_string());
+                matches.push(quote!((#subtype, #subtype) => ::std::result::Result::Err(#message)));
+            }
+        }
+    }
+
+    if data_enum.variants.len() > 1 {
+        // In the strange case where there's only one enum variant this is would be an unreachable
+        // match.
+        let message = format!(
+            "Trying to {} mismatched enum variants",
+            method_ident.to_string()
+        );
+        matches.push(quote!(_ => ::std::result::Result::Err(#message)));
+    }
+    quote!(
+        match (self, rhs) {
+            #(#matches),*
+        }
+    )
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/derive_more/src/constructor.rs
@@ -0,0 +1,45 @@
+use proc_macro2::TokenStream;
+use syn::{Data, DeriveInput, Field, Fields, Ident};
+use utils::{field_idents, get_field_types, named_to_vec, numbered_vars, unnamed_to_vec};
+
+/// Provides the hook to expand `#[derive(Constructor)]` into an implementation of `Constructor`
+pub fn expand(input: &DeriveInput, _: &str) -> TokenStream {
+    let input_type = &input.ident;
+    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
+    let ((body, vars), fields) = match input.data {
+        Data::Struct(ref data_struct) => match data_struct.fields {
+            Fields::Unnamed(ref fields) => {
+                let field_vec = unnamed_to_vec(fields);
+                (tuple_body(input_type, &field_vec), field_vec)
+            }
+            Fields::Named(ref fields) => {
+                let field_vec = named_to_vec(fields);
+                (struct_body(input_type, &field_vec), field_vec)
+            }
+            Fields::Unit => (struct_body(input_type, &[]), vec![]),
+        },
+        _ => panic!("Only structs can derive a constructor"),
+    };
+    let original_types = &get_field_types(&fields);
+    quote!{
+        #[allow(missing_docs)]
+        impl#impl_generics #input_type#ty_generics #where_clause {
+            #[inline]
+            pub fn new(#(#vars: #original_types),*) -> #input_type#ty_generics {
+                #body
+            }
+        }
+    }
+}
+
+fn tuple_body(return_type: &Ident, fields: &[&Field]) -> (TokenStream, Vec<Ident>) {
+    let vars = &numbered_vars(fields.len(), "");
+    (quote!(#return_type(#(#vars),*)), vars.clone())
+}
+
+fn struct_body(return_type: &Ident, fields: &[&Field]) -> (TokenStream, Vec<Ident>) {
+    let field_names: &Vec<Ident> = &field_idents(fields).iter().map(|f| (**f).clone()).collect();
+    let vars = field_names;
+    let ret_vars = field_names.clone();
+    (quote!(#return_type{#(#field_names: #vars),*}), ret_vars)
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/derive_more/src/deref.rs
@@ -0,0 +1,64 @@
+use proc_macro2::{Span, TokenStream};
+use syn::{Data, DeriveInput, Field, Fields, Ident};
+use utils::{add_extra_ty_param_bound, named_to_vec, unnamed_to_vec};
+
+/// Provides the hook to expand `#[derive(Index)]` into an implementation of `From`
+pub fn expand(input: &DeriveInput, trait_name: &str) -> TokenStream {
+    let trait_ident = Ident::new(trait_name, Span::call_site());
+    let trait_path = &quote!(::std::ops::#trait_ident);
+    let input_type = &input.ident;
+    let field_vec: Vec<&Field>;
+    let member = match input.data {
+        Data::Struct(ref data_struct) => match data_struct.fields {
+            Fields::Unnamed(ref fields) => {
+                field_vec = unnamed_to_vec(fields);
+                tuple_from_str(trait_name, &field_vec)
+            }
+            Fields::Named(ref fields) => {
+                field_vec = named_to_vec(fields);
+                struct_from_str(trait_name, &field_vec)
+            }
+            Fields::Unit => panic_one_field(trait_name),
+        },
+        _ => panic_one_field(trait_name),
+    };
+    let field_type = &field_vec[0].ty;
+
+    let generics = add_extra_ty_param_bound(&input.generics, trait_path);
+    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
+    // let generics = add_extra_ty_param_bound(&input.generics, trait_path);
+    let casted_trait = &quote!(<#field_type as #trait_path>);
+    quote!{
+        impl#impl_generics #trait_path for #input_type#ty_generics #where_clause
+        {
+            type Target = #casted_trait::Target;
+            #[inline]
+            fn deref(&self) -> &Self::Target {
+                #casted_trait::deref(&#member)
+            }
+        }
+    }
+}
+
+fn panic_one_field(trait_name: &str) -> ! {
+    panic!(format!(
+        "Only structs with one field can derive({})",
+        trait_name
+    ))
+}
+
+fn tuple_from_str<'a>(trait_name: &str, fields: &[&'a Field]) -> (TokenStream) {
+    if fields.len() != 1 {
+        panic_one_field(trait_name)
+    };
+    quote!(self.0)
+}
+
+fn struct_from_str<'a>(trait_name: &str, fields: &[&'a Field]) -> TokenStream {
+    if fields.len() != 1 {
+        panic_one_field(trait_name)
+    };
+    let field = &fields[0];
+    let field_ident = &field.ident;
+    quote!(self.#field_ident)
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/derive_more/src/deref_mut.rs
@@ -0,0 +1,63 @@
+use proc_macro2::{Span, TokenStream};
+use syn::{Data, DeriveInput, Field, Fields, Ident};
+use utils::{add_extra_ty_param_bound, named_to_vec, unnamed_to_vec};
+
+/// Provides the hook to expand `#[derive(Index)]` into an implementation of `From`
+pub fn expand(input: &DeriveInput, trait_name: &str) -> TokenStream {
+    let trait_ident = Ident::new(trait_name, Span::call_site());
+    let trait_path = &quote!(::std::ops::#trait_ident);
+    let input_type = &input.ident;
+    let field_vec: Vec<&Field>;
+    let member = match input.data {
+        Data::Struct(ref data_struct) => match data_struct.fields {
+            Fields::Unnamed(ref fields) => {
+                field_vec = unnamed_to_vec(fields);
+                tuple_from_str(trait_name, &field_vec)
+            }
+            Fields::Named(ref fields) => {
+                field_vec = named_to_vec(fields);
+                struct_from_str(trait_name, &field_vec)
+            }
+            Fields::Unit => panic_one_field(trait_name),
+        },
+        _ => panic_one_field(trait_name),
+    };
+    let field_type = &field_vec[0].ty;
+
+    let generics = add_extra_ty_param_bound(&input.generics, trait_path);
+    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
+    // let generics = add_extra_ty_param_bound(&input.generics, trait_path);
+    let casted_trait = &quote!(<#field_type as #trait_path>);
+    quote!{
+        impl#impl_generics #trait_path for #input_type#ty_generics #where_clause
+        {
+            #[inline]
+            fn deref_mut(&mut self) -> &mut Self::Target {
+                #casted_trait::deref_mut(&mut #member)
+            }
+        }
+    }
+}
+
+fn panic_one_field(trait_name: &str) -> ! {
+    panic!(format!(
+        "Only structs with one field can derive({})",
+        trait_name
+    ))
+}
+
+fn tuple_from_str<'a>(trait_name: &str, fields: &[&'a Field]) -> (TokenStream) {
+    if fields.len() != 1 {
+        panic_one_field(trait_name)
+    };
+    quote!(self.0)
+}
+
+fn struct_from_str<'a>(trait_name: &str, fields: &[&'a Field]) -> TokenStream {
+    if fields.len() != 1 {
+        panic_one_field(trait_name)
+    };
+    let field = &fields[0];
+    let field_ident = &field.ident;
+    quote!(self.#field_ident)
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/derive_more/src/display.rs
@@ -0,0 +1,220 @@
+use proc_macro2::{Ident, Span, TokenStream};
+use std::fmt::Display;
+use syn::{
+    parse::{Error, Result},
+    spanned::Spanned,
+    Attribute, Data, DeriveInput, Fields, Lit, Meta, MetaNameValue, NestedMeta,
+};
+
+/// Provides the hook to expand `#[derive(Display)]` into an implementation of `From`
+pub fn expand(input: &DeriveInput, trait_name: &str) -> Result<TokenStream> {
+    let trait_ident = Ident::new(trait_name, Span::call_site());
+    let trait_path = &quote!(::std::fmt::#trait_ident);
+    let trait_attr = match trait_name {
+        "Display" => "display",
+        "Binary" => "binary",
+        "Octal" => "octal",
+        "LowerHex" => "lower_hex",
+        "UpperHex" => "upper_hex",
+        "LowerExp" => "lower_exp",
+        "UpperExp" => "upper_exp",
+        "Pointer" => "pointer",
+        _ => unimplemented!(),
+    };
+
+    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
+    let name = &input.ident;
+
+    let arms = State {
+        trait_path,
+        trait_attr,
+        input,
+    }
+    .get_match_arms()?;
+
+    Ok(quote! {
+        impl #impl_generics #trait_path for #name #ty_generics #where_clause
+        {
+            #[inline]
+            fn fmt(&self, _derive_more_Display_formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+                match self {
+                    #arms
+                    _ => Ok(()) // This is needed for empty enums
+                }
+            }
+        }
+    })
+}
+
+struct State<'a, 'b> {
+    trait_path: &'b TokenStream,
+    trait_attr: &'static str,
+    input: &'a DeriveInput,
+}
+
+impl<'a, 'b> State<'a, 'b> {
+    fn get_proper_syntax(&self) -> impl Display {
+        format!(
+            r#"Proper syntax: #[{}(fmt = "My format", "arg1", "arg2")]"#,
+            self.trait_attr
+        )
+    }
+    fn get_matcher(&self, fields: &Fields) -> TokenStream {
+        match fields {
+            Fields::Unit => TokenStream::new(),
+            Fields::Unnamed(fields) => {
+                let fields: TokenStream = (0..fields.unnamed.len())
+                    .map(|n| {
+                        let i = Ident::new(&format!("_{}", n), Span::call_site());
+                        quote!(#i,)
+                    })
+                    .collect();
+                quote!((#fields))
+            }
+            Fields::Named(fields) => {
+                let fields: TokenStream = fields
+                    .named
+                    .iter()
+                    .map(|f| {
+                        let i = f.ident.as_ref().unwrap();
+                        quote!(#i,)
+                    })
+                    .collect();
+                quote!({#fields})
+            }
+        }
+    }
+    fn find_meta(&self, attrs: &[Attribute]) -> Result<Option<Meta>> {
+        let mut it = attrs
+            .iter()
+            .filter_map(|a| a.interpret_meta())
+            .filter(|m| m.name() == self.trait_attr);
+
+        let meta = it.next();
+        if it.next().is_some() {
+            Err(Error::new(meta.span(), "Too many formats given"))
+        } else {
+            Ok(meta)
+        }
+    }
+    fn get_meta_fmt(&self, meta: Meta) -> Result<TokenStream> {
+        let list = match &meta {
+            Meta::List(list) => list,
+            _ => return Err(Error::new(meta.span(), self.get_proper_syntax())),
+        };
+
+        let fmt = match &list.nested[0] {
+            NestedMeta::Meta(Meta::NameValue(MetaNameValue {
+                ident,
+                lit: Lit::Str(s),
+                ..
+            }))
+                if ident == "fmt" =>
+            {
+                s
+            }
+            _ => return Err(Error::new(list.nested[0].span(), self.get_proper_syntax())),
+        };
+
+        let args = list
+            .nested
+            .iter()
+            .skip(1) // skip fmt = "..."
+            .try_fold(TokenStream::new(), |args, arg| {
+                let arg = match arg {
+                    NestedMeta::Literal(Lit::Str(s)) => s,
+                    NestedMeta::Meta(Meta::Word(i)) => {
+                        return Ok(quote_spanned!(list.span()=> #args #i,))
+                    }
+                    _ => return Err(Error::new(arg.span(), self.get_proper_syntax())),
+                };
+                let arg: TokenStream = match arg.parse() {
+                    Ok(arg) => arg,
+                    Err(e) => return Err(Error::new(arg.span(), e)),
+                };
+                Ok(quote_spanned!(list.span()=> #args #arg,))
+            })?;
+
+        Ok(quote_spanned!(meta.span()=> write!(_derive_more_Display_formatter, #fmt, #args)))
+    }
+    fn infer_fmt(&self, fields: &Fields, name: &Ident) -> Result<TokenStream> {
+        let fields = match fields {
+            Fields::Unit => {
+                return Ok(quote!(write!(
+                    _derive_more_Display_formatter,
+                    stringify!(#name)
+                )));
+            }
+            Fields::Named(fields) => &fields.named,
+            Fields::Unnamed(fields) => &fields.unnamed,
+        };
+        if fields.len() == 0 {
+            return Ok(quote!(write!(
+                _derive_more_Display_formatter,
+                stringify!(#name)
+            )));
+        } else if fields.len() > 1 {
+            return Err(Error::new(
+                fields.span(),
+                "Can not automatically infer format for types with more than 1 field",
+            ));
+        }
+
+        let trait_path = self.trait_path;
+        if let Some(ident) = &fields.iter().next().as_ref().unwrap().ident {
+            Ok(quote!(#trait_path::fmt(#ident, _derive_more_Display_formatter)))
+        } else {
+            Ok(quote!(#trait_path::fmt(_0, _derive_more_Display_formatter)))
+        }
+    }
+    fn get_match_arms(&self) -> Result<TokenStream> {
+        match &self.input.data {
+            Data::Enum(e) => {
+                if let Some(meta) = self.find_meta(&self.input.attrs)? {
+                    let fmt = self.get_meta_fmt(meta)?;
+                    e.variants.iter().try_for_each(|v| {
+                        if let Some(meta) = self.find_meta(&v.attrs)? {
+                            Err(Error::new(
+                                meta.span(),
+                                "Can not have a format on the variant when the whole enum has one",
+                            ))
+                        } else {
+                            Ok(())
+                        }
+                    })?;
+                    Ok(quote_spanned!(self.input.span()=> _ => #fmt,))
+                } else {
+                    e.variants.iter().try_fold(TokenStream::new(), |arms, v| {
+                        let matcher = self.get_matcher(&v.fields);
+                        let fmt = if let Some(meta) = self.find_meta(&v.attrs)? {
+                            self.get_meta_fmt(meta)?
+                        } else {
+                            self.infer_fmt(&v.fields, &v.ident)?
+                        };
+                        let name = &self.input.ident;
+                        let v_name = &v.ident;
+                        Ok(quote_spanned!(self.input.span()=> #arms #name::#v_name #matcher => #fmt,))
+                    })
+                }
+            }
+            Data::Struct(s) => {
+                let matcher = self.get_matcher(&s.fields);
+                let fmt = if let Some(meta) = self.find_meta(&self.input.attrs)? {
+                    self.get_meta_fmt(meta)?
+                } else {
+                    self.infer_fmt(&s.fields, &self.input.ident)?
+                };
+                let name = &self.input.ident;
+                Ok(quote_spanned!(self.input.span()=> #name #matcher => #fmt,))
+            }
+            Data::Union(_) => {
+                let meta = self.find_meta(&self.input.attrs)?.ok_or(Error::new(
+                    self.input.span(),
+                    "Can not automatically infer format for unions",
+                ))?;
+                let fmt = self.get_meta_fmt(meta)?;
+                Ok(quote_spanned!(self.input.span()=> _ => #fmt,))
+            }
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/derive_more/src/from.rs
@@ -0,0 +1,132 @@
+use std::collections::HashMap;
+use std::ops::Index;
+
+use proc_macro2::TokenStream;
+use quote::ToTokens;
+use syn::{Data, DataEnum, DeriveInput, Field, Fields};
+use utils::{field_idents, get_field_types, named_to_vec, number_idents, unnamed_to_vec};
+
+/// Provides the hook to expand `#[derive(From)]` into an implementation of `From`
+pub fn expand(input: &DeriveInput, trait_name: &str) -> TokenStream {
+    match input.data {
+        Data::Struct(ref data_struct) => match data_struct.fields {
+            Fields::Unnamed(ref fields) => tuple_from(input, &unnamed_to_vec(fields)),
+            Fields::Named(ref fields) => struct_from(input, &named_to_vec(fields)),
+            Fields::Unit => struct_from(input, &[]),
+        },
+        Data::Enum(ref data_enum) => enum_from(input, data_enum),
+        _ => panic!(format!(
+            "Only structs and enums can use derive({})",
+            trait_name
+        )),
+    }
+}
+
+pub fn from_impl<T: ToTokens>(input: &DeriveInput, fields: &[&Field], body: T) -> TokenStream {
+    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
+    let input_type = &input.ident;
+    let original_types = &get_field_types(fields);
+    quote!{
+        impl#impl_generics ::std::convert::From<(#(#original_types),*)> for
+            #input_type#ty_generics #where_clause {
+
+            #[allow(unused_variables)]
+            #[inline]
+            fn from(original: (#(#original_types),*)) -> #input_type#ty_generics {
+                #body
+            }
+        }
+    }
+}
+
+fn tuple_from(input: &DeriveInput, fields: &[&Field]) -> TokenStream {
+    let input_type = &input.ident;
+    let body = tuple_body(input_type, fields);
+    from_impl(input, fields, body)
+}
+
+fn tuple_body<T: ToTokens>(return_type: T, fields: &[&Field]) -> TokenStream {
+    if fields.len() == 1 {
+        quote!(#return_type(original))
+    } else {
+        let field_names = &number_idents(fields.len());
+        quote!(#return_type(#(original.#field_names),*))
+    }
+}
+
+fn struct_from(input: &DeriveInput, fields: &[&Field]) -> TokenStream {
+    let input_type = &input.ident;
+    let body = struct_body(input_type, fields);
+    from_impl(input, fields, body)
+}
+
+fn struct_body<T: ToTokens>(return_type: T, fields: &[&Field]) -> TokenStream {
+    if fields.len() == 1 {
+        let field_name = &fields[0].ident;
+        quote!(#return_type{#field_name: original})
+    } else {
+        let argument_field_names = &number_idents(fields.len());
+        let field_names = &field_idents(fields);
+        quote!(#return_type{#(#field_names: original.#argument_field_names),*})
+    }
+}
+
+fn enum_from(input: &DeriveInput, data_enum: &DataEnum) -> TokenStream {
+    let mut type_signature_counts = HashMap::new();
+    let input_type = &input.ident;
+
+    for variant in &data_enum.variants {
+        match variant.fields {
+            Fields::Unnamed(ref fields) => {
+                let original_types = unnamed_to_vec(fields).iter().map(|f| &f.ty).collect();
+                let counter = type_signature_counts.entry(original_types).or_insert(0);
+                *counter += 1;
+            }
+            Fields::Named(ref fields) => {
+                let original_types = named_to_vec(fields).iter().map(|f| &f.ty).collect();
+                let counter = type_signature_counts.entry(original_types).or_insert(0);
+                *counter += 1;
+            }
+            Fields::Unit => {
+                let counter = type_signature_counts.entry(vec![]).or_insert(0);
+                *counter += 1;
+            }
+        }
+    }
+
+    let mut tokens = TokenStream::new();
+
+    for variant in &data_enum.variants {
+        match variant.fields {
+            Fields::Unnamed(ref fields) => {
+                let field_vec = &unnamed_to_vec(fields);
+                let original_types = get_field_types(field_vec);
+
+                if *type_signature_counts.index(&original_types) == 1 {
+                    let variant_ident = &variant.ident;
+                    let body = tuple_body(quote!(#input_type::#variant_ident), field_vec);
+                    from_impl(input, field_vec, body).to_tokens(&mut tokens)
+                }
+            }
+
+            Fields::Named(ref fields) => {
+                let field_vec = &named_to_vec(fields);
+                let original_types = get_field_types(field_vec);
+
+                if *type_signature_counts.index(&original_types) == 1 {
+                    let variant_ident = &variant.ident;
+                    let body = struct_body(quote!(#input_type::#variant_ident), field_vec);
+                    from_impl(input, field_vec, body).to_tokens(&mut tokens)
+                }
+            }
+            Fields::Unit => {
+                if *type_signature_counts.index(&vec![]) == 1 {
+                    let variant_ident = &variant.ident;
+                    let body = struct_body(quote!(#input_type::#variant_ident), &[]);
+                    from_impl(input, &[], body).to_tokens(&mut tokens)
+                }
+            }
+        }
+    }
+    tokens
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/derive_more/src/from_str.rs
@@ -0,0 +1,70 @@
+use proc_macro2::TokenStream;
+use syn::{Data, DeriveInput, Field, Fields, Ident, Type};
+use utils::{add_extra_ty_param_bound, named_to_vec, unnamed_to_vec};
+
+/// Provides the hook to expand `#[derive(FromStr)]` into an implementation of `From`
+pub fn expand(input: &DeriveInput, trait_name: &str) -> TokenStream {
+    let trait_path = &quote!(::std::str::FromStr);
+    let generics = add_extra_ty_param_bound(&input.generics, trait_path);
+    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
+    let input_type = &input.ident;
+    let (result, field_type) = match input.data {
+        Data::Struct(ref data_struct) => match data_struct.fields {
+            Fields::Unnamed(ref fields) => {
+                tuple_from_str(input_type, trait_name, &unnamed_to_vec(fields))
+            }
+            Fields::Named(ref fields) => {
+                struct_from_str(input_type, trait_name, &named_to_vec(fields))
+            }
+            Fields::Unit => panic_one_field(trait_name),
+        },
+        _ => panic_one_field(trait_name),
+    };
+    quote!{
+        impl#impl_generics #trait_path for #input_type#ty_generics #where_clause
+        {
+            type Err = <#field_type as #trait_path>::Err;
+            #[inline]
+            fn from_str(src: &str) -> ::std::result::Result<Self, Self::Err> {
+                return ::std::result::Result::Ok(#result)
+            }
+        }
+    }
+}
+
+fn panic_one_field(trait_name: &str) -> ! {
+    panic!(format!(
+        "Only structs with one field can derive({})",
+        trait_name
+    ))
+}
+
+fn tuple_from_str<'a>(
+    input_type: &Ident,
+    trait_name: &str,
+    fields: &[&'a Field],
+) -> (TokenStream, &'a Type) {
+    if fields.len() != 1 {
+        panic_one_field(trait_name)
+    };
+    let field = &fields[0];
+    let field_type = &field.ty;
+    (quote!(#input_type(#field_type::from_str(src)?)), field_type)
+}
+
+fn struct_from_str<'a>(
+    input_type: &Ident,
+    trait_name: &str,
+    fields: &[&'a Field],
+) -> (TokenStream, &'a Type) {
+    if fields.len() != 1 {
+        panic_one_field(trait_name)
+    };
+    let field = &fields[0];
+    let field_type = &field.ty;
+    let field_ident = &field.ident;
+    (
+        quote!(#input_type{#field_ident: #field_type::from_str(src)?}),
+        field_type,
+    )
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/derive_more/src/index.rs
@@ -0,0 +1,75 @@
+use proc_macro2::{Span, TokenStream};
+use syn::{Data, DeriveInput, Field, Fields, Ident};
+use utils::{add_where_clauses_for_new_ident, named_to_vec, unnamed_to_vec};
+
+/// Provides the hook to expand `#[derive(Index)]` into an implementation of `From`
+pub fn expand(input: &DeriveInput, trait_name: &str) -> TokenStream {
+    let trait_ident = Ident::new(trait_name, Span::call_site());
+    let index_type = &Ident::new("__IdxT", Span::call_site());
+    let trait_path = &quote!(::std::ops::#trait_ident<#index_type>);
+    let input_type = &input.ident;
+    let field_vec: Vec<&Field>;
+    let member = match input.data {
+        Data::Struct(ref data_struct) => match data_struct.fields {
+            Fields::Unnamed(ref fields) => {
+                field_vec = unnamed_to_vec(fields);
+                tuple_from_str(trait_name, &field_vec)
+            }
+            Fields::Named(ref fields) => {
+                field_vec = named_to_vec(fields);
+                struct_from_str(trait_name, &field_vec)
+            }
+            Fields::Unit => panic_one_field(trait_name),
+        },
+        _ => panic_one_field(trait_name),
+    };
+    let field_type = &field_vec[0].ty;
+    let type_where_clauses = quote!{
+        where #field_type: #trait_path
+    };
+
+    let new_generics = add_where_clauses_for_new_ident(
+        &input.generics,
+        &field_vec,
+        index_type,
+        type_where_clauses,
+    );
+
+    let (impl_generics, _, where_clause) = new_generics.split_for_impl();
+    let (_, ty_generics, _) = input.generics.split_for_impl();
+    // let generics = add_extra_ty_param_bound(&input.generics, trait_path);
+    let casted_trait = &quote!(<#field_type as #trait_path>);
+    quote!{
+        impl#impl_generics #trait_path for #input_type#ty_generics #where_clause
+        {
+            type Output = #casted_trait::Output;
+            #[inline]
+            fn index(&self, idx: #index_type) -> &Self::Output {
+                #casted_trait::index(&#member, idx)
+            }
+        }
+    }
+}
+
+fn panic_one_field(trait_name: &str) -> ! {
+    panic!(format!(
+        "Only structs with one field can derive({})",
+        trait_name
+    ))
+}
+
+fn tuple_from_str<'a>(trait_name: &str, fields: &[&'a Field]) -> (TokenStream) {
+    if fields.len() != 1 {
+        panic_one_field(trait_name)
+    };
+    quote!(self.0)
+}
+
+fn struct_from_str<'a>(trait_name: &str, fields: &[&'a Field]) -> TokenStream {
+    if fields.len() != 1 {
+        panic_one_field(trait_name)
+    };
+    let field = &fields[0];
+    let field_ident = &field.ident;
+    quote!(self.#field_ident)
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/derive_more/src/index_mut.rs
@@ -0,0 +1,74 @@
+use proc_macro2::{Span, TokenStream};
+use syn::{Data, DeriveInput, Field, Fields, Ident};
+use utils::{add_where_clauses_for_new_ident, named_to_vec, unnamed_to_vec};
+
+/// Provides the hook to expand `#[derive(IndexMut)]` into an implementation of `From`
+pub fn expand(input: &DeriveInput, trait_name: &str) -> TokenStream {
+    let trait_ident = Ident::new(trait_name, Span::call_site());
+    let index_type = &Ident::new("__IdxT", Span::call_site());
+    let trait_path = &quote!(::std::ops::#trait_ident<#index_type>);
+    let input_type = &input.ident;
+    let field_vec: Vec<&Field>;
+    let member = match input.data {
+        Data::Struct(ref data_struct) => match data_struct.fields {
+            Fields::Unnamed(ref fields) => {
+                field_vec = unnamed_to_vec(fields);
+                tuple_from_str(trait_name, &field_vec)
+            }
+            Fields::Named(ref fields) => {
+                field_vec = named_to_vec(fields);
+                struct_from_str(trait_name, &field_vec)
+            }
+            Fields::Unit => panic_one_field(trait_name),
+        },
+        _ => panic_one_field(trait_name),
+    };
+    let field_type = &field_vec[0].ty;
+    let type_where_clauses = quote!{
+        where #field_type: #trait_path
+    };
+
+    let new_generics = add_where_clauses_for_new_ident(
+        &input.generics,
+        &field_vec,
+        index_type,
+        type_where_clauses,
+    );
+
+    let (impl_generics, _, where_clause) = new_generics.split_for_impl();
+    let (_, ty_generics, _) = input.generics.split_for_impl();
+    // let generics = add_extra_ty_param_bound(&input.generics, trait_path);
+    let casted_trait = &quote!(<#field_type as #trait_path>);
+    quote!{
+        impl#impl_generics #trait_path for #input_type#ty_generics #where_clause
+        {
+            #[inline]
+            fn index_mut(&mut self, idx: #index_type) -> &mut Self::Output {
+                #casted_trait::index_mut(&mut #member, idx)
+            }
+        }
+    }
+}
+
+fn panic_one_field(trait_name: &str) -> ! {
+    panic!(format!(
+        "Only structs with one field can derive({})",
+        trait_name
+    ))
+}
+
+fn tuple_from_str<'a>(trait_name: &str, fields: &[&'a Field]) -> (TokenStream) {
+    if fields.len() != 1 {
+        panic_one_field(trait_name)
+    };
+    quote!(self.0)
+}
+
+fn struct_from_str<'a>(trait_name: &str, fields: &[&'a Field]) -> TokenStream {
+    if fields.len() != 1 {
+        panic_one_field(trait_name)
+    };
+    let field = &fields[0];
+    let field_ident = &field.ident;
+    quote!(self.#field_ident)
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/derive_more/src/into.rs
@@ -0,0 +1,53 @@
+use proc_macro2::TokenStream;
+use quote::ToTokens;
+use syn::{Data, DeriveInput, Field, Fields};
+use utils::{field_idents, get_field_types, named_to_vec, number_idents, unnamed_to_vec};
+
+/// Provides the hook to expand `#[derive(Into)]` into an implementation of `Into`
+pub fn expand(input: &DeriveInput, _: &str) -> TokenStream {
+    let input_type = &input.ident;
+    let field_vec: Vec<_>;
+    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
+    let (field_names, fields) = match input.data {
+        Data::Struct(ref data_struct) => match data_struct.fields {
+            Fields::Unnamed(ref fields) => {
+                field_vec = unnamed_to_vec(fields);
+                (tuple_field_names(&field_vec), field_vec)
+            }
+            Fields::Named(ref fields) => {
+                field_vec = named_to_vec(fields);
+                (struct_field_names(&field_vec), field_vec)
+            }
+            Fields::Unit => (vec![], vec![]),
+        },
+        _ => panic!("Only structs can derive Into"),
+    };
+
+    let original_types = &get_field_types(&fields);
+
+    quote!{
+        impl#impl_generics ::std::convert::From<#input_type#ty_generics> for
+            (#(#original_types),*) #where_clause {
+
+            #[allow(unused_variables)]
+            #[inline]
+            fn from(original: #input_type#ty_generics) -> (#(#original_types),*) {
+                (#(original.#field_names),*)
+            }
+        }
+    }
+}
+
+fn tuple_field_names(fields: &[&Field]) -> Vec<TokenStream> {
+    number_idents(fields.len())
+        .iter()
+        .map(|f| f.into_token_stream())
+        .collect()
+}
+
+fn struct_field_names(fields: &[&Field]) -> Vec<TokenStream> {
+    field_idents(fields)
+        .iter()
+        .map(|f| (*f).into_token_stream())
+        .collect()
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/derive_more/src/lib.rs
@@ -0,0 +1,293 @@
+//! # `derive_more`
+//! Rust has lots of builtin traits that are implemented for its basic types, such as [`Add`],
+//! [`Not`] or [`From`].
+//! However, when wrapping these types inside your own structs or enums you lose the
+//! implementations of these traits and are required to recreate them.
+//! This is especially annoying when your own structures are very simple, such as when using the
+//! commonly advised newtype pattern (e.g. `MyInt(i32)`).
+//!
+//! This library tries to remove these annoyances and the corresponding boilerplate code.
+//! It does this by allowing you to derive lots of commonly used traits for both structs and enums.
+//!
+//! ## Example code
+//!
+//! By using this library the following code just works:
+//!
+//!
+//! ```rust
+//! #[macro_use]
+//! extern crate derive_more;
+//!
+//! #[derive(Debug, Eq, PartialEq, From, Add)]
+//! struct MyInt(i32);
+//!
+//! #[derive(Debug, Eq, PartialEq, From, Into, Constructor, Mul)]
+//! struct Point2D {
+//!     x: i32,
+//!     y: i32,
+//! }
+//!
+//! #[derive(Debug, Eq, PartialEq, From, Add)]
+//! enum MyEnum {
+//!     Int(i32),
+//!     UnsignedInt(u32),
+//!     Nothing,
+//! }
+//!
+//! fn main() {
+//!     let my_11 = MyInt(5) + 6.into();
+//!     assert_eq!(MyInt(11), MyInt(5) + 6.into());
+//!     assert_eq!(Point2D { x: 5, y: 6 } * 10, (50, 60).into());
+//!     assert_eq!((5, 6), Point2D { x: 5, y: 6 }.into());
+//!     assert_eq!(Point2D { x: 5, y: 6 }, Point2D::new(5, 6));
+//!     assert_eq!(MyEnum::Int(15), (MyEnum::Int(8) + 7.into()).unwrap())
+//! }
+//! ```
+//!
+//! ## The derivable traits
+//!
+//! Below are all the traits that you can derive using this library.
+//! Some trait derivations are so similar that the further documentation will only show a single one
+//! of them.
+//! You can recognize these by the "-like" suffix in their name.
+//! The trait name before that will be the only one that is used throughout the further
+//! documentation.
+//!
+//! **NOTE**: You still have to derive each trait separately. So `#[derive(Mul)]` doesn't
+//! automatically derive `Div` as well. To derive both you should do `#[derive(Mul, Div)]`
+//!
+//! ### Conversion traits
+//! These are traits that are used to convert automatically between types.
+//!
+//! 1. [`From`]
+//! 2. [`Into`]
+//! 3. [`FromStr`]
+//! 4. [`TryInto`] (nightly-only as of writing)
+//!
+//! ### Formatting traits
+//! These traits are used for converting a struct to a string in different ways.
+//!
+//! 1. `Display`-like, contains [`Display`], [`Binary`], [`Octal`], [`LowerHex`], [`UpperHex`],
+//!    [`LowerExp`], [`UpperExp`], [`Pointer`]
+//!
+//! ### Operators
+//! These are traits that can be used for operator overloading.
+//!
+//! 1. [`Index`]
+//! 2. [`Deref`]
+//! 3. `Not`-like, contains [`Not`] and [`Neg`]
+//! 4. `Add`-like, contains [`Add`], [`Sub`], [`BitAnd`], [`BitOr`] and [`BitXor`]
+//! 5. `Mul`-like, contains [`Mul`], [`Div`], [`Rem`], [`Shr`] and [`Shl`]
+//! 6. [`IndexMut`]
+//! 7. [`DerefMut`]
+//! 8. `AddAssign`-like, contains [`AddAssign`], [`SubAssign`], [`BitAndAssign`], [`BitOrAssign`]
+//!    and [`BitXorAssign`]
+//! 9. `MulAssign`-like, contains [`MulAssign`], [`DivAssign`], [`RemAssign`], [`ShrAssign`] and
+//!    [`ShlAssign`]
+//!
+//! ### Static methods
+//! These don't derive traits, but derive static methods instead.
+//!
+//! 1. `Constructor`, this derives a `new` method that can be used as a constructor. This is very
+//!    basic if you need more customization for your constructor, check out the [`derive-new`] crate.
+//!
+//!
+//! ## Generated code
+//!
+//! It is important to understand what code gets generated when using one of the derives from this
+//! crate.
+//! That is why the links below explain what code gets generated for a trait for each group from
+//! before.
+//!
+//! 1. [`#[derive(From)]`](https://jeltef.github.io/derive_more/derive_more/from.html)
+//! 2. [`#[derive(Into)]`](https://jeltef.github.io/derive_more/derive_more/into.html)
+//! 3. [`#[derive(FromStr)]`](https://jeltef.github.io/derive_more/derive_more/from_str.html)
+//! 4. [`#[derive(TryInto)]`](https://jeltef.github.io/derive_more/derive_more/try_into.html)
+//! 5. [`#[derive(Display)]`](https://jeltef.github.io/derive_more/derive_more/display.html)
+//! 6. [`#[derive(Index)]`](https://jeltef.github.io/derive_more/derive_more/index_op.html)
+//! 7. [`#[derive(Deref)]`](https://jeltef.github.io/derive_more/derive_more/deref.html)
+//! 8. [`#[derive(Not)]`](https://jeltef.github.io/derive_more/derive_more/not.html)
+//! 9. [`#[derive(Add)]`](https://jeltef.github.io/derive_more/derive_more/add.html)
+//! 10. [`#[derive(Mul)]`](https://jeltef.github.io/derive_more/derive_more/mul.html)
+//! 11. [`#[derive(IndexMut)]`](https://jeltef.github.io/derive_more/derive_more/index_mut.html)
+//! 12. [`#[derive(DerefMut)]`](https://jeltef.github.io/derive_more/derive_more/deref_mut.html)
+//! 13. [`#[derive(AddAssign)]`](https://jeltef.github.io/derive_more/derive_more/add_assign.html)
+//! 14. [`#[derive(MulAssign)]`](https://jeltef.github.io/derive_more/derive_more/mul_assign.html)
+//! 15. [`#[derive(Constructor)]`](https://jeltef.github.io/derive_more/derive_more/constructor.html)
+//!
+//! If you want to be sure what code is generated for your specific type I recommend using the
+//! [`cargo-expand`] utility.
+//! This will show you your code with all macros and derives expanded.
+//!
+//! ## Installation
+//!
+//! This library requires Rust 1.15 or higher, so this needs to be installed.
+//! Then add the following to `Cargo.toml`:
+//!
+//! ```toml
+//! [dependencies]
+//! derive_more = "0.13.0"
+//! ```
+//!
+//! And this to the top of your Rust file:
+//!
+//! ```rust
+//! #[macro_use]
+//! extern crate derive_more;
+//! # fn main () {}
+//! ```
+//!
+//! [`cargo-expand`]: https://github.com/dtolnay/cargo-expand
+//! [`derive-new`]: https://github.com/nrc/derive-new
+//! [`From`]: https://doc.rust-lang.org/core/convert/trait.From.html
+//! [`Into`]: https://doc.rust-lang.org/core/convert/trait.Into.html
+//! [`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html
+//! [`TryInto`]: https://doc.rust-lang.org/core/convert/trait.TryInto.html
+//! [`Display`]: https://doc.rust-lang.org/std/fmt/trait.Display.html
+//! [`Binary`]: https://doc.rust-lang.org/std/fmt/trait.Binary.html
+//! [`Octal`]: https://doc.rust-lang.org/std/fmt/trait.Octal.html
+//! [`LowerHex`]: https://doc.rust-lang.org/std/fmt/trait.LowerHex.html
+//! [`UpperHex`]: https://doc.rust-lang.org/std/fmt/trait.UpperHex.html
+//! [`LowerExp`]: https://doc.rust-lang.org/std/fmt/trait.LowerExp.html
+//! [`UpperExp`]: https://doc.rust-lang.org/std/fmt/trait.UpperExp.html
+//! [`Pointer`]: https://doc.rust-lang.org/std/fmt/trait.Pointer.html
+//! [`Index`]: https://doc.rust-lang.org/std/ops/trait.Index.html
+//! [`Deref`]: https://doc.rust-lang.org/std/ops/trait.Deref.html
+//! [`Not`]: https://doc.rust-lang.org/std/ops/trait.Not.html
+//! [`Neg`]: https://doc.rust-lang.org/std/ops/trait.Neg.html
+//! [`Add`]: https://doc.rust-lang.org/std/ops/trait.Add.html
+//! [`Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html
+//! [`BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html
+//! [`BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html
+//! [`BitXor`]: https://doc.rust-lang.org/std/ops/trait.BitXor.html
+//! [`Mul`]: https://doc.rust-lang.org/std/ops/trait.Mul.html
+//! [`Div`]: https://doc.rust-lang.org/std/ops/trait.Div.html
+//! [`Rem`]: https://doc.rust-lang.org/std/ops/trait.Rem.html
+//! [`Shr`]: https://doc.rust-lang.org/std/ops/trait.Shr.html
+//! [`Shl`]: https://doc.rust-lang.org/std/ops/trait.Shl.html
+//! [`IndexMut`]: https://doc.rust-lang.org/std/ops/trait.IndexMut.html
+//! [`DerefMut`]: https://doc.rust-lang.org/std/ops/trait.DerefMut.html
+//! [`AddAssign`]: https://doc.rust-lang.org/std/ops/trait.AddAssign.html
+//! [`SubAssign`]: https://doc.rust-lang.org/std/ops/trait.SubAssign.html
+//! [`BitAndAssign`]: https://doc.rust-lang.org/std/ops/trait.BitAndAssign.html
+//! [`BitOrAssign`]: https://doc.rust-lang.org/std/ops/trait.BitOrAssign.html
+//! [`BitXorAssign`]: https://doc.rust-lang.org/std/ops/trait.BitXorAssign.html
+//! [`MulAssign`]: https://doc.rust-lang.org/std/ops/trait.MulAssign.html
+//! [`DivAssign`]: https://doc.rust-lang.org/std/ops/trait.DivAssign.html
+//! [`RemAssign`]: https://doc.rust-lang.org/std/ops/trait.RemAssign.html
+//! [`ShrAssign`]: https://doc.rust-lang.org/std/ops/trait.ShrAssign.html
+//! [`ShlAssign`]: https://doc.rust-lang.org/std/ops/trait.ShlAssign.html
+
+#![recursion_limit = "128"]
+extern crate proc_macro;
+extern crate proc_macro2;
+#[macro_use]
+extern crate quote;
+extern crate syn;
+
+use proc_macro::TokenStream;
+use syn::parse::Error as ParseError;
+
+mod utils;
+
+mod add_assign_like;
+mod add_like;
+mod constructor;
+mod deref;
+mod deref_mut;
+mod display;
+mod from;
+mod from_str;
+mod index;
+mod index_mut;
+mod into;
+mod mul_assign_like;
+mod mul_like;
+mod not_like;
+mod try_into;
+
+// This trait describes the possible return types of
+// the derives. A derive can generally be infallible and
+// return a TokenStream, or it can be fallible and return
+// a Result<TokenStream, syn::parse::Error>.
+trait Output {
+    fn process(self) -> TokenStream;
+}
+
+impl Output for proc_macro2::TokenStream {
+    fn process(self) -> TokenStream {
+        self.into()
+    }
+}
+
+impl Output for Result<proc_macro2::TokenStream, ParseError> {
+    fn process(self) -> TokenStream {
+        match self {
+            Ok(ts) => ts.into(),
+            Err(e) => e.to_compile_error().into(),
+        }
+    }
+}
+
+macro_rules! create_derive(
+    ($mod_:ident, $trait_:ident, $fn_name: ident $(,$attribute:ident)*) => {
+        #[proc_macro_derive($trait_, attributes($($attribute),*))]
+        #[doc(hidden)]
+        pub fn $fn_name(input: TokenStream) -> TokenStream {
+            let ast = syn::parse(input).unwrap();
+            Output::process($mod_::expand(&ast, stringify!($trait_)))
+        }
+    }
+);
+
+create_derive!(from, From, from_derive);
+
+create_derive!(into, Into, into_derive);
+
+create_derive!(constructor, Constructor, constructor_derive);
+
+create_derive!(not_like, Not, not_derive);
+create_derive!(not_like, Neg, neg_derive);
+
+create_derive!(add_like, Add, add_derive);
+create_derive!(add_like, Sub, sub_derive);
+create_derive!(add_like, BitAnd, bit_and_derive);
+create_derive!(add_like, BitOr, bit_or_derive);
+create_derive!(add_like, BitXor, bit_xor_derive);
+
+create_derive!(mul_like, Mul, mul_derive);
+create_derive!(mul_like, Div, div_derive);
+create_derive!(mul_like, Rem, rem_derive);
+create_derive!(mul_like, Shr, shr_derive);
+create_derive!(mul_like, Shl, shl_derive);
+
+create_derive!(add_assign_like, AddAssign, add_assign_derive);
+create_derive!(add_assign_like, SubAssign, sub_assign_derive);
+create_derive!(add_assign_like, BitAndAssign, bit_and_assign_derive);
+create_derive!(add_assign_like, BitOrAssign, bit_or_assign_derive);
+create_derive!(add_assign_like, BitXorAssign, bit_xor_assign_derive);
+
+create_derive!(mul_assign_like, MulAssign, mul_assign_derive);
+create_derive!(mul_assign_like, DivAssign, div_assign_derive);
+create_derive!(mul_assign_like, RemAssign, rem_assign_derive);
+create_derive!(mul_assign_like, ShrAssign, shr_assign_derive);
+create_derive!(mul_assign_like, ShlAssign, shl_assign_derive);
+
+create_derive!(from_str, FromStr, from_str_derive);
+
+create_derive!(display, Display, display_derive, display);
+create_derive!(display, Binary, binary_derive, binary);
+create_derive!(display, Octal, octal_derive, octal);
+create_derive!(display, LowerHex, lower_hex_derive, lower_hex);
+create_derive!(display, UpperHex, upper_hex_derive, upper_hex);
+create_derive!(display, LowerExp, lower_exp_derive, lower_exp);
+create_derive!(display, UpperExp, upper_exp_derive, upper_exp);
+create_derive!(display, Pointer, pointer_derive, pointer);
+
+create_derive!(index, Index, index_derive);
+create_derive!(index_mut, IndexMut, index_mut_derive);
+
+create_derive!(try_into, TryInto, try_into_derive);
+
+create_derive!(deref, Deref, deref_derive);
+create_derive!(deref_mut, DerefMut, deref_mut_derive);
new file mode 100644
--- /dev/null
+++ b/third_party/rust/derive_more/src/mul_assign_like.rs
@@ -0,0 +1,56 @@
+use mul_like::{struct_exprs, tuple_exprs};
+use proc_macro2::{Span, TokenStream};
+use std::collections::HashSet;
+use std::iter;
+use syn::{Data, DeriveInput, Fields, Ident};
+use utils::{add_where_clauses_for_new_ident, get_field_types_iter, named_to_vec, unnamed_to_vec};
+
+pub fn expand(input: &DeriveInput, trait_name: &str) -> TokenStream {
+    let trait_ident = Ident::new(trait_name, Span::call_site());
+    let trait_path = &quote!(::std::ops::#trait_ident);
+    let method_name = trait_name.to_string();
+    let method_name = method_name.trim_right_matches("Assign");
+    let method_name = method_name.to_lowercase();
+    let method_ident = Ident::new(&(method_name.to_string() + "_assign"), Span::call_site());
+    let input_type = &input.ident;
+
+    let (exprs, fields) = match input.data {
+        Data::Struct(ref data_struct) => match data_struct.fields {
+            Fields::Unnamed(ref fields) => {
+                let field_vec = unnamed_to_vec(fields);
+                (tuple_exprs(&field_vec, &method_ident), field_vec)
+            }
+            Fields::Named(ref fields) => {
+                let field_vec = named_to_vec(fields);
+                (struct_exprs(&field_vec, &method_ident), field_vec)
+            }
+            _ => panic!(format!("Unit structs cannot use derive({})", trait_name)),
+        },
+
+        _ => panic!(format!("Only structs can use derive({})", trait_name)),
+    };
+
+    let scalar_ident = &Ident::new("__RhsT", Span::call_site());
+    let tys: &HashSet<_> = &get_field_types_iter(&fields).collect();
+    let scalar_iter = iter::repeat(scalar_ident);
+    let trait_path_iter = iter::repeat(trait_path);
+
+    let type_where_clauses = quote!{
+        where #(#tys: #trait_path_iter<#scalar_iter>),*
+    };
+
+    let new_generics =
+        add_where_clauses_for_new_ident(&input.generics, &fields, scalar_ident, type_where_clauses);
+    let (impl_generics, _, where_clause) = new_generics.split_for_impl();
+    let (_, ty_generics, _) = input.generics.split_for_impl();
+
+    quote!(
+        impl#impl_generics #trait_path<#scalar_ident> for #input_type#ty_generics #where_clause{
+            #[inline]
+            fn #method_ident(&mut self, rhs: #scalar_ident#ty_generics) {
+                #(#exprs;
+                  )*
+            }
+        }
+    )
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/derive_more/src/mul_like.rs
@@ -0,0 +1,97 @@
+use proc_macro2::{Span, TokenStream};
+use quote::ToTokens;
+use std::collections::HashSet;
+use std::iter;
+use syn::{Data, DeriveInput, Field, Fields, Ident};
+use utils::{
+    add_where_clauses_for_new_ident, field_idents, get_field_types_iter, named_to_vec,
+    number_idents, unnamed_to_vec,
+};
+
+pub fn expand(input: &DeriveInput, trait_name: &str) -> TokenStream {
+    let trait_ident = Ident::new(trait_name, Span::call_site());
+    let trait_path = &quote!(::std::ops::#trait_ident);
+    let method_name = trait_name.to_lowercase();
+    let method_ident = &Ident::new(&method_name, Span::call_site());
+    let input_type = &input.ident;
+
+    let (block, fields) = match input.data {
+        Data::Struct(ref data_struct) => match data_struct.fields {
+            Fields::Unnamed(ref fields) => {
+                let field_vec = unnamed_to_vec(fields);
+                (
+                    tuple_content(input_type, &field_vec, method_ident),
+                    field_vec,
+                )
+            }
+            Fields::Named(ref fields) => {
+                let field_vec = named_to_vec(fields);
+                (
+                    struct_content(input_type, &field_vec, method_ident),
+                    field_vec,
+                )
+            }
+            _ => panic!(format!("Unit structs cannot use derive({})", trait_name)),
+        },
+        _ => panic!(format!("Only structs can use derive({})", trait_name)),
+    };
+
+    let scalar_ident = &Ident::new("__RhsT", Span::call_site());
+    let tys: &HashSet<_> = &get_field_types_iter(&fields).collect();
+    let tys2 = tys;
+    let scalar_iter = iter::repeat(scalar_ident);
+    let trait_path_iter = iter::repeat(trait_path);
+
+    let type_where_clauses = quote!{
+        where #(#tys: #trait_path_iter<#scalar_iter, Output=#tys2>),*
+    };
+
+    let new_generics =
+        add_where_clauses_for_new_ident(&input.generics, &fields, scalar_ident, type_where_clauses);
+    let (impl_generics, _, where_clause) = new_generics.split_for_impl();
+    let (_, ty_generics, _) = input.generics.split_for_impl();
+
+    quote!(
+        impl#impl_generics  #trait_path<#scalar_ident> for #input_type#ty_generics #where_clause {
+            type Output = #input_type#ty_generics;
+            #[inline]
+            fn #method_ident(self, rhs: #scalar_ident) -> #input_type#ty_generics {
+                #block
+            }
+        }
+
+    )
+}
+
+fn tuple_content<'a, T: ToTokens>(
+    input_type: &T,
+    fields: &[&'a Field],
+    method_ident: &Ident,
+) -> TokenStream {
+    let exprs = tuple_exprs(fields, method_ident);
+    quote!(#input_type(#(#exprs),*))
+}
+
+pub fn tuple_exprs(fields: &[&Field], method_ident: &Ident) -> Vec<TokenStream> {
+    number_idents(fields.len())
+        .iter()
+        .map(|i| quote!(self.#i.#method_ident(rhs)))
+        .collect()
+}
+
+fn struct_content<'a, T: ToTokens>(
+    input_type: &T,
+    fields: &[&'a Field],
+    method_ident: &Ident,
+) -> TokenStream {
+    let exprs = struct_exprs(fields, method_ident);
+    let field_names = field_idents(fields);
+    quote!(#input_type{#(#field_names: #exprs),*})
+}
+
+pub fn struct_exprs(fields: &[&Field], method_ident: &Ident) -> Vec<TokenStream> {
+    field_idents(fields)
+        .iter()
+        .map(|f| quote!(self.#f.#method_ident(rhs)))
+        .collect()
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/derive_more/src/not_like.rs
@@ -0,0 +1,159 @@
+use proc_macro2::{Span, TokenStream};
+use quote::ToTokens;
+use std::iter;
+use syn::{Data, DataEnum, DeriveInput, Field, Fields, Ident, Index};
+use utils::{add_extra_type_param_bound_op_output, named_to_vec, unnamed_to_vec};
+
+pub fn expand(input: &DeriveInput, trait_name: &str) -> TokenStream {
+    let trait_ident = Ident::new(trait_name, Span::call_site());
+    let method_name = trait_name.to_lowercase();
+    let method_ident = &Ident::new(&method_name, Span::call_site());
+    let input_type = &input.ident;
+
+    let generics = add_extra_type_param_bound_op_output(&input.generics, &trait_ident);
+    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
+
+    let (output_type, block) = match input.data {
+        Data::Struct(ref data_struct) => match data_struct.fields {
+            Fields::Unnamed(ref fields) => (
+                quote!(#input_type#ty_generics),
+                tuple_content(input_type, &unnamed_to_vec(fields), method_ident),
+            ),
+            Fields::Named(ref fields) => (
+                quote!(#input_type#ty_generics),
+                struct_content(input_type, &named_to_vec(fields), method_ident),
+            ),
+            _ => panic!(format!("Unit structs cannot use derive({})", trait_name)),
+        },
+        Data::Enum(ref data_enum) => enum_output_type_and_content(input, data_enum, method_ident),
+
+        _ => panic!(format!(
+            "Only structs and enums can use derive({})",
+            trait_name
+        )),
+    };
+
+    quote!(
+        impl#impl_generics ::std::ops::#trait_ident for #input_type#ty_generics #where_clause {
+            type Output = #output_type;
+            fn #method_ident(self) -> #output_type {
+                #block
+            }
+        }
+    )
+}
+
+fn tuple_content<T: ToTokens>(
+    input_type: &T,
+    fields: &[&Field],
+    method_ident: &Ident,
+) -> TokenStream {
+    let mut exprs = vec![];
+
+    for i in 0..fields.len() {
+        let i = Index::from(i);
+        // generates `self.0.add()`
+        let expr = quote!(self.#i.#method_ident());
+        exprs.push(expr);
+    }
+
+    quote!(#input_type(#(#exprs),*))
+}
+
+fn struct_content(input_type: &Ident, fields: &[&Field], method_ident: &Ident) -> TokenStream {
+    let mut exprs = vec![];
+
+    for field in fields {
+        // It's safe to unwrap because struct fields always have an identifier
+        let field_id = field.ident.as_ref();
+        // generates `x: self.x.not()`
+        let expr = quote!(#field_id: self.#field_id.#method_ident());
+        exprs.push(expr)
+    }
+
+    quote!(#input_type{#(#exprs),*})
+}
+
+fn enum_output_type_and_content(
+    input: &DeriveInput,
+    data_enum: &DataEnum,
+    method_ident: &Ident,
+) -> (TokenStream, TokenStream) {
+    let input_type = &input.ident;
+    let (_, ty_generics, _) = input.generics.split_for_impl();
+    let mut matches = vec![];
+    let mut method_iter = iter::repeat(method_ident);
+    // If the enum contains unit types that means it can error.
+    let has_unit_type = data_enum.variants.iter().any(|v| v.fields == Fields::Unit);
+
+    for variant in &data_enum.variants {
+        let subtype = &variant.ident;
+        let subtype = quote!(#input_type::#subtype);
+
+        match variant.fields {
+            Fields::Unnamed(ref fields) => {
+                // The patern that is outputted should look like this:
+                // (Subtype(vars)) => Ok(TypePath(exprs))
+                let size = unnamed_to_vec(fields).len();
+                let vars: &Vec<_> = &(0..size)
+                    .map(|i| Ident::new(&format!("__{}", i), Span::call_site()))
+                    .collect();
+                let method_iter = method_iter.by_ref();
+                let mut body = quote!(#subtype(#(#vars.#method_iter()),*));
+                if has_unit_type {
+                    body = quote!(::std::result::Result::Ok(#body))
+                }
+                let matcher = quote!{
+                    #subtype(#(#vars),*) => {
+                        #body
+                    }
+                };
+                matches.push(matcher);
+            }
+            Fields::Named(ref fields) => {
+                // The patern that is outputted should look like this:
+                // (Subtype{a: __l_a, ...} => {
+                //     Ok(Subtype{a: __l_a.neg(__r_a), ...})
+                // }
+                let field_vec = named_to_vec(fields);
+                let size = field_vec.len();
+                let field_names: &Vec<_> = &field_vec
+                    .iter()
+                    .map(|f| f.ident.as_ref().unwrap())
+                    .collect();
+                let vars: &Vec<_> = &(0..size)
+                    .map(|i| Ident::new(&format!("__{}", i), Span::call_site()))
+                    .collect();
+                let method_iter = method_iter.by_ref();
+                let mut body = quote!(#subtype{#(#field_names: #vars.#method_iter()),*});
+                if has_unit_type {
+                    body = quote!(::std::result::Result::Ok(#body))
+                }
+                let matcher = quote!{
+                    #subtype{#(#field_names: #vars),*} => {
+                        #body
+                    }
+                };
+                matches.push(matcher);
+            }
+            Fields::Unit => {
+                let message = format!("Cannot {}() unit variants", method_ident.to_string());
+                matches.push(quote!(#subtype => ::std::result::Result::Err(#message)));
+            }
+        }
+    }
+
+    let body = quote!(
+        match self {
+            #(#matches),*
+        }
+    );
+
+    let output_type = if has_unit_type {
+        quote!(::std::result::Result<#input_type#ty_generics, &'static str>)
+    } else {
+        quote!(#input_type#ty_generics)
+    };
+
+    (output_type, body)
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/derive_more/src/try_into.rs
@@ -0,0 +1,91 @@
+use proc_macro2::TokenStream;
+use quote::ToTokens;
+use std::collections::HashMap;
+use syn::{Data, DataEnum, DeriveInput, Fields};
+use utils::{field_idents, named_to_vec, numbered_vars, unnamed_to_vec};
+
+/// Provides the hook to expand `#[derive(TryInto)]` into an implementation of `TryInto`
+pub fn expand(input: &DeriveInput, _: &str) -> TokenStream {
+    match input.data {
+        Data::Enum(ref data_enum) => enum_try_into(input, data_enum),
+        _ => panic!("Only enums can derive TryInto"),
+    }
+}
+
+fn enum_try_into(input: &DeriveInput, data_enum: &DataEnum) -> TokenStream {
+    let mut variants_per_types = HashMap::new();
+    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
+    let input_type = &input.ident;
+
+    for variant in &data_enum.variants {
+        let original_types = match variant.fields {
+            Fields::Unnamed(ref fields) => unnamed_to_vec(fields).iter().map(|f| &f.ty).collect(),
+            Fields::Named(ref fields) => named_to_vec(fields).iter().map(|f| &f.ty).collect(),
+            Fields::Unit => vec![],
+        };
+        variants_per_types
+            .entry(original_types)
+            .or_insert_with(Vec::new)
+            .push(variant);
+    }
+
+    let mut tokens = TokenStream::new();
+
+    for (ref original_types, ref variants) in variants_per_types {
+        let mut matchers = vec![];
+        let vars = &numbered_vars(original_types.len(), "");
+        for variant in variants.iter() {
+            let subtype = &variant.ident;
+            let subtype = quote!(#input_type::#subtype);
+            matchers.push(match variant.fields {
+                Fields::Unnamed(_) => quote!(#subtype(#(#vars),*)),
+                Fields::Named(ref fields) => {
+                    let field_vec = &named_to_vec(fields);
+                    let field_names = &field_idents(field_vec);
+                    quote!(#subtype{#(#field_names: #vars),*})
+                }
+                Fields::Unit => quote!(#subtype),
+            });
+        }
+
+        let vars = if vars.len() == 1 {
+            quote!(#(#vars)*)
+        } else {
+            quote!((#(#vars),*))
+        };
+
+        let output_type = if original_types.len() == 1 {
+            format!("{}", quote!(#(#original_types)*))
+        } else {
+            let types = original_types
+                .iter()
+                .map(|t| format!("{}", quote!(#t)))
+                .collect::<Vec<_>>();
+            format!("({})", types.join(", "))
+        };
+        let variants = variants
+            .iter()
+            .map(|v| format!("{}", v.ident))
+            .collect::<Vec<_>>()
+            .join(", ");
+        let message = format!("Only {} can be converted to {}", variants, output_type);
+
+        let try_from = quote!{
+            impl#impl_generics ::std::convert::TryFrom<#input_type#ty_generics> for
+                (#(#original_types),*) #where_clause {
+                type Error = &'static str;
+
+                #[allow(unused_variables)]
+                #[inline]
+                fn try_from(value: #input_type#ty_generics) -> Result<Self, Self::Error> {
+                    match value {
+                        #(#matchers)|* => ::std::result::Result::Ok(#vars),
+                        _ => ::std::result::Result::Err(#message),
+                    }
+                }
+            }
+        };
+        try_from.to_tokens(&mut tokens)
+    }
+    tokens
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/derive_more/src/utils.rs
@@ -0,0 +1,105 @@
+use proc_macro2::{Span, TokenStream};
+use syn::{
+    parse_str, Field, FieldsNamed, FieldsUnnamed, GenericParam,
+    Generics, Ident, Index, Type, TypeParamBound, WhereClause,
+};
+
+pub fn numbered_vars(count: usize, prefix: &str) -> Vec<Ident> {
+    (0..count)
+        .map(|i| Ident::new(&format!("__{}{}", prefix, i), Span::call_site()))
+        .collect()
+}
+
+pub fn number_idents(count: usize) -> Vec<Index> {
+    (0..count).map(Index::from).collect()
+}
+
+pub fn field_idents<'a>(fields: &'a [&'a Field]) -> Vec<&'a Ident> {
+    fields
+        .iter()
+        .map(|f| {
+            f.ident
+                .as_ref()
+                .expect("Tried to get field names of a tuple struct")
+        }).collect()
+}
+
+pub fn get_field_types_iter<'a>(fields: &'a [&'a Field]) -> Box<Iterator<Item = &'a Type> + 'a> {
+    Box::new(fields.iter().map(|f| &f.ty))
+}
+
+pub fn get_field_types<'a>(fields: &'a [&'a Field]) -> Vec<&'a Type> {
+    get_field_types_iter(fields).collect()
+}
+
+pub fn add_extra_type_param_bound_op_output<'a>(
+    generics: &'a Generics,
+    trait_ident: &'a Ident,
+) -> Generics {
+    let mut generics = generics.clone();
+    for type_param in &mut generics.type_params_mut() {
+        let type_ident = &type_param.ident;
+        let bound: TypeParamBound =
+            parse_str(&quote!(::std::ops::#trait_ident<Output=#type_ident>).to_string()).unwrap();
+        type_param.bounds.push(bound)
+    }
+
+    generics
+}
+
+pub fn add_extra_ty_param_bound_op<'a>(generics: &'a Generics, trait_ident: &'a Ident) -> Generics {
+    add_extra_ty_param_bound(generics, &quote!(::std::ops::#trait_ident))
+}
+
+pub fn add_extra_ty_param_bound<'a>(generics: &'a Generics, bound: &'a TokenStream) -> Generics {
+    let mut generics = generics.clone();
+    let bound: TypeParamBound = parse_str(&bound.to_string()).unwrap();
+    for type_param in &mut generics.type_params_mut() {
+        type_param.bounds.push(bound.clone())
+    }
+
+    generics
+}
+
+pub fn add_extra_generic_param(generics: &Generics, generic_param: TokenStream) -> Generics {
+    let generic_param: GenericParam = parse_str(&generic_param.to_string()).unwrap();
+    let mut generics = generics.clone();
+    generics.params.push(generic_param);
+
+    generics
+}
+
+pub fn add_extra_where_clauses(generics: &Generics, type_where_clauses: TokenStream) -> Generics {
+    let mut type_where_clauses: WhereClause = parse_str(&type_where_clauses.to_string()).unwrap();
+    let mut new_generics = generics.clone();
+    if let Some(old_where) = new_generics.where_clause {
+        type_where_clauses.predicates.extend(old_where.predicates)
+    }
+    new_generics.where_clause = Some(type_where_clauses);
+
+    new_generics
+}
+
+pub fn add_where_clauses_for_new_ident<'a>(
+    generics: &'a Generics,
+    fields: &[&'a Field],
+    type_ident: &Ident,
+    type_where_clauses: TokenStream,
+) -> Generics {
+    let generic_param = if fields.len() > 1 {
+        quote!(#type_ident: ::std::marker::Copy)
+    } else {
+        quote!(#type_ident)
+    };
+
+    let generics = add_extra_where_clauses(generics, type_where_clauses);
+    add_extra_generic_param(&generics, generic_param)
+}
+
+pub fn unnamed_to_vec(fields: &FieldsUnnamed) -> Vec<&Field> {
+    fields.unnamed.iter().collect()
+}
+
+pub fn named_to_vec(fields: &FieldsNamed) -> Vec<&Field> {
+    fields.named.iter().collect()
+}
--- 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":"2f437f4dd58d6813bfa542ffb1ed4c970c3670739f92c41346230e7a5b05796a","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"c9a75f18b9ab2927829a208fc6aa2cf4e63b8420887ba29cdb265d6619ae82d5","README.md":"b4cb2c1de00ae7382a77431d221a52e10a8a62170cdc1a2ad1c1e711bea7817f","src/errors.rs":"b28c2eeb1278fc3e8d68a64b177034faed67f6762335729d3a6d1e61be8fb034","src/lib.rs":"6a5d5ceb57cf03955af1dbb80a6401ca6d5eac65211d0594354b38b465ce7b45"},"package":"b9743a7670d88d5d52950408ecdb7c71d8986251ab604d4689dd2ca25c9bca69"}
\ No newline at end of file
+{"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
--- a/third_party/rust/rustc_version/Cargo.toml
+++ b/third_party/rust/rustc_version/Cargo.toml
@@ -1,15 +1,26 @@
+# 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
+#
+# 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]
 name = "rustc_version"
-version = "0.2.1"
+version = "0.2.3"
 authors = ["Marvin Löbel <loebel.marvin@gmail.com>"]
-license = "MIT/Apache-2.0"
-
 description = "A library for querying the version of a installed rustc compiler"
+documentation = "https://docs.rs/rustc_version/"
 readme = "README.md"
-documentation = "http://kimundi.github.io/rustc-version-rs/rustc_version/index.html"
-
+keywords = ["version", "rustc"]
+license = "MIT/Apache-2.0"
 repository = "https://github.com/Kimundi/rustc-version-rs"
-keywords = ["version", "rustc"]
-
-[dependencies]
-semver = "0.6"
+[dependencies.semver]
+version = "0.9"
+[badges.travis-ci]
+repository = "Kimundi/rustc-version-rs"
--- a/third_party/rust/rustc_version/README.md
+++ b/third_party/rust/rustc_version/README.md
@@ -13,17 +13,17 @@ to make decisions based on the version o
 [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
-[dependencies]
+[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.
 
 # Example
 
 ```rust
--- a/third_party/rust/rustc_version/src/lib.rs
+++ b/third_party/rust/rustc_version/src/lib.rs
@@ -103,96 +103,90 @@ pub struct VersionMeta {
     pub short_version_string: String,
 }
 
 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;
 
-        let out = match cmd.arg("-vV").output() {
-            Err(e) => return Err(Error::CouldNotExecuteCommand(e)),
-            Ok(out) => out,
-        };
-        let out = try!(str::from_utf8(&out.stdout));
+        let out = cmd.arg("-vV").output().map_err(Error::CouldNotExecuteCommand)?;
+        let out = str::from_utf8(&out.stdout)?;
 
         version_meta_for(out)
     }
 }
 
 /// Returns the `rustc` SemVer version.
 pub fn version() -> Result<Version> {
-    Ok(try!(version_meta()).semver)
+    Ok(version_meta()?.semver)
 }
 
 /// Returns the `rustc` SemVer version and additional metadata
 /// like the git short hash and build date.
 pub fn version_meta() -> Result<VersionMeta> {
     let cmd = env::var_os("RUSTC").unwrap_or_else(|| OsString::from("rustc"));
 
     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 short_version_string = out[0];
 
     fn expect_prefix<'a>(line: &'a str, prefix: &str) -> Result<&'a str> {
-        match line.starts_with(prefix) {
-            true => Ok(&line[prefix.len()..]),
-            false => Err(Error::UnexpectedVersionFormat),
+        if line.starts_with(prefix) {
+            Ok(&line[prefix.len()..])
+        } else {
+            Err(Error::UnexpectedVersionFormat)
         }
     }
 
-    let commit_hash = match try!(expect_prefix(out[2], "commit-hash: ")) {
+    let commit_hash = match expect_prefix(out[2], "commit-hash: ")? {
         "unknown" => None,
         hash => Some(hash.to_owned()),
     };
 
-    let commit_date = match try!(expect_prefix(out[3], "commit-date: ")) {
+    let commit_date = match expect_prefix(out[3], "commit-date: ")? {
         "unknown" => None,
         hash => Some(hash.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 try!(expect_prefix(out[idx], "build-date: ")) {
+        build_date = match expect_prefix(out[idx], "build-date: ")? {
             "unknown" => None,
             s => Some(s.to_owned()),
         };
-        idx = idx + 1;
+        idx += 1;
     }
 
-    let host = try!(expect_prefix(out[idx], "host: "));
-    idx = idx + 1;
-    let release = try!(expect_prefix(out[idx], "release: "));
+    let host = expect_prefix(out[idx], "host: ")?;
+    idx += 1;
+    let release = expect_prefix(out[idx], "release: ")?;
 
-    let semver: Version = try!(release.parse());
+    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,
+            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())),
         }
     };
 
     Ok(VersionMeta {
         semver: semver,
         commit_hash: commit_hash,
         commit_date: commit_date,
copy from third_party/rust/semver/.cargo-checksum.json
copy to third_party/rust/semver-0.6.0/.cargo-checksum.json
copy from third_party/rust/semver/Cargo.toml
copy to third_party/rust/semver-0.6.0/Cargo.toml
new file mode 100644
--- /dev/null
+++ b/third_party/rust/semver-0.6.0/LICENSE-APACHE
@@ -0,0 +1,201 @@
+                              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.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/semver-0.6.0/LICENSE-MIT
@@ -0,0 +1,25 @@
+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
+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.
copy from third_party/rust/semver/README.md
copy to third_party/rust/semver-0.6.0/README.md
copy from third_party/rust/semver/src/lib.rs
copy to third_party/rust/semver-0.6.0/src/lib.rs
copy from third_party/rust/semver/src/version.rs
copy to third_party/rust/semver-0.6.0/src/version.rs
copy from third_party/rust/semver/src/version_req.rs
copy to third_party/rust/semver-0.6.0/src/version_req.rs
new file mode 100644
--- /dev/null
+++ b/third_party/rust/semver-0.6.0/tests/deprecation.rs
@@ -0,0 +1,22 @@
+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);
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/semver-0.6.0/tests/regression.rs
@@ -0,0 +1,25 @@
+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);
+        }
+    }
+}
--- a/third_party/rust/semver/.cargo-checksum.json
+++ b/third_party/rust/semver/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"d02f51526644dbe6c82add37202f246a6b95e185a5519ef0c3ca4d55a245f22c","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"bb80bfbd16bf7dc34de45891c21333c42590d5c5c10e8ba0ed59549fce5af1dd","src/lib.rs":"b33fcb9a79d46a581a4628f7c2bb00f7ba3451b1acfeeae0b38ff22532ed5b68","src/version.rs":"fc36d1e58c9a73f46fdec63283fd50ea78c89a0f816b8abaaa89438fb0c47c70","src/version_req.rs":"093f2ac08f2bc8fcf6a93ae0fc333eccc1ea04932e0c0b26835a952bb220eca1","tests/deprecation.rs":"b5ec79e19d61968d05b96b876c449e54d43cbd1762c6e63c23c3470f9db56292","tests/regression.rs":"180b699ad029b81e6135d42f0a8e6d782177bc29a41132f875ee6f8607a46b56"},"package":"7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"}
\ No newline at end of file
+{"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
--- a/third_party/rust/semver/Cargo.toml
+++ b/third_party/rust/semver/Cargo.toml
@@ -1,25 +1,45 @@
+# 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
+#
+# 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]
-
 name = "semver"
-version = "0.6.0"
+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/"
+readme = "README.md"
 license = "MIT/Apache-2.0"
 repository = "https://github.com/steveklabnik/semver"
-homepage = "https://docs.rs/crate/semver/"
-documentation = "https://docs.rs/crate/semver/"
-description = """
-Semantic version parsing and comparison.
-"""
+[dependencies.semver-parser]
+version = "0.7.0"
+
+[dependencies.serde]
+version = "1.0"
+optional = true
+[dev-dependencies.crates-index]
+version = "0.5.0"
 
-[dependencies]
-semver-parser = "0.7.0"
+[dev-dependencies.serde_json]
+version = "1.0"
+
+[dev-dependencies.serde_derive]
+version = "1.0"
+
+[dev-dependencies.tempdir]
+version = "0.3.4"
 
 [features]
 default = []
-
-# are we testing on CI?
-ci = []
-
-[dev-dependencies]
-crates-index = "0.5.0"
-tempdir = "0.3.4"
+ci = ["serde"]
+[badges.travis-ci]
+repository = "steveklabnik/semver"
--- a/third_party/rust/semver/README.md
+++ b/third_party/rust/semver/README.md
@@ -18,17 +18,17 @@ not tied together.
 [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:
 
 ```toml
-semver = "0.6.0"
+semver = "0.7.0"
 ```
 
 And this to your crate root:
 
 ```rust
 extern crate semver;
 ```
 
--- a/third_party/rust/semver/src/lib.rs
+++ b/third_party/rust/semver/src/lib.rs
@@ -159,16 +159,20 @@
 
 #![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))]
 
 extern crate semver_parser;
 
+// Serialization and deserialization support for version numbers
+#[cfg(feature = "serde")]
+extern crate serde;
+
 // We take the common approach of keeping our own module system private, and
 // just re-exporting the interface that we want.
 
 pub use version::{Version, Identifier, SemVerError};
 pub use version::Identifier::{Numeric, AlphaNumeric};
 pub use version_req::{VersionReq, ReqParseError};
 
 // SemVer-compliant versions.
--- a/third_party/rust/semver/src/version.rs
+++ b/third_party/rust/semver/src/version.rs
@@ -16,16 +16,21 @@ 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),
@@ -47,16 +52,61 @@ impl fmt::Display for Identifier {
     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,
@@ -76,16 +126,52 @@ impl From<semver_parser::version::Versio
             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),
 }
@@ -105,16 +191,28 @@ impl Error for SemVerError {
         }
     }
 }
 
 /// 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)),
@@ -243,16 +341,23 @@ 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]
@@ -279,16 +384,20 @@ mod tests {
         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(),
                    }));
--- a/third_party/rust/semver/src/version_req.rs
+++ b/third_party/rust/semver/src/version_req.rs
@@ -5,48 +5,90 @@
 // 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(PartialEq,Clone,Debug)]
+#[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() }
     }
 }
 
-#[derive(Clone, PartialEq, Debug)]
+#[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(PartialEq,Clone,Debug)]
+#[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 ^
@@ -70,17 +112,17 @@ impl From<semver_parser::range::Op> for 
                     range::WildcardVersion::Minor => Op::Wildcard(WildcardVersion::Minor),
                     range::WildcardVersion::Patch => Op::Wildcard(WildcardVersion::Patch),
                 }
             }
         }
     }
 }
 
-#[derive(PartialEq,Clone,Debug)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
 struct Predicate {
     op: Op,
     major: u64,
     minor: Option<u64>,
     patch: Option<u64>,
     pre: Vec<Identifier>,
 }
 
@@ -163,32 +205,33 @@ impl VersionReq {
     /// use semver::VersionReq;
     ///
     /// let anything = VersionReq::any();
     /// ```
     pub fn any() -> VersionReq {
         VersionReq { predicates: vec![] }
     }
 
-    /// `parse()` is the main constructor of a `VersionReq`. It turns a string like `"^1.2.3"`
+    /// `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;
@@ -518,16 +561,17 @@ impl fmt::Display for Op {
         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,
@@ -542,16 +586,24 @@ mod test {
     }
 
     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"]);
@@ -816,9 +868,28 @@ mod test {
         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("*"));
+    }
 }
new file mode 100644
--- /dev/null
+++ b/third_party/rust/semver/tests/serde.rs
@@ -0,0 +1,90 @@
+#![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());
+}
--- a/toolkit/library/rust/shared/Cargo.toml
+++ b/toolkit/library/rust/shared/Cargo.toml
@@ -28,19 +28,17 @@ rsdparsa_capi = { path = "../../../../me
 log = {version = "0.4", features = ["release_max_level_info"]}
 env_logger = {version = "0.5", default-features = false} # disable `regex` to reduce code size
 cose-c = { version = "0.1.5" }
 rkv = "0.5"
 jsrust_shared = { path = "../../../../js/src/rust/shared", optional = true }
 arrayvec = "0.4"
 
 [build-dependencies]
-# Use exactly version 0.2.1, which uses semver 0.6, which other crates
-# require (0.2.2 requires 0.9)
-rustc_version = "=0.2.1"
+rustc_version = "0.2"
 
 [features]
 default = []
 bindgen = ["geckoservo/bindgen"]
 servo = ["geckoservo"]
 quantum_render = ["webrender_bindings"]
 cubeb-remoting = ["cubeb-sys", "audioipc-client", "audioipc-server"]
 cubeb_pulse_rust = ["cubeb-sys", "cubeb-pulse"]