Bug 1341102: Revendor rust dependencies; r=bustage
authorManish Goregaokar <manishearth@gmail.com>
Tue, 28 Feb 2017 09:22:51 -0800
changeset 394156 17b6cdda4c106fba27557407fe598b08d5ffbf65
parent 394155 7d83ebea9020daa786f4368adc906f4d5c697d74
child 394157 ce4d5be6f3fb01e6f896d7be1ee5a027289b28a4
push id1468
push userasasaki@mozilla.com
push dateMon, 05 Jun 2017 19:31:07 +0000
treeherdermozilla-release@0641fc6ee9d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbustage
bugs1341102
milestone54.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 1341102: Revendor rust dependencies; r=bustage MozReview-Commit-ID: 7hXRyaLssOZ
third_party/rust/bincode/.cargo-checksum.json
third_party/rust/bincode/Cargo.toml
third_party/rust/bincode/readme.md
third_party/rust/bincode/src/lib.rs
third_party/rust/bincode/src/serde/mod.rs
third_party/rust/bincode/src/serde/reader.rs
third_party/rust/bincode/src/serde/writer.rs
third_party/rust/bincode/tests/test.rs
third_party/rust/clap/.cargo-checksum.json
third_party/rust/clap/.github/CONTRIBUTING.md
third_party/rust/clap/CHANGELOG.md
third_party/rust/clap/Cargo.toml
third_party/rust/clap/README.md
third_party/rust/clap/src/app/mod.rs
third_party/rust/clap/src/app/parser.rs
third_party/rust/clap/src/macros.rs
third_party/rust/cssparser-macros/.cargo-checksum.json
third_party/rust/cssparser-macros/Cargo.toml
third_party/rust/cssparser-macros/lib.rs
third_party/rust/cssparser/.cargo-checksum.json
third_party/rust/cssparser/Cargo.toml
third_party/rust/cssparser/build.rs
third_party/rust/cssparser/build/match_byte.rs
third_party/rust/cssparser/src/color.rs
third_party/rust/cssparser/src/lib.rs
third_party/rust/cssparser/src/macros.rs
third_party/rust/cssparser/src/macros/match_byte.rs
third_party/rust/cssparser/src/macros/mod.rs
third_party/rust/cssparser/src/tests.rs
third_party/rust/env_logger/.cargo-checksum.json
third_party/rust/env_logger/Cargo.toml
third_party/rust/env_logger/LICENSE-APACHE
third_party/rust/env_logger/LICENSE-MIT
third_party/rust/num-integer/.cargo-checksum.json
third_party/rust/num-integer/Cargo.toml
third_party/rust/num-integer/LICENSE-APACHE
third_party/rust/num-integer/LICENSE-MIT
third_party/rust/num-integer/src/lib.rs
third_party/rust/num-traits/.cargo-checksum.json
third_party/rust/num-traits/Cargo.toml
third_party/rust/num-traits/LICENSE-APACHE
third_party/rust/num-traits/LICENSE-MIT
third_party/rust/num-traits/src/int.rs
third_party/rust/num-traits/src/lib.rs
third_party/rust/num-traits/src/ops/mod.rs
third_party/rust/num-traits/src/ops/wrapping.rs
third_party/rust/parking_lot/.cargo-checksum.json
third_party/rust/parking_lot/Cargo.toml
third_party/rust/parking_lot/src/rwlock.rs
third_party/rust/pdqsort/.cargo-checksum.json
third_party/rust/pdqsort/Cargo.toml
third_party/rust/pdqsort/README.md
third_party/rust/pdqsort/benches/bench.rs
third_party/rust/pdqsort/src/lib.rs
third_party/rust/procedural-masquerade/.cargo-checksum.json
third_party/rust/procedural-masquerade/.cargo-ok
third_party/rust/procedural-masquerade/Cargo.toml
third_party/rust/procedural-masquerade/lib.rs
third_party/rust/quote/.cargo-checksum.json
third_party/rust/quote/Cargo.toml
third_party/rust/quote/LICENSE-APACHE
third_party/rust/quote/LICENSE-MIT
third_party/rust/quote/README.md
third_party/rust/quote/src/tokens.rs
third_party/rust/quote/tests/test.rs
third_party/rust/serde/.cargo-checksum.json
third_party/rust/serde/Cargo.toml
third_party/rust/serde/LICENSE-APACHE
third_party/rust/serde/LICENSE-MIT
third_party/rust/serde/README.md
third_party/rust/serde/src/bytes.rs
third_party/rust/serde/src/de/content.rs
third_party/rust/serde/src/de/impls.rs
third_party/rust/serde/src/de/mod.rs
third_party/rust/serde/src/de/private.rs
third_party/rust/serde/src/de/value.rs
third_party/rust/serde/src/error.rs
third_party/rust/serde/src/iter.rs
third_party/rust/serde/src/lib.rs
third_party/rust/serde/src/macros.rs
third_party/rust/serde/src/ser/content.rs
third_party/rust/serde/src/ser/impls.rs
third_party/rust/serde/src/ser/impossible.rs
third_party/rust/serde/src/ser/mod.rs
third_party/rust/serde/src/ser/private.rs
third_party/rust/serde/src/utils.rs
third_party/rust/serde_json/.cargo-checksum.json
third_party/rust/serde_json/Cargo.toml
third_party/rust/serde_json/LICENSE-APACHE
third_party/rust/serde_json/LICENSE-MIT
third_party/rust/serde_json/README.md
third_party/rust/serde_json/src/de.rs
third_party/rust/serde_json/src/error.rs
third_party/rust/serde_json/src/lib.rs
third_party/rust/serde_json/src/macros.rs
third_party/rust/serde_json/src/map.rs
third_party/rust/serde_json/src/number.rs
third_party/rust/serde_json/src/read.rs
third_party/rust/serde_json/src/value.rs
third_party/rust/syn/.cargo-checksum.json
third_party/rust/syn/Cargo.toml
third_party/rust/syn/src/constant.rs
third_party/rust/syn/src/data.rs
third_party/rust/syn/src/expr.rs
third_party/rust/syn/src/lib.rs
third_party/rust/syn/src/ty.rs
third_party/rust/synom/.cargo-checksum.json
third_party/rust/synom/Cargo.toml
third_party/rust/synom/README.md
third_party/rust/synom/src/helper.rs
third_party/rust/term_size/.cargo-checksum.json
third_party/rust/term_size/CHANGELOG.md
third_party/rust/term_size/Cargo.toml
third_party/rust/term_size/src/lib.rs
third_party/rust/thread_local/.cargo-checksum.json
third_party/rust/thread_local/Cargo.toml
third_party/rust/thread_local/README.md
third_party/rust/thread_local/src/lib.rs
third_party/rust/xml-rs/.cargo-checksum.json
third_party/rust/xml-rs/Cargo.toml
third_party/rust/xml-rs/Changelog.md
third_party/rust/xml-rs/Readme.md
third_party/rust/xml-rs/src/escape.rs
third_party/rust/xml-rs/src/lib.rs
third_party/rust/xml-rs/src/writer/emitter.rs
toolkit/library/gtest/rust/Cargo.lock
toolkit/library/rust/Cargo.lock
--- a/third_party/rust/bincode/.cargo-checksum.json
+++ b/third_party/rust/bincode/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"e084df3ce631ce22082bd63f9e421e7f4d7a2408d6520de532f6a649e4d320dd",".travis.yml":"f705a11b487bf71c41ebd8223cc1f3cbde0dfdfeea96a100af55e06e93397a1b","Cargo.toml":"c1d0f68b42bff71b04c8e763f13b0141f30dc849bee5b0ab5b9008e3627aac99","LICENSE.md":"90d7e062634054e6866d3c81e6a2b3058a840e6af733e98e80bdfe1a7dec6912","changelist.org":"90bb4036f90c3792c8294de2e3d52a54cc6230c3e5dc78013a781a9aa468f5f3","examples/basic.rs":"57aeca11d5cc5c3d5bb613e78b2ea43a2e80d66c15a2fffae303b165aa4ab41d","logo.png":"ebc5305aae938c1f834cf35302faa8be0f1b7b8c3c3beef5cf6b2f68b9628c35","readme.dev.md":"43bad3bcc13a5c057344d3ba7f64bd2b313f8c133d6afa068108df73e8e8facd","readme.md":"1fe1bda36327400cfedfcf103d58091c8465067b62706b0a368d287ca0312cd9","src/lib.rs":"04d6e4533f4bbb2ce2126bca414f95610075642b223f4e0c0b8f7a573792d7fd","src/refbox.rs":"fe266cec4f9f36942a1a9a9ad094a4bb1003d0c0f3c070cfb6214790d0f21b69","src/serde/mod.rs":"ef0c0a55936d835ae756d84a6ac38de312687d7c0f2cfc6810ec994413464516","src/serde/reader.rs":"6bfde2e2df9b450f6c07576198e47fdc837bbc4ddc74f447c72875c188c72ddc","src/serde/writer.rs":"eb3b439e8822871d715464ef6aca4b93a73b2b57625f9c586b68007f7386ab12","tests/test.rs":"f009e979fda892ad531ddd0f2003f0a7df607b19bd453a53f87c9041dfd9c745"},"package":"62650bb5651ba8f0580cebf4ef255d791b8b0ef53800322661e1bb5791d42966"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"e084df3ce631ce22082bd63f9e421e7f4d7a2408d6520de532f6a649e4d320dd",".travis.yml":"f705a11b487bf71c41ebd8223cc1f3cbde0dfdfeea96a100af55e06e93397a1b","Cargo.toml":"8988a4300b10f78e0a3affbc4530827766c80c0d9847441e42e12017b09f7854","LICENSE.md":"90d7e062634054e6866d3c81e6a2b3058a840e6af733e98e80bdfe1a7dec6912","changelist.org":"90bb4036f90c3792c8294de2e3d52a54cc6230c3e5dc78013a781a9aa468f5f3","examples/basic.rs":"57aeca11d5cc5c3d5bb613e78b2ea43a2e80d66c15a2fffae303b165aa4ab41d","logo.png":"ebc5305aae938c1f834cf35302faa8be0f1b7b8c3c3beef5cf6b2f68b9628c35","readme.dev.md":"43bad3bcc13a5c057344d3ba7f64bd2b313f8c133d6afa068108df73e8e8facd","readme.md":"a70631b99064d77c968edf1e2f59415ff26c307589fa3767243376db44f00800","src/lib.rs":"84f115fcd9fe9a6fad489341f1134a24f178de46bfba6dab774a13212eac32ba","src/refbox.rs":"fe266cec4f9f36942a1a9a9ad094a4bb1003d0c0f3c070cfb6214790d0f21b69","src/serde/mod.rs":"5b4eaf256ec87f08bec20e0ac46184b3b336e87b2cb22f40bae6213613ae3081","src/serde/reader.rs":"8b223500017eff9eb9b634b74acefb96457db124e64fe594511abf12a4ef4207","src/serde/writer.rs":"5fd74db7389aebfd14c126dad56348ea5ad0d58bbbcc91a0757e9451c6ee977f","tests/test.rs":"8f595d83de63c0ce091626fd5875185fa29040cf77c47f3a27ceba30673d6e67"},"package":"db8831e3eb4e9ae608d826876fa422ffb15b47caa89fc1bcb96bfbe4f5ded8b2"}
\ No newline at end of file
--- a/third_party/rust/bincode/Cargo.toml
+++ b/third_party/rust/bincode/Cargo.toml
@@ -1,11 +1,11 @@
 [package]
 name = "bincode"
-version = "1.0.0-alpha2"
+version = "1.0.0-alpha4"
 authors = ["Ty Overby <ty@pre-alpha.com>", "Francesco Mazzoli <f@mazzo.li>", "David Tolnay <dtolnay@gmail.com>", "Daniel Griffen"]
 
 repository = "https://github.com/TyOverby/bincode"
 documentation = "https://docs.rs/bincode"
 keywords = ["binary", "encode", "decode", "serialize", "deserialize"]
 
 license = "MIT"
 description = "A binary serialization / deserialization strategy that uses Serde for transforming structs into bytes and vice versa!"
--- a/third_party/rust/bincode/readme.md
+++ b/third_party/rust/bincode/readme.md
@@ -11,17 +11,23 @@ The size of the encoded object will be t
 the object takes up in memory in a running Rust program.
 
 In addition to exposing two simple functions that encode to Vec<u8> and decode
 from Vec<u8>, binary-encode exposes a Reader/Writer API that makes it work
 perfectly with other stream-based apis such as rust files, network streams,
 and the [flate2-rs](https://github.com/alexcrichton/flate2-rs) compression
 library.
 
-[Api Documentation](http://tyoverby.github.io/bincode/bincode/)
+## [Api Documentation](http://tyoverby.github.io/bincode/bincode/)
+
+## Bincode in the wild
+
+* [google/tarpc](https://github.com/google/tarpc): Bincode is used to serialize and deserialize networked RPC messages.
+* [servo/webrender](https://github.com/servo/webrender): Bincode records webrender API calls for record/replay-style graphics debugging.
+* [servo/icp-channel](https://github.com/servo/ipc-channel): Ipc-Channel uses Bincode to send structs between processes using a channel-like API.
 
 ## Example
 ```rust
 extern crate bincode;
 extern crate rustc_serialize;
 
 use bincode::SizeLimit;
 use bincode::rustc_serialize::{encode, decode};
--- a/third_party/rust/bincode/src/lib.rs
+++ b/third_party/rust/bincode/src/lib.rs
@@ -38,17 +38,73 @@
 
 extern crate byteorder;
 extern crate num_traits;
 extern crate serde as serde_crate;
 
 pub mod refbox;
 mod serde;
 
-pub use serde::*;
+pub mod endian_choice {
+    pub use super::serde::{serialize, serialize_into, deserialize, deserialize_from};
+}
+
+use std::io::{Read, Write};
+
+pub use serde::{Deserializer, Serializer, ErrorKind, Error, Result, serialized_size, serialized_size_bounded};
+
+/// Deserializes a slice of bytes into an object.
+///
+/// This method does not have a size-limit because if you already have the bytes
+/// in memory, then you don't gain anything by having a limiter.
+pub fn deserialize<T>(bytes: &[u8]) -> serde::Result<T>
+    where T: serde_crate::Deserialize,
+{
+    serde::deserialize::<_, byteorder::LittleEndian>(bytes)
+}
+
+/// Deserializes an object directly from a `Buffer`ed Reader.
+///
+/// If the provided `SizeLimit` is reached, the deserialization will bail immediately.
+/// A SizeLimit can help prevent an attacker from flooding your server with
+/// a neverending stream of values that runs your server out of memory.
+///
+/// If this returns an `Error`, assume that the buffer that you passed
+/// in is in an invalid state, as the error could be returned during any point
+/// in the reading.
+pub fn deserialize_from<R: ?Sized, T>(reader: &mut R, size_limit: SizeLimit) -> serde::Result<T>
+    where R: Read,
+          T: serde_crate::Deserialize,
+{
+    serde::deserialize_from::<_, _, byteorder::LittleEndian>(reader, size_limit)
+}
+
+/// Serializes an object directly into a `Writer`.
+///
+/// If the serialization would take more bytes than allowed by `size_limit`, an error
+/// is returned and *no bytes* will be written into the `Writer`.
+///
+/// If this returns an `Error` (other than SizeLimit), assume that the
+/// writer is in an invalid state, as writing could bail out in the middle of
+/// serializing.
+pub fn serialize_into<W: ?Sized, T: ?Sized>(writer: &mut W, value: &T, size_limit: SizeLimit) -> serde::Result<()>
+    where W: Write, T: serde_crate::Serialize
+{
+    serde::serialize_into::<_, _, byteorder::LittleEndian>(writer, value, size_limit)
+}
+
+/// Serializes a serializable object into a `Vec` of bytes.
+///
+/// If the serialization would take more bytes than allowed by `size_limit`,
+/// an error is returned.
+pub fn serialize<T: ?Sized>(value: &T, size_limit: SizeLimit) -> serde::Result<Vec<u8>>
+    where T: serde_crate::Serialize
+{
+    serde::serialize::<_, byteorder::LittleEndian>(value, size_limit)
+}
 
 /// A limit on the amount of bytes that can be read or written.
 ///
 /// Size limits are an incredibly important part of both encoding and decoding.
 ///
 /// In order to prevent DOS attacks on a decoder, it is important to limit the
 /// amount of bytes that a single encoded message can be; otherwise, if you
 /// are decoding bytes right off of a TCP stream for example, it would be
--- a/third_party/rust/bincode/src/serde/mod.rs
+++ b/third_party/rust/bincode/src/serde/mod.rs
@@ -1,16 +1,17 @@
 //! A collection of serialization and deserialization functions
 //! that use the `serde` crate for the serializable and deserializable
 //! implementation.
 
 use std::io::{Write, Read};
 use std::io::Error as IoError;
 use std::{error, fmt, result};
 use ::SizeLimit;
+use byteorder::{ByteOrder};
 
 pub use self::reader::{
     Deserializer,
 };
 
 pub use self::writer::{
     Serializer,
 };
@@ -113,51 +114,50 @@ impl serde::ser::Error for Error {
 /// Serializes an object directly into a `Writer`.
 ///
 /// If the serialization would take more bytes than allowed by `size_limit`, an error
 /// is returned and *no bytes* will be written into the `Writer`.
 ///
 /// If this returns an `Error` (other than SizeLimit), assume that the
 /// writer is in an invalid state, as writing could bail out in the middle of
 /// serializing.
-pub fn serialize_into<W: ?Sized, T: ?Sized>(writer: &mut W, value: &T, size_limit: SizeLimit) -> Result<()>
-    where W: Write, 
-          T: serde::Serialize,
+pub fn serialize_into<W: ?Sized, T: ?Sized, E>(writer: &mut W, value: &T, size_limit: SizeLimit) -> Result<()>
+    where W: Write, T: serde::Serialize, E: ByteOrder
 {
     match size_limit {
         SizeLimit::Infinite => { }
         SizeLimit::Bounded(x) => {
             let mut size_checker = SizeChecker::new(x);
             try!(value.serialize(&mut size_checker))
         }
     }
 
-    let mut serializer = Serializer::new(writer);
+    let mut serializer = Serializer::<_, E>::new(writer);
     serde::Serialize::serialize(value, &mut serializer)
 }
 
 /// Serializes a serializable object into a `Vec` of bytes.
 ///
 /// If the serialization would take more bytes than allowed by `size_limit`,
 /// an error is returned.
-pub fn serialize<T: ?Sized>(value: &T, size_limit: SizeLimit) -> Result<Vec<u8>>
+pub fn serialize<T: ?Sized, E: ByteOrder>(value: &T, size_limit: SizeLimit) -> Result<Vec<u8>>
     where T: serde::Serialize
 {
     // Since we are putting values directly into a vector, we can do size
     // computation out here and pre-allocate a buffer of *exactly*
     // the right size.
     let mut writer = match size_limit {
         SizeLimit::Bounded(size_limit) => {
             let actual_size = try!(serialized_size_bounded(value, size_limit).ok_or(ErrorKind::SizeLimit));
             Vec::with_capacity(actual_size as usize)
         }
         SizeLimit::Infinite => Vec::new()
     };
 
-    try!(serialize_into(&mut writer, value, SizeLimit::Infinite));
+    try!(serialize_into::<_, _, E>(&mut writer, value, SizeLimit::Infinite));
     Ok(writer)
 }
 
 /// Returns the size that an object would be if serialized using bincode.
 ///
 /// This is used internally as part of the check for encode_into, but it can
 /// be useful for preallocating buffers if thats your style.
 pub fn serialized_size<T: ?Sized>(value: &T) -> u64 
@@ -185,26 +185,26 @@ pub fn serialized_size_bounded<T: ?Sized
 ///
 /// If the provided `SizeLimit` is reached, the deserialization will bail immediately.
 /// A SizeLimit can help prevent an attacker from flooding your server with
 /// a neverending stream of values that runs your server out of memory.
 ///
 /// If this returns an `Error`, assume that the buffer that you passed
 /// in is in an invalid state, as the error could be returned during any point
 /// in the reading.
-pub fn deserialize_from<R: ?Sized, T>(reader: &mut R, size_limit: SizeLimit) -> Result<T>
+pub fn deserialize_from<R: ?Sized, T, E: ByteOrder>(reader: &mut R, size_limit: SizeLimit) -> Result<T>
     where R: Read,
           T: serde::Deserialize,
 {
-    let mut deserializer = Deserializer::new(reader, size_limit);
+    let mut deserializer = Deserializer::<_, E>::new(reader, size_limit);
     serde::Deserialize::deserialize(&mut deserializer)
 }
 
 /// Deserializes a slice of bytes into an object.
 ///
 /// This method does not have a size-limit because if you already have the bytes
 /// in memory, then you don't gain anything by having a limiter.
-pub fn deserialize<T>(bytes: &[u8]) -> Result<T>
+pub fn deserialize<T, E: ByteOrder>(bytes: &[u8]) -> Result<T>
     where T: serde::Deserialize,
 {
     let mut reader = bytes;
-    deserialize_from(&mut reader, SizeLimit::Infinite)
+    deserialize_from::<_, _, E>(&mut reader, SizeLimit::Infinite)
 }
--- a/third_party/rust/bincode/src/serde/reader.rs
+++ b/third_party/rust/bincode/src/serde/reader.rs
@@ -1,39 +1,42 @@
 use std::io::Read;
+use std::marker::PhantomData;
 
-use byteorder::{BigEndian, ReadBytesExt};
+use byteorder::{ReadBytesExt, ByteOrder};
 use serde_crate as serde;
 use serde_crate::de::value::ValueDeserializer;
 use serde_crate::de::Error as DeError;
 use ::SizeLimit;
 use super::{Result, Error, ErrorKind};
 
 /// A Deserializer that reads bytes from a buffer.
 ///
 /// This struct should rarely be used.
 /// In most cases, prefer the `decode_from` function.
 ///
 /// ```rust,ignore
 /// let d = Deserializer::new(&mut some_reader, SizeLimit::new());
 /// serde::Deserialize::deserialize(&mut deserializer);
 /// let bytes_read = d.bytes_read();
 /// ```
-pub struct Deserializer<R> {
+pub struct Deserializer<R, E: ByteOrder> {
     reader: R,
     size_limit: SizeLimit,
-    read: u64
+    read: u64,
+    _phantom: PhantomData<E>,
 }
 
-impl<R: Read> Deserializer<R> {
-    pub fn new(r: R, size_limit: SizeLimit) -> Deserializer<R> {
+impl<R: Read, E: ByteOrder> Deserializer<R, E> {
+    pub fn new(r: R, size_limit: SizeLimit) -> Deserializer<R, E> {
         Deserializer {
             reader: r,
             size_limit: size_limit,
-            read: 0
+            read: 0,
+            _phantom: PhantomData
         }
     }
 
     /// Returns the number of bytes read from the contained Reader.
     pub fn bytes_read(&self) -> u64 {
         self.read
     }
 
@@ -46,46 +49,50 @@ impl<R: Read> Deserializer<R> {
         }
     }
 
     fn read_type<T>(&mut self) -> Result<()> {
         use std::mem::size_of;
         self.read_bytes(size_of::<T>() as u64)
     }
 
-    fn read_string(&mut self) -> Result<String> {
+    fn read_vec(&mut self) -> Result<Vec<u8>> {
         let len = try!(serde::Deserialize::deserialize(&mut *self));
         try!(self.read_bytes(len));
 
-        let mut buffer = Vec::new();
-        try!(self.reader.by_ref().take(len as u64).read_to_end(&mut buffer));
+        let len = len as usize;
+        let mut bytes = Vec::with_capacity(len);
+        unsafe { bytes.set_len(len); }
+        try!(self.reader.read_exact(&mut bytes));
+        Ok(bytes)
+    }
 
-        String::from_utf8(buffer).map_err(|err|
+    fn read_string(&mut self) -> Result<String> {
+        String::from_utf8(try!(self.read_vec())).map_err(|err|
             ErrorKind::InvalidEncoding{
                 desc: "error while decoding utf8 string",
                 detail: Some(format!("Deserialize error: {}", err))
             }.into())
     }
 }
 
 macro_rules! impl_nums {
     ($ty:ty, $dser_method:ident, $visitor_method:ident, $reader_method:ident) => {
         #[inline]
         fn $dser_method<V>(self, visitor: V) -> Result<V::Value>
             where V: serde::de::Visitor,
         {
             try!(self.read_type::<$ty>());
-            let value = try!(self.reader.$reader_method::<BigEndian>());
+            let value = try!(self.reader.$reader_method::<E>());
             visitor.$visitor_method(value)
         }
     }
 }
 
-
-impl<'a, R: Read> serde::Deserializer for &'a mut Deserializer<R> {
+impl<'a, R: Read, E: ByteOrder> serde::Deserializer for &'a mut Deserializer<R, E> {
     type Error = Error;
 
     #[inline]
     fn deserialize<V>(self, _visitor: V) -> Result<V::Value>
         where V: serde::de::Visitor,
     {
         let message = "bincode does not support Deserializer::deserialize";
         Err(Error::custom(message))
@@ -187,32 +194,32 @@ impl<'a, R: Read> serde::Deserializer fo
         where V: serde::de::Visitor,
     {
         visitor.visit_string(try!(self.read_string()))
     }
 
     fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
         where V: serde::de::Visitor,
     {
-        self.deserialize_seq(visitor)
+        visitor.visit_bytes(&try!(self.read_vec()))
     }
 
     fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
         where V: serde::de::Visitor,
     {
-        self.deserialize_seq(visitor)
+        visitor.visit_byte_buf(try!(self.read_vec()))
     }
 
     fn deserialize_enum<V>(self,
                      _enum: &'static str,
                      _variants: &'static [&'static str],
                      visitor: V) -> Result<V::Value>
         where V: serde::de::Visitor,
     {
-        impl<'a, R: Read + 'a> serde::de::EnumVisitor for &'a mut Deserializer<R> {
+        impl<'a, R: Read + 'a, E: ByteOrder> serde::de::EnumVisitor for &'a mut Deserializer<R, E> {
             type Error = Error;
             type Variant = Self;
 
             fn visit_variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
                 where V: serde::de::DeserializeSeed,
             {
                 let idx: u32 = try!(serde::de::Deserialize::deserialize(&mut *self));
                 let val: Result<_> = seed.deserialize(idx.into_deserializer());
@@ -223,19 +230,19 @@ impl<'a, R: Read> serde::Deserializer fo
         visitor.visit_enum(self)
     }
     
     fn deserialize_tuple<V>(self,
                       _len: usize,
                       visitor: V) -> Result<V::Value>
         where V: serde::de::Visitor,
     {
-        struct TupleVisitor<'a, R: Read + 'a>(&'a mut Deserializer<R>);
+        struct TupleVisitor<'a, R: Read + 'a, E: ByteOrder + 'a>(&'a mut Deserializer<R, E>);
 
-        impl<'a, 'b: 'a, R: Read + 'b> serde::de::SeqVisitor for TupleVisitor<'a, R> {
+        impl<'a, 'b: 'a, R: Read + 'b, E: ByteOrder> serde::de::SeqVisitor for TupleVisitor<'a, R, E> {
             type Error = Error;
 
             fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
                 where T: serde::de::DeserializeSeed,
             {
                 let value = try!(serde::de::DeserializeSeed::deserialize(seed, &mut *self.0));
                 Ok(Some(value))
             }
@@ -244,22 +251,22 @@ impl<'a, R: Read> serde::Deserializer fo
         visitor.visit_seq(TupleVisitor(self))
     }
 
     fn deserialize_seq_fixed_size<V>(self,
                             len: usize,
                             visitor: V) -> Result<V::Value>
         where V: serde::de::Visitor,
     {
-        struct SeqVisitor<'a, R: Read + 'a> {
-            deserializer: &'a mut Deserializer<R>,
+        struct SeqVisitor<'a, R: Read + 'a, E: ByteOrder + 'a> {
+            deserializer: &'a mut Deserializer<R, E>,
             len: usize,
         }
 
-        impl<'a, 'b: 'a, R: Read + 'b> serde::de::SeqVisitor for SeqVisitor<'a, R> {
+        impl<'a, 'b: 'a, R: Read + 'b, E: ByteOrder> serde::de::SeqVisitor for SeqVisitor<'a, R, E> {
             type Error = Error;
 
             fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
                 where T: serde::de::DeserializeSeed,
             {
                 if self.len > 0 {
                     self.len -= 1;
                     let value = try!(serde::de::DeserializeSeed::deserialize(seed, &mut *self.deserializer));
@@ -293,22 +300,22 @@ impl<'a, R: Read> serde::Deserializer fo
         let len = try!(serde::Deserialize::deserialize(&mut *self));
 
         self.deserialize_seq_fixed_size(len, visitor)
     }
 
     fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
         where V: serde::de::Visitor,
     {
-        struct MapVisitor<'a, R: Read + 'a> {
-            deserializer: &'a mut Deserializer<R>,
+        struct MapVisitor<'a, R: Read + 'a, E: ByteOrder + 'a> {
+            deserializer: &'a mut Deserializer<R, E>,
             len: usize,
         }
 
-        impl<'a, 'b: 'a, R: Read + 'b> serde::de::MapVisitor for MapVisitor<'a, R> {
+        impl<'a, 'b: 'a, R: Read + 'b, E: ByteOrder> serde::de::MapVisitor for MapVisitor<'a, R, E> {
             type Error = Error;
 
             fn visit_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
                 where K: serde::de::DeserializeSeed,
             {
                 if self.len > 0 {
                     self.len -= 1;
                     let key = try!(serde::de::DeserializeSeed::deserialize(seed, &mut *self.deserializer));
@@ -377,17 +384,17 @@ impl<'a, R: Read> serde::Deserializer fo
                                   _visitor: V) -> Result<V::Value>
         where V: serde::de::Visitor,
     {
         let message = "bincode does not support Deserializer::deserialize_ignored_any";
         Err(Error::custom(message))
     }
 }
 
-impl<'a, R: Read> serde::de::VariantVisitor for &'a mut Deserializer<R> {
+impl<'a, R: Read, E: ByteOrder> serde::de::VariantVisitor for &'a mut Deserializer<R, E> {
     type Error = Error;
 
     fn visit_unit(self) -> Result<()> {
         Ok(())
     }
 
     fn visit_newtype_seed<T>(self, seed: T) -> Result<T::Value>
         where T: serde::de::DeserializeSeed,
--- a/third_party/rust/bincode/src/serde/writer.rs
+++ b/third_party/rust/bincode/src/serde/writer.rs
@@ -1,98 +1,101 @@
 use std::io::Write;
 use std::u32;
+use std::marker::PhantomData;
 
 use serde_crate as serde;
 
-use byteorder::{BigEndian, WriteBytesExt};
+use byteorder::{WriteBytesExt, ByteOrder};
 
 use super::{Result, Error, ErrorKind};
 
 /// An Serializer that encodes values directly into a Writer.
 ///
 /// This struct should not be used often.
 /// For most cases, prefer the `encode_into` function.
-pub struct Serializer<W> {
+pub struct Serializer<W, E: ByteOrder> {
     writer: W,
+    _phantom: PhantomData<E>,
 }
 
-impl<W: Write> Serializer<W> {
-    pub fn new(w: W) -> Serializer<W> {
+impl<W: Write, E: ByteOrder> Serializer<W, E> {
+    pub fn new(w: W) -> Serializer<W, E> {
         Serializer {
             writer: w,
+            _phantom: PhantomData,
         }
     }
 
     fn add_enum_tag(&mut self, tag: usize) -> Result<()> {
         if tag > u32::MAX as usize {
             panic!("Variant tag doesn't fit in a u32")
         }
 
         serde::Serializer::serialize_u32(self, tag as u32)
     }
 }
 
-impl<'a, W: Write> serde::Serializer for &'a mut Serializer<W> {
+impl<'a, W: Write, E: ByteOrder> serde::Serializer for &'a mut Serializer<W, E> {
     type Ok = ();
     type Error = Error;
-    type SerializeSeq = Compound<'a, W>;
-    type SerializeTuple = Compound<'a, W>;
-    type SerializeTupleStruct = Compound<'a, W>;
-    type SerializeTupleVariant = Compound<'a, W>;
-    type SerializeMap = Compound<'a, W>;
-    type SerializeStruct = Compound<'a, W>;
-    type SerializeStructVariant = Compound<'a, W>;
+    type SerializeSeq = Compound<'a, W, E>;
+    type SerializeTuple = Compound<'a, W, E>;
+    type SerializeTupleStruct = Compound<'a, W, E>;
+    type SerializeTupleVariant = Compound<'a, W, E>;
+    type SerializeMap = Compound<'a, W, E>;
+    type SerializeStruct = Compound<'a, W, E>;
+    type SerializeStructVariant = Compound<'a, W, E>;
 
     fn serialize_unit(self) -> Result<()> { Ok(()) }
 
     fn serialize_unit_struct(self, _: &'static str) -> Result<()> { Ok(()) }
 
     fn serialize_bool(self, v: bool) -> Result<()> {
         self.writer.write_u8(if v {1} else {0}).map_err(Into::into)
     }
 
     fn serialize_u8(self, v: u8) -> Result<()> {
         self.writer.write_u8(v).map_err(Into::into)
     }
 
     fn serialize_u16(self, v: u16) -> Result<()> {
-        self.writer.write_u16::<BigEndian>(v).map_err(Into::into)
+        self.writer.write_u16::<E>(v).map_err(Into::into)
     }
 
     fn serialize_u32(self, v: u32) -> Result<()> {
-        self.writer.write_u32::<BigEndian>(v).map_err(Into::into)
+        self.writer.write_u32::<E>(v).map_err(Into::into)
     }
 
     fn serialize_u64(self, v: u64) -> Result<()> {
-        self.writer.write_u64::<BigEndian>(v).map_err(Into::into)
+        self.writer.write_u64::<E>(v).map_err(Into::into)
     }
 
     fn serialize_i8(self, v: i8) -> Result<()> {
         self.writer.write_i8(v).map_err(Into::into)
     }
 
     fn serialize_i16(self, v: i16) -> Result<()> {
-        self.writer.write_i16::<BigEndian>(v).map_err(Into::into)
+        self.writer.write_i16::<E>(v).map_err(Into::into)
     }
 
     fn serialize_i32(self, v: i32) -> Result<()> {
-        self.writer.write_i32::<BigEndian>(v).map_err(Into::into)
+        self.writer.write_i32::<E>(v).map_err(Into::into)
     }
 
     fn serialize_i64(self, v: i64) -> Result<()> {
-        self.writer.write_i64::<BigEndian>(v).map_err(Into::into)
+        self.writer.write_i64::<E>(v).map_err(Into::into)
     }
 
     fn serialize_f32(self, v: f32) -> Result<()> {
-        self.writer.write_f32::<BigEndian>(v).map_err(Into::into)
+        self.writer.write_f32::<E>(v).map_err(Into::into)
     }
 
     fn serialize_f64(self, v: f64) -> Result<()> {
-        self.writer.write_f64::<BigEndian>(v).map_err(Into::into)
+        self.writer.write_f64::<E>(v).map_err(Into::into)
     }
 
     fn serialize_str(self, v: &str) -> Result<()> {
         try!(self.serialize_u64(v.len() as u64));
         self.writer.write_all(v.as_bytes()).map_err(Into::into)
     }
 
     fn serialize_char(self, c: char) -> Result<()> {
@@ -379,22 +382,22 @@ impl<'a> serde::Serializer for &'a mut S
                                value: &V) -> Result<()>
     {
         try!(self.add_enum_tag(variant_index));
         value.serialize(self)
     }
 }
 
 #[doc(hidden)]
-pub struct Compound<'a, W: 'a> {
-    ser: &'a mut Serializer<W>,
+pub struct Compound<'a, W: 'a, E: ByteOrder + 'a> {
+    ser: &'a mut Serializer<W, E>,
 }
 
-impl<'a, W> serde::ser::SerializeSeq for Compound<'a, W> 
-    where W: Write
+impl<'a, W, E> serde::ser::SerializeSeq for Compound<'a, W, E>
+    where W: Write, E: ByteOrder
 {
     type Ok = ();
     type Error = Error;
 
     #[inline]
     fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()> 
     where T: serde::ser::Serialize 
     {
@@ -402,18 +405,18 @@ impl<'a, W> serde::ser::SerializeSeq for
     }
 
     #[inline]
     fn end(self) -> Result<()> {
         Ok(())
     }
 }
 
-impl<'a, W> serde::ser::SerializeTuple for Compound<'a, W>
-    where W: Write
+impl<'a, W, E> serde::ser::SerializeTuple for Compound<'a, W, E>
+    where W: Write, E: ByteOrder
 {
     type Ok = ();
     type Error = Error;
 
     #[inline]
     fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()> 
     where T: serde::ser::Serialize 
     {
@@ -421,18 +424,18 @@ impl<'a, W> serde::ser::SerializeTuple f
     }
 
     #[inline]
     fn end(self) -> Result<()> {
         Ok(())
     }
 }
 
-impl<'a, W> serde::ser::SerializeTupleStruct for Compound<'a, W> 
-    where W: Write
+impl<'a, W, E> serde::ser::SerializeTupleStruct for Compound<'a, W, E>
+    where W: Write, E: ByteOrder
 {
     type Ok = ();
     type Error = Error;
 
     #[inline]
     fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()> 
     where T: serde::ser::Serialize 
     {
@@ -440,18 +443,18 @@ impl<'a, W> serde::ser::SerializeTupleSt
     }
 
     #[inline]
     fn end(self) -> Result<()> {
         Ok(())
     }
 }
 
-impl<'a, W> serde::ser::SerializeTupleVariant for Compound<'a, W> 
-    where W: Write
+impl<'a, W, E> serde::ser::SerializeTupleVariant for Compound<'a, W, E>
+    where W: Write, E: ByteOrder
 {
     type Ok = ();
     type Error = Error;
 
     #[inline]
     fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()> 
     where T: serde::ser::Serialize 
     {
@@ -459,18 +462,18 @@ impl<'a, W> serde::ser::SerializeTupleVa
     }
 
     #[inline]
     fn end(self) -> Result<()> {
         Ok(())
     }
 }
 
-impl<'a, W> serde::ser::SerializeMap for Compound<'a, W> 
-    where W: Write
+impl<'a, W, E> serde::ser::SerializeMap for Compound<'a, W, E>
+    where W: Write, E: ByteOrder
 {
     type Ok = ();
     type Error = Error;
 
     #[inline]
     fn serialize_key<K: ?Sized>(&mut self, value: &K) -> Result<()> 
     where K: serde::ser::Serialize 
     {
@@ -485,18 +488,18 @@ impl<'a, W> serde::ser::SerializeMap for
     }
 
     #[inline]
     fn end(self) -> Result<()> {
         Ok(())
     }
 }
 
-impl<'a, W> serde::ser::SerializeStruct for Compound<'a, W> 
-    where W: Write
+impl<'a, W, E> serde::ser::SerializeStruct for Compound<'a, W, E>
+    where W: Write, E: ByteOrder
 {
     type Ok = ();
     type Error = Error;
 
     #[inline]
     fn serialize_field<T: ?Sized>(&mut self, _key: &'static str, value: &T) -> Result<()> 
     where T: serde::ser::Serialize 
     {
@@ -504,18 +507,18 @@ impl<'a, W> serde::ser::SerializeStruct 
     }
 
     #[inline]
     fn end(self) -> Result<()> {
         Ok(())
     }
 }
 
-impl<'a, W> serde::ser::SerializeStructVariant for Compound<'a, W> 
-    where W: Write
+impl<'a, W, E> serde::ser::SerializeStructVariant for Compound<'a, W, E>
+    where W: Write, E: ByteOrder
 {
     type Ok = ();
     type Error = Error;
 
     #[inline]
     fn serialize_field<T: ?Sized>(&mut self, _key: &'static str, value: &T) -> Result<()> 
     where T: serde::ser::Serialize 
     {
--- a/third_party/rust/bincode/tests/test.rs
+++ b/third_party/rust/bincode/tests/test.rs
@@ -1,66 +1,66 @@
 #[macro_use]
 extern crate serde_derive;
 
 extern crate bincode;
 extern crate serde;
+extern crate byteorder;
 
 use std::fmt::Debug;
 use std::collections::HashMap;
 use std::ops::Deref;
 
 use bincode::refbox::{RefBox, StrBox, SliceBox};
 
-use bincode::SizeLimit::{self, Infinite, Bounded};
-use bincode::{serialize, serialized_size, deserialize, deserialize_from, ErrorKind, Result};
-
-fn proxy_encode<V>(element: &V, size_limit: SizeLimit) -> Vec<u8>
-    where V: serde::Serialize + serde::Deserialize + PartialEq + Debug + 'static
-{
-    let v2 = serialize(element, size_limit).unwrap();
-    v2
-}
+use bincode::SizeLimit::{Infinite, Bounded};
+use bincode::{serialized_size, ErrorKind, Result};
+use bincode::endian_choice::{serialize, deserialize};
 
-fn proxy_decode<V>(slice: &[u8]) -> V
-    where V: serde::Serialize + serde::Deserialize + PartialEq + Debug + 'static
-{
-    let e2 = deserialize(slice).unwrap();
-    e2
-}
-
-fn proxy_encoded_size<V>(element: &V) -> u64
-    where V: serde::Serialize + PartialEq + Debug + 'static
-{
-    let serde_size = serialized_size(element);
-    serde_size
-}
+use bincode::serialize as serialize_little;
+use bincode::deserialize as deserialize_little;
+use bincode::deserialize_from as deserialize_from_little;
 
 fn the_same<V>(element: V)
     where V: serde::Serialize+serde::Deserialize+PartialEq+Debug+'static
 {
     // Make sure that the bahavior isize correct when wrapping with a RefBox.
     fn ref_box_correct<V>(v: &V) -> bool
         where V: serde::Serialize + serde::Deserialize + PartialEq + Debug + 'static
     {
         let rf = RefBox::new(v);
-        let encoded = serialize(&rf, Infinite).unwrap();
-        let decoded: RefBox<'static, V> = deserialize(&encoded[..]).unwrap();
+        let encoded = serialize_little(&rf, Infinite).unwrap();
+        let decoded: RefBox<'static, V> = deserialize_little(&encoded[..]).unwrap();
 
         decoded.take().deref() == v
     }
 
-    let size = proxy_encoded_size(&element);
+    let size = serialized_size(&element);
+
+    {
+        let encoded = serialize_little(&element, Infinite);
+        let encoded = encoded.unwrap();
+        let decoded = deserialize_little(&encoded[..]);
+        let decoded = decoded.unwrap();
 
-    let encoded = proxy_encode(&element, Infinite);
-    let decoded = proxy_decode(&encoded[..]);
+        assert_eq!(element, decoded);
+        assert_eq!(size, encoded.len() as u64);
+        assert!(ref_box_correct(&element));
+    }
 
-    assert_eq!(element, decoded);
-    assert_eq!(size, encoded.len() as u64);
-    assert!(ref_box_correct(&element));
+    {
+        let encoded = serialize::<_, byteorder::BigEndian>(&element, Infinite);
+        let encoded = encoded.unwrap();
+        let decoded = deserialize::<_, byteorder::BigEndian>(&encoded[..]);
+        let decoded = decoded.unwrap();
+
+        assert_eq!(element, decoded);
+        assert_eq!(size, encoded.len() as u64);
+        assert!(ref_box_correct(&element));
+    }
 }
 
 #[test]
 fn test_numbers() {
     // unsigned positive
     the_same(5u8);
     the_same(5u16);
     the_same(5u32);
@@ -215,93 +215,93 @@ fn deserializing_errors() {
         match res.map_err(|e| *e) {
             Err(ErrorKind::InvalidEncoding{..}) => {},
             Err(ErrorKind::Custom(ref s)) if s.contains("invalid encoding") => {},
             Err(ErrorKind::Custom(ref s)) if s.contains("invalid value") => {},
             other => panic!("Expecting InvalidEncoding, got {:?}", other),
         }
     }
 
-    isize_invalid_deserialize(deserialize::<bool>(&vec![0xA][..]));
-    isize_invalid_deserialize(deserialize::<String>(&vec![0, 0, 0, 0, 0, 0, 0, 1, 0xFF][..]));
+    isize_invalid_deserialize(deserialize_little::<bool>(&vec![0xA][..]));
+    isize_invalid_deserialize(deserialize_little::<String>(&vec![1, 0, 0, 0, 0, 0, 0, 0, 0xFF][..]));
     // Out-of-bounds variant
     #[derive(Serialize, Deserialize, Debug)]
     enum Test {
         One,
         Two,
     };
-    isize_invalid_deserialize(deserialize::<Test>(&vec![0, 0, 0, 5][..]));
-    isize_invalid_deserialize(deserialize::<Option<u8>>(&vec![5, 0][..]));
+    isize_invalid_deserialize(deserialize_little::<Test>(&vec![0, 0, 0, 5][..]));
+    isize_invalid_deserialize(deserialize_little::<Option<u8>>(&vec![5, 0][..]));
 }
 
 #[test]
 fn too_big_deserialize() {
     let serialized = vec![0,0,0,3];
-    let deserialized: Result<u32> = deserialize_from(&mut &serialized[..], Bounded(3));
+    let deserialized: Result<u32> = deserialize_from_little::<_, _>(&mut &serialized[..], Bounded(3));
     assert!(deserialized.is_err());
 
     let serialized = vec![0,0,0,3];
-    let deserialized: Result<u32> = deserialize_from(&mut &serialized[..], Bounded(4));
+    let deserialized: Result<u32> = deserialize_from_little::<_, _>(&mut &serialized[..], Bounded(4));
     assert!(deserialized.is_ok());
 }
 
 #[test]
 fn char_serialization() {
     let chars = "Aa\0☺♪";
     for c in chars.chars() {
-        let encoded = serialize(&c, Bounded(4)).expect("serializing char failed");
-        let decoded: char = deserialize(&encoded).expect("deserializing failed");
+        let encoded = serialize_little(&c, Bounded(4)).expect("serializing char failed");
+        let decoded: char = deserialize_little(&encoded).expect("deserializing failed");
         assert_eq!(decoded, c);
     }
 }
 
 #[test]
 fn too_big_char_deserialize() {
     let serialized = vec![0x41];
-    let deserialized: Result<char> = deserialize_from(&mut &serialized[..], Bounded(1));
+    let deserialized: Result<char> = deserialize_from_little::<_, _>(&mut &serialized[..], Bounded(1));
     assert!(deserialized.is_ok());
     assert_eq!(deserialized.unwrap(), 'A');
 }
 
 #[test]
 fn too_big_serialize() {
-    assert!(serialize(&0u32, Bounded(3)).is_err());
-    assert!(serialize(&0u32, Bounded(4)).is_ok());
+    assert!(serialize_little(&0u32, Bounded(3)).is_err());
+    assert!(serialize_little(&0u32, Bounded(4)).is_ok());
 
-    assert!(serialize(&"abcde", Bounded(8 + 4)).is_err());
-    assert!(serialize(&"abcde", Bounded(8 + 5)).is_ok());
+    assert!(serialize_little(&"abcde", Bounded(8 + 4)).is_err());
+    assert!(serialize_little(&"abcde", Bounded(8 + 5)).is_ok());
 }
 
 #[test]
 fn test_proxy_encoded_size() {
-    assert!(proxy_encoded_size(&0u8) == 1);
-    assert!(proxy_encoded_size(&0u16) == 2);
-    assert!(proxy_encoded_size(&0u32) == 4);
-    assert!(proxy_encoded_size(&0u64) == 8);
+    assert!(serialized_size(&0u8) == 1);
+    assert!(serialized_size(&0u16) == 2);
+    assert!(serialized_size(&0u32) == 4);
+    assert!(serialized_size(&0u64) == 8);
 
     // length isize stored as u64
-    assert!(proxy_encoded_size(&"") == 8);
-    assert!(proxy_encoded_size(&"a") == 8 + 1);
+    assert!(serialized_size(&"") == 8);
+    assert!(serialized_size(&"a") == 8 + 1);
 
-    assert!(proxy_encoded_size(&vec![0u32, 1u32, 2u32]) == 8 + 3 * (4))
+    assert!(serialized_size(&vec![0u32, 1u32, 2u32]) == 8 + 3 * (4))
 
 }
 
 #[test]
 fn test_serialized_size() {
-    assert!(proxy_encoded_size(&0u8) == 1);
-    assert!(proxy_encoded_size(&0u16) == 2);
-    assert!(proxy_encoded_size(&0u32) == 4);
-    assert!(proxy_encoded_size(&0u64) == 8);
+    assert!(serialized_size(&0u8) == 1);
+    assert!(serialized_size(&0u16) == 2);
+    assert!(serialized_size(&0u32) == 4);
+    assert!(serialized_size(&0u64) == 8);
 
     // length isize stored as u64
-    assert!(proxy_encoded_size(&"") == 8);
-    assert!(proxy_encoded_size(&"a") == 8 + 1);
+    assert!(serialized_size(&"") == 8);
+    assert!(serialized_size(&"a") == 8 + 1);
 
-    assert!(proxy_encoded_size(&vec![0u32, 1u32, 2u32]) == 8 + 3 * (4))
+    assert!(serialized_size(&vec![0u32, 1u32, 2u32]) == 8 + 3 * (4))
 }
 
 #[test]
 fn encode_box() {
     the_same(Box::new(5));
 }
 
 #[test]
@@ -314,62 +314,62 @@ fn test_refbox_serialize() {
     #[derive(Serialize, Deserialize, Debug)]
     enum Message<'a> {
         M1(RefBox<'a, Vec<u32>>),
         M2(RefBox<'a, HashMap<u32, u32>>)
     }
 
     // Test 1
     {
-        let serialized = serialize(&Message::M1(RefBox::new(&large_object)), Infinite).unwrap();
-        let deserialized: Message<'static> = deserialize_from(&mut &serialized[..], Infinite).unwrap();
+        let serialized = serialize_little(&Message::M1(RefBox::new(&large_object)), Infinite).unwrap();
+        let deserialized: Message<'static> = deserialize_from_little(&mut &serialized[..], Infinite).unwrap();
 
         match deserialized {
             Message::M1(b) => assert!(b.take().deref() == &large_object),
             _ => assert!(false)
         }
     }
 
     // Test 2
     {
-        let serialized = serialize(&Message::M2(RefBox::new(&large_map)), Infinite).unwrap();
-        let deserialized: Message<'static> = deserialize_from(&mut &serialized[..], Infinite).unwrap();
+        let serialized = serialize_little(&Message::M2(RefBox::new(&large_map)), Infinite).unwrap();
+        let deserialized: Message<'static> = deserialize_from_little(&mut &serialized[..], Infinite).unwrap();
 
         match deserialized {
             Message::M2(b) => assert!(b.take().deref() == &large_map),
             _ => assert!(false)
         }
     }
 }
 
 #[test]
 fn test_strbox_serialize() {
     let strx: &'static str = "hello world";
-    let serialized = serialize(&StrBox::new(strx), Infinite).unwrap();
-    let deserialized: StrBox<'static> = deserialize_from(&mut &serialized[..], Infinite).unwrap();
+    let serialized = serialize_little(&StrBox::new(strx), Infinite).unwrap();
+    let deserialized: StrBox<'static> = deserialize_from_little(&mut &serialized[..], Infinite).unwrap();
     let stringx: String = deserialized.take();
     assert!(strx == &stringx[..]);
 }
 
 #[test]
 fn test_slicebox_serialize() {
     let slice = [1u32, 2, 3 ,4, 5];
-    let serialized = serialize(&SliceBox::new(&slice), Infinite).unwrap();
-    let deserialized: SliceBox<'static, u32> = deserialize_from(&mut &serialized[..], Infinite).unwrap();
+    let serialized = serialize_little(&SliceBox::new(&slice), Infinite).unwrap();
+    let deserialized: SliceBox<'static, u32> = deserialize_from_little(&mut &serialized[..], Infinite).unwrap();
     {
         let sb: &[u32] = &deserialized;
         assert!(slice == sb);
     }
     let vecx: Vec<u32> = deserialized.take();
     assert!(slice == &vecx[..]);
 }
 
 #[test]
 fn test_multi_strings_serialize() {
-    assert!(serialize(&("foo", "bar", "baz"), Infinite).is_ok());
+    assert!(serialize_little(&("foo", "bar", "baz"), Infinite).is_ok());
 }
 
 /*
 #[test]
 fn test_oom_protection() {
     use std::io::Cursor;
     struct FakeVec {
         len: u64,
@@ -379,23 +379,31 @@ fn test_oom_protection() {
     let y : Result<Vec<u8>, _> = bincode::rustc_serialize::decode_from(&mut Cursor::new(&x[..]), bincode::SizeLimit::Bounded(10));
     assert!(y.is_err());
 }*/
 
 #[test]
 fn path_buf() {
     use std::path::{Path, PathBuf};
     let path = Path::new("foo").to_path_buf();
-    let serde_encoded = serialize(&path, Infinite).unwrap();
-    let decoded: PathBuf = deserialize(&serde_encoded).unwrap();
+    let serde_encoded = serialize_little(&path, Infinite).unwrap();
+    let decoded: PathBuf = deserialize_little(&serde_encoded).unwrap();
     assert!(path.to_str() == decoded.to_str());
 }
 
 #[test]
 fn bytes() {
     use serde::bytes::Bytes;
 
     let data = b"abc\0123";
-    let s = serialize(&data, Infinite).unwrap();
-    let s2 = serialize(&Bytes::new(data), Infinite).unwrap();
+    let s = serialize_little(&data, Infinite).unwrap();
+    let s2 = serialize_little(&Bytes::new(data), Infinite).unwrap();
     assert_eq!(s[..], s2[8..]);
 }
 
+
+#[test]
+fn endian_difference() {
+    let x = 10u64;
+    let little = serialize_little(&x, Infinite).unwrap();
+    let big = serialize::<_, byteorder::BigEndian>(&x, Infinite).unwrap();
+    assert_ne!(little, big);
+}
--- a/third_party/rust/clap/.cargo-checksum.json
+++ b/third_party/rust/clap/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".clog.toml":"f691701bd51b5f311931d0d8f05fa3d78c00dda8d60f3313e21011309c736ff1",".github/CONTRIBUTING.md":"e0db4b38cfc60de0a8d423251fc1f00b794b9754bc1e910fd731bc88edbec068",".github/ISSUE_TEMPLATE.md":"681afbd64b3603e3e82789ceb6841d851eaa7333caec5769173462bab1b5d82b",".gitignore":"57b1cc6deeaf68d35909201e4bb863c7dbec899ceaa17edde7b9fe64ece8c3e9",".travis.yml":"2975b3159624d4ecc4dd29577f378e9d4fa27f1991bfd5042ac3c267fb2cdd38","CHANGELOG.md":"2063be281de14341e47526fb8726000d67b86e2cec63c6d3d0bcb60e0cf8f055","CONTRIBUTORS.md":"62c5e9edb670a0b9315970b1a635a368928cf74b1240bbf1a0dab68d8ca6d598","Cargo.toml":"a38907da1b6af6f34ae4aa196c1d95f56fc16660e28c79cc3ef3604a0261a555","LICENSE-MIT":"6725d1437fc6c77301f2ff0e7d52914cf4f9509213e1078dc77d9356dbe6eac5","README.md":"0385f93d92d48ff5e9ef0522113030b6b8979cc04ff9e98fad827829d6313792","appveyor.yml":"303c64c2cc84c24b3c9ac0b4cd66b98d6bb25dec7d030ed53e5cb6ab3f13ebd1","clap-test.rs":"1021e44ea7981166f988268e619410f8329db8874018f4bc880a4f74b0b8ae76","index.html":"36f9ce4465266f3af9a259444b01c4239200473cabfc848f789f75b322a3ea8f","justfile":"82c20f705bc096a391f4b7232dbf712a0d3f00f9a2229aaa674f035ad0d9650e","rustfmt.toml":"8fd2d63119df515fd5f44e530c709b19d66b09fbc2e22a640bf4b64c57e7d6b3","src/app/help.rs":"f48bfb67331df1ff72da5d404b68a6e2049203ba1a091f701dc212ab0450461b","src/app/macros.rs":"8a8e8fe466da78588affeeadacf5c2a28d00299d387fdb8081ab9314a1d0b4eb","src/app/meta.rs":"81414fb8bfb32fa809eb470f3f3deee6610bfe54205240095371708c3d037933","src/app/mod.rs":"090ed3f2e9e070a06ca910236cecd2d24ab9fc1432bbf46b7cc441469b2dcc8c","src/app/parser.rs":"6d0919580b64dc892d1e4e6c78c7d774972761e092574eac1b7a7a43988733f7","src/app/settings.rs":"52d5482b96e9832af1f06d15f5055cfe4cfb1edca0e2bf8f7c3ac7f72e982ec9","src/args/any_arg.rs":"6b1b480083ae2d31805a7d89ffaac8f452378fa19f0ef13bfc5a198707540f82","src/args/arg.rs":"77f8fd843928b7b963d332657ccaee21258fa9831565d225973579718d010ccc","src/args/arg_builder/base.rs":"70a9882495e2bcec53f5c9a370e5e2ae5d3b06559ef7ebda24c8a842c089df67","src/args/arg_builder/flag.rs":"2c20a751707fa0c5cc24afca3d3f3528eb68d9805ff69830bde66699bbcdd889","src/args/arg_builder/mod.rs":"7a32c8fd85b48f7b60e5f2c13dc70fa9100aa65cd933ba419300d28d682bf722","src/args/arg_builder/option.rs":"1a9473b10e94d09a7345c8c1c845a0380cd5234433ef01e0e62dabc28fa57470","src/args/arg_builder/positional.rs":"a60431c4619333ba0ed6e01cabd2d91f412c51f829c05656cf0f1bbf9b03c7da","src/args/arg_builder/switched.rs":"43b4da391b51a475a8a9bd3a396f507c2ae21bbd5a5a923bb8b1fd6d7829f228","src/args/arg_builder/valued.rs":"bdaa6943254e79c332d45af2e623baf2a99f6418a0d47240d7f666940af33e97","src/args/arg_matcher.rs":"16c4c68c253fa5660586dfa09bfa0f5dbae9cb8cb6de5e5f791ba41839ccc2e5","src/args/arg_matches.rs":"5b948efdc025fc9c39c93a84fbda1c8916c400e3557ae09a422aa29091072414","src/args/group.rs":"93797d3b8ca690d9bd23730ede9c490d49678220c70f8a90bf68914ea9eb8e22","src/args/macros.rs":"0dd7ae4c6e26ed78044c3ef90e21259816e544f724dcb09e6a0d92d4fcbc4b1a","src/args/matched_arg.rs":"ce480cff445964707663886ebbdc7c7bc168ac079ea1dafe928305d387ca07f7","src/args/mod.rs":"e15fc06bd63c3ef09c13c38c801b70c3318350456a3171d0110816eb92e0a0e2","src/args/settings.rs":"f1cdaa80def5760c72efdfddb3c509fa6ebbd83defb746dfc8fbfd57bcd080e3","src/args/subcommand.rs":"e1ad9638c33785f1301675de1795b0a4f4b079452aa11f7526d263c2a1179432","src/completions/bash.rs":"d323396378a5770ea09062fe22a6cade8c5ace74f26678dc992d86268a91c270","src/completions/fish.rs":"737084dc358bc3477477ecb18c0ec00e3ddf1bb8c238374ef017aed9f95d0bed","src/completions/macros.rs":"ebad5037e6e63401b1a54498e09d3bd93d1a3a06f045c2990902d47eb9a73774","src/completions/mod.rs":"5d4a734df6a21e6c1e0831a2f7be50a45d2e7bdaf7475589ea78b978643229cd","src/completions/powershell.rs":"e442d7ee240fb8430ed3ffd8abf7abb69f1523452f8dbe960b4b05047b3523c9","src/completions/shell.rs":"c7995ca229fd0d8671761da0aca0513c4f740165f02d06cd97aa0ae881c22cd4","src/completions/zsh.rs":"8ac4576e1cb3b1403dbb35ce146159aa8b29864e1d8201776200d999052b422d","src/errors.rs":"4da870f2002486b107b6b4b3dc8a5c81525b8416cef9aa1efb6bef495e431c09","src/fmt.rs":"284d4fc8463779241341b779b0a69d24368a21d4798862268036855fd331e18a","src/lib.rs":"78ae21e3fcfa8ffd1b9b2e5a846bd083f03b30b23a9bebc7d24249e3b0599d79","src/macros.rs":"ed6407c433813e8f9be366af42433967db3d43aeebab34530f0e3b36aa5ca33c","src/osstringext.rs":"680869e35af8f4f4b7f57bb7121b6274a9781cc6f7de6ba4c95683d1a71bd848","src/strext.rs":"d4418d396069e9c05804f92c042ba7192a4244e46059e2edc98670b45cd2daee","src/suggestions.rs":"ca35c332646fe9d3f93c6263830eaef77c87522f71794bfc986f90fc34229dec","src/usage_parser.rs":"ac23fdbff8a92eb02d0716685513f765dafe04a3d4ec0f4daf7cf40ed37149f7"},"package":"f89819450aa94325998aa83ce7ea142db11ad24c725d6bc48459845e0d6d9f18"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".clog.toml":"f691701bd51b5f311931d0d8f05fa3d78c00dda8d60f3313e21011309c736ff1",".github/CONTRIBUTING.md":"f7eff737f3aa25294802fefb233e3758a64b248781dbbf3262532d693f340a87",".github/ISSUE_TEMPLATE.md":"681afbd64b3603e3e82789ceb6841d851eaa7333caec5769173462bab1b5d82b",".gitignore":"57b1cc6deeaf68d35909201e4bb863c7dbec899ceaa17edde7b9fe64ece8c3e9",".travis.yml":"2975b3159624d4ecc4dd29577f378e9d4fa27f1991bfd5042ac3c267fb2cdd38","CHANGELOG.md":"a1e86059e19fe5dd7c674d1165d31b77d1ec71d0db2aaa43c2442c3d65301ddd","CONTRIBUTORS.md":"62c5e9edb670a0b9315970b1a635a368928cf74b1240bbf1a0dab68d8ca6d598","Cargo.toml":"166690f9a21d1ea2f0492f10b8974d5ad5238eddea9b35cd3507059abb42ba66","LICENSE-MIT":"6725d1437fc6c77301f2ff0e7d52914cf4f9509213e1078dc77d9356dbe6eac5","README.md":"229557cb90d19e7632ec23820271b4aedad872544190b2477b9b43001c937e13","appveyor.yml":"303c64c2cc84c24b3c9ac0b4cd66b98d6bb25dec7d030ed53e5cb6ab3f13ebd1","clap-test.rs":"1021e44ea7981166f988268e619410f8329db8874018f4bc880a4f74b0b8ae76","index.html":"36f9ce4465266f3af9a259444b01c4239200473cabfc848f789f75b322a3ea8f","justfile":"82c20f705bc096a391f4b7232dbf712a0d3f00f9a2229aaa674f035ad0d9650e","rustfmt.toml":"8fd2d63119df515fd5f44e530c709b19d66b09fbc2e22a640bf4b64c57e7d6b3","src/app/help.rs":"f48bfb67331df1ff72da5d404b68a6e2049203ba1a091f701dc212ab0450461b","src/app/macros.rs":"8a8e8fe466da78588affeeadacf5c2a28d00299d387fdb8081ab9314a1d0b4eb","src/app/meta.rs":"81414fb8bfb32fa809eb470f3f3deee6610bfe54205240095371708c3d037933","src/app/mod.rs":"b36db7c4a404d04e58be00d3a720b87ed071f9234937cac5e77b938ac29d4f3f","src/app/parser.rs":"7aa95d1ddaf2941329668d5bd92c4a0b96ab00b8525207a0fa630e5d633d05e5","src/app/settings.rs":"52d5482b96e9832af1f06d15f5055cfe4cfb1edca0e2bf8f7c3ac7f72e982ec9","src/args/any_arg.rs":"6b1b480083ae2d31805a7d89ffaac8f452378fa19f0ef13bfc5a198707540f82","src/args/arg.rs":"77f8fd843928b7b963d332657ccaee21258fa9831565d225973579718d010ccc","src/args/arg_builder/base.rs":"70a9882495e2bcec53f5c9a370e5e2ae5d3b06559ef7ebda24c8a842c089df67","src/args/arg_builder/flag.rs":"2c20a751707fa0c5cc24afca3d3f3528eb68d9805ff69830bde66699bbcdd889","src/args/arg_builder/mod.rs":"7a32c8fd85b48f7b60e5f2c13dc70fa9100aa65cd933ba419300d28d682bf722","src/args/arg_builder/option.rs":"1a9473b10e94d09a7345c8c1c845a0380cd5234433ef01e0e62dabc28fa57470","src/args/arg_builder/positional.rs":"a60431c4619333ba0ed6e01cabd2d91f412c51f829c05656cf0f1bbf9b03c7da","src/args/arg_builder/switched.rs":"43b4da391b51a475a8a9bd3a396f507c2ae21bbd5a5a923bb8b1fd6d7829f228","src/args/arg_builder/valued.rs":"bdaa6943254e79c332d45af2e623baf2a99f6418a0d47240d7f666940af33e97","src/args/arg_matcher.rs":"16c4c68c253fa5660586dfa09bfa0f5dbae9cb8cb6de5e5f791ba41839ccc2e5","src/args/arg_matches.rs":"5b948efdc025fc9c39c93a84fbda1c8916c400e3557ae09a422aa29091072414","src/args/group.rs":"93797d3b8ca690d9bd23730ede9c490d49678220c70f8a90bf68914ea9eb8e22","src/args/macros.rs":"0dd7ae4c6e26ed78044c3ef90e21259816e544f724dcb09e6a0d92d4fcbc4b1a","src/args/matched_arg.rs":"ce480cff445964707663886ebbdc7c7bc168ac079ea1dafe928305d387ca07f7","src/args/mod.rs":"e15fc06bd63c3ef09c13c38c801b70c3318350456a3171d0110816eb92e0a0e2","src/args/settings.rs":"f1cdaa80def5760c72efdfddb3c509fa6ebbd83defb746dfc8fbfd57bcd080e3","src/args/subcommand.rs":"e1ad9638c33785f1301675de1795b0a4f4b079452aa11f7526d263c2a1179432","src/completions/bash.rs":"d323396378a5770ea09062fe22a6cade8c5ace74f26678dc992d86268a91c270","src/completions/fish.rs":"737084dc358bc3477477ecb18c0ec00e3ddf1bb8c238374ef017aed9f95d0bed","src/completions/macros.rs":"ebad5037e6e63401b1a54498e09d3bd93d1a3a06f045c2990902d47eb9a73774","src/completions/mod.rs":"5d4a734df6a21e6c1e0831a2f7be50a45d2e7bdaf7475589ea78b978643229cd","src/completions/powershell.rs":"e442d7ee240fb8430ed3ffd8abf7abb69f1523452f8dbe960b4b05047b3523c9","src/completions/shell.rs":"c7995ca229fd0d8671761da0aca0513c4f740165f02d06cd97aa0ae881c22cd4","src/completions/zsh.rs":"8ac4576e1cb3b1403dbb35ce146159aa8b29864e1d8201776200d999052b422d","src/errors.rs":"4da870f2002486b107b6b4b3dc8a5c81525b8416cef9aa1efb6bef495e431c09","src/fmt.rs":"284d4fc8463779241341b779b0a69d24368a21d4798862268036855fd331e18a","src/lib.rs":"78ae21e3fcfa8ffd1b9b2e5a846bd083f03b30b23a9bebc7d24249e3b0599d79","src/macros.rs":"50bf5bb36a4ca5511d3e1959aedb8d234bd84ff3d4eef0918fe9a269ef050a35","src/osstringext.rs":"680869e35af8f4f4b7f57bb7121b6274a9781cc6f7de6ba4c95683d1a71bd848","src/strext.rs":"d4418d396069e9c05804f92c042ba7192a4244e46059e2edc98670b45cd2daee","src/suggestions.rs":"ca35c332646fe9d3f93c6263830eaef77c87522f71794bfc986f90fc34229dec","src/usage_parser.rs":"ac23fdbff8a92eb02d0716685513f765dafe04a3d4ec0f4daf7cf40ed37149f7"},"package":"7db281b0520e97fbd15cd615dcd8f8bcad0c26f5f7d5effe705f090f39e9a758"}
\ No newline at end of file
--- a/third_party/rust/clap/.github/CONTRIBUTING.md
+++ b/third_party/rust/clap/.github/CONTRIBUTING.md
@@ -47,10 +47,10 @@ 4. Ensure your changes contain documenta
 ### Preparing the PR
 
 1. `git rebase` into concise commits and remove `--fixup`s or `wip` commits (`git rebase -i HEAD~NUM` where `NUM` is number of commits back to start the rebase)
 2. Push your changes back to your fork (`git push origin $your-branch`)
 3. Create a pull request against `master`! (You can also create the pull request first, and we'll merge when ready. This a good way to discuss proposed changes.)
 
 ### Other ways to contribute
 
-Another really great way to help is if you find an interesting, or helpful way in which to use `clap`. You can either add it to the [examples/](examples) directory, or file an issue and tell me. I'm all about giving credit where credit is due :)
+Another really great way to help is if you find an interesting, or helpful way in which to use `clap`. You can either add it to the [examples/](../examples) directory, or file an issue and tell me. I'm all about giving credit where credit is due :)
 
--- a/third_party/rust/clap/CHANGELOG.md
+++ b/third_party/rust/clap/CHANGELOG.md
@@ -1,8 +1,30 @@
+<a name="v2.20.5"></a>
+### v2.20.5 (2017-02-18)
+
+
+#### Bug Fixes
+
+* **clap_app!:**   fixes a critical bug of a missing fragment specifier when using `!property` style tags. ([5635c1f94](https://github.com/kbknapp/clap-rs/commit/5e9b9cf4dd80fa66a624374fd04e6545635c1f94))
+
+
+<a name="v2.20.4"></a>
+### v2.20.4 (2017-02-15)
+
+
+#### Bug Fixes
+
+* **Completions:**   fixes a bug that tried to propogate global args multiple times when generating multiple completion scripts ([5e9b9cf4](https://github.com/kbknapp/clap-rs/commit/5e9b9cf4dd80fa66a624374fd04e6545635c1f94), closes [#846](https://github.com/kbknapp/clap-rs/issues/846))
+
+#### Documentation
+
+*   Fix examples link in CONTRIBUTING.md ([60cf875d](https://github.com/kbknapp/clap-rs/commit/60cf875d67a252e19bb85054be57696fac2c57a1))
+
+
 <a name="v2.20.3"></a>
 ### v2.20.3 (2017-02-03)
 
 
 #### Documentation
 
 * **Macros:**  adds a warning about changing values in Cargo.toml not triggering a rebuild automatically ([112aea3e](https://github.com/kbknapp/clap-rs/commit/112aea3e42ae9e0c0a2d33ebad89496dbdd95e5d), closes [#838](https://github.com/kbknapp/clap-rs/issues/838))
 
--- a/third_party/rust/clap/Cargo.toml
+++ b/third_party/rust/clap/Cargo.toml
@@ -1,21 +1,21 @@
 [package]
 
 name = "clap"
-version = "2.20.3"
+version = "2.20.5"
 authors = ["Kevin K. <kbknapp@gmail.com>"]
 exclude = ["examples/*", "clap-test/*", "tests/*", "benches/*", "*.png", "clap-perf/*", "*.dot"]
 repository = "https://github.com/kbknapp/clap-rs.git"
 documentation = "https://docs.rs/clap/"
 homepage = "https://clap.rs/"
 readme = "README.md"
 license = "MIT"
 keywords = ["argument", "command", "arg", "parser", "parse"]
-categories = ["command-line interface"]
+categories = ["command-line-interface"]
 description = """
 A simple to use, efficient, and full featured  Command Line Argument Parser
 """
 
 [dependencies]
 bitflags              = "0.7.0"
 vec_map               = "0.6.0"
 unicode-width         = "0.1.4"
--- a/third_party/rust/clap/README.md
+++ b/third_party/rust/clap/README.md
@@ -40,29 +40,32 @@ Table of Contents
 * [License](#license)
 * [Recent Breaking Changes](#recent-breaking-changes)
   * [Deprecations](#deprecations)
 
 Created by [gh-md-toc](https://github.com/ekalinin/github-markdown-toc)
 
 ## What's New
 
-Here's the highlights for v2.20.2
+Here's the highlights for v2.20.5
+
+* Fixes a critical bug in the `clap_app!` macro of a missing fragment specifier when using `!property` style tags.
+
+
+Here's the highlights from v2.0.0 to v2.20.4
 
-* fixes a println->debugln typo 
-* **Completions**: fixes bash completions for commands that have an underscore in the name 
-* **Completions**: fixes a bug where ZSH completions would panic if the binary name had an underscore in it 
-* allow final word to be wrapped in wrap_help 
-* **Completions**: fixes a bug where global args weren't included in the generated completion scripts 
-* **Macros Documentation:**  adds a warning about changing values in Cargo.toml not triggering a rebuild automatically 
-
-Here's the highlights from v2.0.0 to v2.20.2
-
-* Fixes a critical bug where subcommand settings were being propogated too far 
-* Adds ArgGroup::multiple to the supported YAML fields for building ArgGroups from YAML 
+* Fixes a bug that tried to propogate global args multiple times when generating multiple completion scripts
+* Fix examples link in CONTRIBUTING.md
+* **Completions**: fixes bash completions for commands that have an underscore in the name
+* **Completions**: fixes a bug where ZSH completions would panic if the binary name had an underscore in it
+* allow final word to be wrapped in wrap_help
+* **Completions**: fixes a bug where global args weren't included in the generated completion scripts
+* **Macros Documentation:**  adds a warning about changing values in Cargo.toml not triggering a rebuild automatically
+* Fixes a critical bug where subcommand settings were being propogated too far
+* Adds ArgGroup::multiple to the supported YAML fields for building ArgGroups from YAML
 * Fixes a bug where the final word wasn't wrapped in help messages
 * Fixes finding required arguments in group arguments
 * **ArgsNegateSubcommands:**  disables args being allowed between subcommands
 * **DontCollapseArgsInUsage:** disables the collapsing of positional args into `[ARGS]` in the usage string
 * **DisableHelpSubcommand:**  disables building the `help` subcommand
 * **AllowMissingPositional:**  allows one to implement `$ prog [optional] <required>` style CLIs where the second postional argument is required, but the first is optional
 * **PropagateGlobalValuesDown:**  automatically propagats global arg's values down through *used* subcommands
 * **Arg::value_terminator:**  adds the ability to terminate multiple values with a given string or char
--- a/third_party/rust/clap/src/app/mod.rs
+++ b/third_party/rust/clap/src/app/mod.rs
@@ -395,37 +395,42 @@ impl<'a, 'b> App<'a, 'b> {
     ///
     /// Tags arg given inside curly brackets.
     ///
     /// Valid tags are:
     ///
     ///   * `{bin}`         - Binary name.
     ///   * `{version}`     - Version number.
     ///   * `{author}`      - Author information.
+    ///   * `{about}`       - General description (from [`App::about`])
     ///   * `{usage}`       - Automatically generated or given usage string.
     ///   * `{all-args}`    - Help for all arguments (options, flags, positionals arguments,
     ///                       and subcommands) including titles.
     ///   * `{unified}`     - Unified help for options and flags.
     ///   * `{flags}`       - Help for flags.
     ///   * `{options}`     - Help for options.
     ///   * `{positionals}` - Help for positionals arguments.
     ///   * `{subcommands}` - Help for subcommands.
-    ///   * `{after-help}`  - Help for flags.
+    ///   * `{after-help}`  - Help from [`App::after_help`]
+    ///   * `{before-help}`  - Help from [`App::before_help`]
     ///
     /// # Examples
     ///
     /// ```no_run
     /// # use clap::{App, Arg};
     /// App::new("myprog")
     ///     .version("1.0")
     ///     .template("{bin} ({version}) - {usage}")
     /// # ;
     /// ```
     /// **NOTE:**The template system is, on purpose, very simple. Therefore the tags have to writen
     /// in the lowercase and without spacing.
+    /// [`App::about`]: ./struct.App.html#method.about
+    /// [`App::after_help`]: ./struct.App.html#method.after_help
+    /// [`App::before_help`]: ./struct.App.html#method.before_help
     pub fn template<S: Into<&'b str>>(mut self, s: S) -> Self {
         self.p.meta.template = Some(s.into());
         self
     }
 
     /// Enables a single command, or [`SubCommand`], level settings.
     ///
     /// See [`AppSettings`] for a full list of possibilities and examples.
--- a/third_party/rust/clap/src/app/parser.rs
+++ b/third_party/rust/clap/src/app/parser.rs
@@ -32,16 +32,17 @@ use osstringext::OsStrExt2;
 use completions::Shell;
 use suggestions;
 
 #[allow(missing_debug_implementations)]
 #[doc(hidden)]
 pub struct Parser<'a, 'b>
     where 'a: 'b
 {
+    propogated: bool,
     required: Vec<&'a str>,
     r_ifs: Vec<(&'a str, &'b str, &'a str)>,
     pub short_list: Vec<char>,
     pub long_list: Vec<&'b str>,
     blacklist: Vec<&'b str>,
     // A list of possible flags
     pub flags: Vec<FlagBuilder<'a, 'b>>,
     // A list of possible options
@@ -64,16 +65,17 @@ pub struct Parser<'a, 'b>
     valid_neg_num: bool,
     // have we found a valid arg yet
     valid_arg: bool,
 }
 
 impl<'a, 'b> Default for Parser<'a, 'b> {
     fn default() -> Self {
         Parser {
+            propogated: false,
             flags: vec![],
             opts: vec![],
             positionals: VecMap::new(),
             subcommands: vec![],
             help_short: None,
             version_short: None,
             required: vec![],
             r_ifs: vec![],
@@ -109,21 +111,23 @@ impl<'a, 'b> Parser<'a, 'b>
 
     pub fn version_short(&mut self, s: &str) {
         self.version_short = s.trim_left_matches(|c| c == '-')
             .chars()
             .nth(0);
     }
 
     pub fn gen_completions_to<W: Write>(&mut self, for_shell: Shell, buf: &mut W) {
-
-        self.propogate_help_version();
-        self.build_bin_names();
-        self.propogate_globals();
-        self.propogate_settings();
+        if !self.propogated {
+            self.propogate_help_version();
+            self.build_bin_names();
+            self.propogate_globals();
+            self.propogate_settings();
+            self.propogated = true;
+        }
 
         ComplGen::new(self).generate(for_shell, buf)
     }
 
     pub fn gen_completions(&mut self, for_shell: Shell, od: OsString) {
         use std::error::Error;
 
         let out_dir = PathBuf::from(od);
@@ -2205,16 +2209,17 @@ impl<'a, 'b> Parser<'a, 'b>
     }
 }
 
 impl<'a, 'b> Clone for Parser<'a, 'b>
     where 'a: 'b
 {
     fn clone(&self) -> Self {
         Parser {
+            propogated: self.propogated,
             required: self.required.clone(),
             short_list: self.short_list.clone(),
             long_list: self.long_list.clone(),
             blacklist: self.blacklist.clone(),
             flags: self.flags.clone(),
             opts: self.opts.clone(),
             positionals: self.positionals.clone(),
             subcommands: self.subcommands.clone(),
--- a/third_party/rust/clap/src/macros.rs
+++ b/third_party/rust/clap/src/macros.rs
@@ -527,17 +527,76 @@ macro_rules! app_from_crate {
         $crate::App::new(crate_name!())
             .version(crate_version!())
             .author(crate_authors!($sep))
             .about(crate_description!())
     };
 }
 
 /// Build `App`, `Arg`s, `SubCommand`s and `Group`s with Usage-string like input
-/// but without the parsing.
+/// but without the associated parsing runtime cost.
+///
+/// `clap_app!` also supports several shorthand syntaxes.
+///
+/// # Examples
+///
+/// ```no_run
+/// # #[macro_use]
+/// # extern crate clap;
+/// # fn main() {
+/// let matches = clap_app!(myapp =>                                       
+///     (version: "1.0")                                                   
+///     (author: "Kevin K. <kbknapp@gmail.com>")                           
+///     (about: "Does awesome things")                                     
+///     (@arg CONFIG: -c --config +takes_value "Sets a custom config file")
+///     (@arg INPUT: +required "Sets the input file to use")               
+///     (@arg debug: -d ... "Sets the level of debugging information")     
+///     (@subcommand test =>                                               
+///         (about: "controls testing features")                           
+///         (version: "1.3")                                               
+///         (author: "Someone E. <someone_else@other.com>")                
+///         (@arg verbose: -v --verbose "Print test information verbosely")
+///     )                                                                  
+/// );
+/// # }                                                                          
+/// ```
+/// # Shorthand Syntax for Args
+/// 
+/// * A single hyphen followed by a character (such as `-c`) sets the [`Arg::short`]
+/// * A double hyphen followed by a character or word (such as `--config`) sets [`Arg::long`]
+/// * Three dots (`...`) sets [`Arg::multiple(true)`]
+/// * Angled brackets after either a short or long will set [`Arg::value_name`] and 
+/// `Arg::required(true)` such as `--config <FILE>` = `Arg::value_name("FILE")` and 
+/// `Arg::required(true)
+/// * Square brackets after either a short or long will set [`Arg::value_name`] and 
+/// `Arg::required(false)` such as `--config [FILE]` = `Arg::value_name("FILE")` and 
+/// `Arg::required(false)
+/// * There are short hand syntaxes for Arg methods that accept booleans 
+///   * A plus sign will set that method to `true` such as `+required` = `Arg::required(true)`
+///   * An exclamation will set that method to `false` such as `!required` = `Arg::required(false)`
+/// * A `#{min, max}` will set [`Arg::min_values(min)`] and [`Arg::max_values(max)`]
+/// * An asterisk (`*`) will set `Arg::required(true)`
+/// * Curly brackets around a `fn` will set [`Arg::validator`] as in `{fn}` = `Arg::validator(fn)`
+/// * An Arg method that accepts a string followed by square brackets will set that method such as 
+/// `conflicts_with[FOO]` will set `Arg::conflicts_with("FOO")` (note the lack of quotes around 
+/// `FOO` in the macro) 
+/// * An Arg method that takes a string and can be set multiple times (such as 
+/// [`Arg::conflicts_with`]) followed by square brackets and a list of values separated by spaces 
+/// will set that method such as `conflicts_with[FOO BAR BAZ]` will set 
+/// `Arg::conflicts_with("FOO")`, `Arg::conflicts_with("BAR")`, and `Arg::conflicts_with("BAZ")`
+/// (note the lack of quotes around the values in the macro) 
+///
+/// [`Arg::short`]: ./struct.Arg.html#method.short
+/// [`Arg::long`]: ./struct.Arg.html#method.long
+/// [`Arg::multiple(true)`]: ./struct.Arg.html#method.multiple
+/// [`Arg::value_name`]: ./struct.Arg.html#method.value_name
+/// [`Arg::min_values(min)`]: ./struct.Arg.html#method.min_values
+/// [`Arg::max_values(max)`]: ./struct.Arg.html#method.max_values
+/// [`Arg::validator`]: ./struct.Arg.html#method.validator
+/// [`Arg::conflicts_with`]: ./struct.Arg.html#method.conflicts_with
 #[macro_export]
 macro_rules! clap_app {
     (@app ($builder:expr)) => { $builder };
     (@app ($builder:expr) (@arg $name:ident: $($tail:tt)*) $($tt:tt)*) => {
         clap_app!{ @app
             ($builder.arg(
                 clap_app!{ @arg ($crate::Arg::with_name(stringify!($name))) (-) $($tail)* }))
             $($tt)*
@@ -620,20 +679,20 @@ macro_rules! clap_app {
 // Shorthand magic
     (@arg ($arg:expr) $modes:tt #{$n:expr, $m:expr} $($tail:tt)*) => {
         clap_app!{ @arg ($arg) $modes min_values($n) max_values($m) $($tail)* }
     };
     (@arg ($arg:expr) $modes:tt * $($tail:tt)*) => {
         clap_app!{ @arg ($arg) $modes +required $($tail)* }
     };
 // !foo -> .foo(false)
-    (@arg ($arg:expr) $modes:tt !$ident $($tail:tt)*) => {
+    (@arg ($arg:expr) $modes:tt !$ident:ident $($tail:tt)*) => {
         clap_app!{ @arg ($arg.$ident(false)) $modes $($tail)* }
     };
-// foo -> .foo(true)
+// +foo -> .foo(true)
     (@arg ($arg:expr) $modes:tt +$ident:ident $($tail:tt)*) => {
         clap_app!{ @arg ($arg.$ident(true)) $modes $($tail)* }
     };
 // Validator
     (@arg ($arg:expr) $modes:tt {$fn_:expr} $($tail:tt)*) => {
         clap_app!{ @arg ($arg.validator($fn_)) $modes $($tail)* }
     };
     (@as_expr $expr:expr) => { $expr };
--- a/third_party/rust/cssparser-macros/.cargo-checksum.json
+++ b/third_party/rust/cssparser-macros/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"ebe4110b0c97747210ec48a874d3b128531f59868f3ee1e169023854413cc948","lib.rs":"f7219b22e9cccc53a02f5a5e40f38d50640042727566913d4b2b579517667983"},"package":"a85e1452f40a50777c8424fa7fcaa7dd7074c7bc5419014fbffe7ea3d750dee8"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"e740a473ab5e2339d639a86f1996b1ecc72f25b25f23b2789c836bff1455cf5a","lib.rs":"2b54cf96da2049eb03e4b30a223124e7f5a9c067975d54ec0ecf92f0245777a1"},"package":"b8f0415de0bdbce823c0db204e00a62c8240fa2d3e04cd13ff7c6396e4446b95"}
\ No newline at end of file
--- a/third_party/rust/cssparser-macros/Cargo.toml
+++ b/third_party/rust/cssparser-macros/Cargo.toml
@@ -1,18 +1,18 @@
 [package]
 name = "cssparser-macros"
-version = "0.1.0"
+version = "0.2.0"
 authors = ["Simon Sapin <simon.sapin@exyr.org>"]
 description = "Procedural macros for cssparser"
 documentation = "https://docs.rs/cssparser-macros/"
 repository = "https://github.com/servo/rust-cssparser"
 license = "MPL-2.0"
 
 [lib]
 path = "lib.rs"
 proc-macro = true
 
 [dependencies]
+procedural-masquerade = {path = "../procedural-masquerade", version = "0.1"}
 phf_codegen = "0.7"
-quote = "0.3"
-syn = "0.11"
-
+quote = "0.3.14"
+syn = {version = "0.11.8", features = ["full"]}
--- a/third_party/rust/cssparser-macros/lib.rs
+++ b/third_party/rust/cssparser-macros/lib.rs
@@ -1,123 +1,105 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#[macro_use] extern crate procedural_masquerade;
 extern crate phf_codegen;
 extern crate proc_macro;
 #[macro_use] extern crate quote;
 extern crate syn;
 
 use std::ascii::AsciiExt;
 
-/// Find a `#[cssparser__assert_ascii_lowercase__data(string = "…", string = "…")]` attribute,
-/// and panic if any string contains ASCII uppercase letters.
-#[proc_macro_derive(cssparser__assert_ascii_lowercase,
-                    attributes(cssparser__assert_ascii_lowercase__data))]
-pub fn assert_ascii_lowercase(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
-    let input = syn::parse_macro_input(&input.to_string()).unwrap();
-    let data = list_attr(&input, "cssparser__assert_ascii_lowercase__data");
-
-    for sub_attr in data {
-        let string = sub_attr_value(sub_attr, "string");
-        assert_eq!(*string, string.to_ascii_lowercase(),
-                   "the expected strings must be given in ASCII lowercase");
+define_proc_macros! {
+    /// Input: the arms of a `match` expression.
+    ///
+    /// Output: a `MAX_LENGTH` constant with the length of the longest string pattern.
+    ///
+    /// Panic if the arms contain non-string patterns,
+    /// or string patterns that contains ASCII uppercase letters.
+    #[allow(non_snake_case)]
+    pub fn cssparser_internal__assert_ascii_lowercase__max_len(input: &str) -> String {
+        let expr = syn::parse_expr(&format!("match x {{ {} }}", input)).unwrap();
+        let arms = match expr {
+            syn::Expr { node: syn::ExprKind::Match(_, ref arms), .. } => arms,
+            _ => panic!("expected a match expression, got {:?}", expr)
+        };
+        max_len(arms.iter().flat_map(|arm| &arm.pats).filter_map(|pattern| {
+            let expr = match *pattern {
+                syn::Pat::Lit(ref expr) => expr,
+                syn::Pat::Wild |
+                syn::Pat::Ident(_, _, None) => return None,
+                syn::Pat::Ident(_, _, Some(ref sub_pattern)) => {
+                    match **sub_pattern {
+                        syn::Pat::Lit(ref expr) => expr,
+                        syn::Pat::Wild => return None,
+                        _ => panic!("expected string or wildcard pattern, got {:?}", pattern)
+                    }
+                }
+                _ => panic!("expected string or wildcard pattern, got {:?}", pattern)
+            };
+            match **expr {
+                syn::Expr { node: syn::ExprKind::Lit(syn::Lit::Str(ref string, _)), .. } => {
+                    assert_eq!(*string, string.to_ascii_lowercase(),
+                               "string patterns must be given in ASCII lowercase");
+                    Some(string.len())
+                }
+                _ => panic!("expected string pattern, got {:?}", expr)
+            }
+        }))
     }
 
-    "".parse().unwrap()
-}
+    /// Input: string literals with no separator
+    ///
+    /// Output: a `MAX_LENGTH` constant with the length of the longest string.
+    #[allow(non_snake_case)]
+    pub fn cssparser_internal__max_len(input: &str) -> String {
+        max_len(syn::parse_token_trees(input).unwrap().iter().map(|tt| string_literal(tt).len()))
+    }
 
-/// Find a `#[cssparser__max_len__data(string = "…", string = "…")]` attribute,
-/// panic if any string contains ASCII uppercase letters,
-/// emit a `MAX_LENGTH` constant with the length of the longest string.
-#[proc_macro_derive(cssparser__max_len,
-                    attributes(cssparser__max_len__data))]
-pub fn max_len(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
-    let input = syn::parse_macro_input(&input.to_string()).unwrap();
-    let data = list_attr(&input, "cssparser__max_len__data");
+    /// Input: parsed as token trees. The first TT is a type. (Can be wrapped in parens.)
+    /// following TTs are grouped in pairs, each pair being a key as a string literal
+    /// and the corresponding value as a const expression.
+    ///
+    /// Output: a rust-phf map, with keys ASCII-lowercased:
+    /// ```
+    /// static MAP: &'static ::cssparser::phf::Map<&'static str, $ValueType> = …;
+    /// ```
+    #[allow(non_snake_case)]
+    pub fn cssparser_internal__phf_map(input: &str) -> String {
+        let token_trees = syn::parse_token_trees(input).unwrap();
+        let value_type = &token_trees[0];
+        let pairs: Vec<_> = token_trees[1..].chunks(2).map(|chunk| {
+            let key = string_literal(&chunk[0]);
+            let value = &chunk[1];
+            (key.to_ascii_lowercase(), quote!(#value).to_string())
+        }).collect();
 
-    let lengths = data.iter().map(|sub_attr| sub_attr_value(sub_attr, "string").len());
-    let max_length = lengths.max().expect("expected at least one string");
+        let mut map = phf_codegen::Map::new();
+        map.phf_path("::cssparser::_internal__phf");
+        for &(ref key, ref value) in &pairs {
+            map.entry(&**key, &**value);
+        }
 
-    let tokens = quote! {
-        const MAX_LENGTH: usize = #max_length;
-    };
-
-    tokens.as_str().parse().unwrap()
+        let mut tokens = quote! {
+            static MAP: ::cssparser::_internal__phf::Map<&'static str, #value_type> =
+        };
+        let mut initializer_bytes = Vec::new();
+        map.build(&mut initializer_bytes).unwrap();
+        tokens.append(::std::str::from_utf8(&initializer_bytes).unwrap());
+        tokens.append(";");
+        tokens.into_string()
+    }
 }
 
-/// On `struct $Name($ValueType)`, add a new static method
-/// `fn map() -> &'static ::phf::Map<&'static str, $ValueType>`.
-/// The map’s content is given as:
-/// `#[cssparser__phf_map__kv_pairs(key = "…", value = "…", key = "…", value = "…")]`.
-/// Keys are ASCII-lowercased.
-#[proc_macro_derive(cssparser__phf_map,
-                    attributes(cssparser__phf_map__kv_pairs))]
-pub fn phf_map(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
-    let input = syn::parse_macro_input(&input.to_string()).unwrap();
-    let name = &input.ident;
-    let value_type = match input.body {
-        syn::Body::Struct(syn::VariantData::Tuple(ref fields)) if fields.len() == 1 => {
-            &fields[0].ty
-        }
-        _ => panic!("expected tuple struct newtype, got {:?}", input.body)
-    };
-
-    let pairs: Vec<_> = list_attr(&input, "cssparser__phf_map__kv_pairs").chunks(2).map(|chunk| {
-        let key = sub_attr_value(&chunk[0], "key");
-        let value = sub_attr_value(&chunk[1], "value");
-        (key.to_ascii_lowercase(), value)
-    }).collect();
-
-    let mut map = phf_codegen::Map::new();
-    for &(ref key, value) in &pairs {
-        map.entry(&**key, value);
-    }
-
-    let mut initializer_bytes = Vec::<u8>::new();
-    let mut initializer_tokens = quote::Tokens::new();
-    map.build(&mut initializer_bytes).unwrap();
-    initializer_tokens.append(::std::str::from_utf8(&initializer_bytes).unwrap());
-
-    let tokens = quote! {
-        impl #name {
-            #[inline]
-            fn map() -> &'static ::phf::Map<&'static str, #value_type> {
-                static MAP: ::phf::Map<&'static str, #value_type> = #initializer_tokens;
-                &MAP
-            }
-        }
-    };
-
-    tokens.as_str().parse().unwrap()
+fn max_len<I: Iterator<Item=usize>>(lengths: I) -> String {
+    let max_length = lengths.max().expect("expected at least one string");
+    quote!( const MAX_LENGTH: usize = #max_length; ).into_string()
 }
 
-/// Panic if the first attribute isn’t `#[foo(…)]` with the given name,
-/// or return the parameters.
-fn list_attr<'a>(input: &'a syn::DeriveInput, expected_name: &str) -> &'a [syn::NestedMetaItem] {
-    for attr in &input.attrs {
-        match attr.value {
-            syn::MetaItem::List(ref name, ref nested) if name == expected_name => {
-                return nested
-            }
-            _ => {}
-        }
-    }
-    panic!("expected a {} attribute", expected_name)
-}
-
-/// Panic if `sub_attr` is not a name-value like `foo = "…"` with the given name,
-/// or return the value.
-fn sub_attr_value<'a>(sub_attr: &'a syn::NestedMetaItem, expected_name: &str) -> &'a str {
-    match *sub_attr {
-        syn::NestedMetaItem::MetaItem(
-            syn::MetaItem::NameValue(ref name, syn::Lit::Str(ref value, _))
-        )
-        if name == expected_name => {
-            value
-        }
-        _ => {
-            panic!("expected a `{} = \"…\"` parameter to the attribute, got {:?}",
-                   expected_name, sub_attr)
-        }
+fn string_literal(token: &syn::TokenTree) -> &str {
+    match *token {
+        syn::TokenTree::Token(syn::Token::Literal(syn::Lit::Str(ref string, _))) => string,
+        _ => panic!("expected string literal, got {:?}", token)
     }
 }
--- a/third_party/rust/cssparser/.cargo-checksum.json
+++ b/third_party/rust/cssparser/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"e32812a8f09b0c5b0b972e2e090f8929eb5b600a37ca7aac2ed07ba10c30291e",".travis.yml":"f1fb4b65964c81bc1240544267ea334f554ca38ae7a74d57066f4d47d2b5d568","Cargo.toml":"b8bd480e473642bfe3a7075661ea5f9ddff03b703dddaddb796cfd0d82ee73f3","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"9afe084d70a5d9396674a2624012d6ac749df35f81e322d2d75b042bf208f523","build.rs":"56bfa720a5982d724661a8029315e801258e67245354aabaf2120b73f853cf3c","docs/.nojekyll":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","docs/404.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","docs/index.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","src/big-data-url.css":"04a8f6197ea1181123bca48bd1ebd016268e1da40f01b8f21055814e44bf62b8","src/color.rs":"4941bb291e3be9537c70bac16cedb57b338daded2a801b19201302bacae2dca5","src/css-parsing-tests/An+B.json":"d24559c1dad55d3da9d1fca29383edefdfc6046988435d6388a9bc0f28850257","src/css-parsing-tests/LICENSE":"5f9019a92f4aa8917aadc8e035aa673c2c1bf08d5ca2e535a0564106599f44eb","src/css-parsing-tests/README.rst":"775c5f957dd1d46d3ce954aaad219c821d2b64b4a9fb93c42e9737a11131ca44","src/css-parsing-tests/color3.json":"008f080f6f2dbae5ee403ff46aaa40a9a16e68a2b8923446ac6374f04da9e868","src/css-parsing-tests/color3_hsl.json":"09a4a1e51fb78276cdbf2e834cc9234f5b97c35426ddc879e35b2b09990327b5","src/css-parsing-tests/color3_keywords.json":"95609bf9fe762c316878a30f371fa375a2e51c21a6fda24fa188a95cd9118f5c","src/css-parsing-tests/component_value_list.json":"dda7244eb3a4fcf6d296762e285f7031028837d987065a09e584e8d973edc7f3","src/css-parsing-tests/declaration_list.json":"0b85cc3f19e945f838432acbfb9edb003abea13debc4ea27bcdcef25d117eac5","src/css-parsing-tests/make_color3_hsl.py":"df6f4c154c098641aab81d030de53c65d75d9bde429e9d1ff7069cc5b1827031","src/css-parsing-tests/make_color3_keywords.py":"66bccab3f1dea18698fcfd854be79b1fd1cd724dd487e25b1f057b522163aad2","src/css-parsing-tests/one_component_value.json":"8798017709002e14cf11e203c9d716f82d308ce6ba0f6e64ee4eea331b8485c6","src/css-parsing-tests/one_declaration.json":"a34c9da56edfff9e2e21615f059e141b0e878e90f794dc8fa58d65b47cd193ed","src/css-parsing-tests/one_rule.json":"88f7b1b6049be88e1e2827673b75fc9261986b216e8ee6bf09621fecbe274e3c","src/css-parsing-tests/rule_list.json":"97c45e80fb83abef149a4016c5625a74f053e7ad70a2ce5a95c02fce1c195686","src/css-parsing-tests/stylesheet.json":"05f1e10fc486bfbda2c059c313a74ff78c0063c0768b99737cab41969c0c87ce","src/css-parsing-tests/stylesheet_bytes.json":"890fd856a596e61f82cf7ed77920ffe95df89209fdb5ee0afe0b26bdfdb80a42","src/css-parsing-tests/urange.json":"7ce494811fcb64f20597bd11c88dc99bd72445290582e280bf7774f5d15e1ed3","src/from_bytes.rs":"331fe63af2123ae3675b61928a69461b5ac77799fff3ce9978c55cf2c558f4ff","src/lib.rs":"718d9ecd62b66ad0b2337f5f4aa89421ef25bfe12a8a98d0f882059fb3e321b0","src/macros/match_byte.rs":"89e8b941af74df2c204abf808672d3ff278bdec75abc918c41a843260b924677","src/macros/mod.rs":"99ffb7c3dbb5a09c7363db84a6ea439ab848439615b37a2e420710c5be3fbde2","src/nth.rs":"0a5e68bd8a597403e184ebf34e69230ae1e955f92b16b99b3f67cf8730a180a9","src/parser.rs":"99739b79e0829d868fc9d3ded5a20d54023dd4ff4bd71f2d0bf8e20df4f395ac","src/rules_and_declarations.rs":"6b66a986e411a56998546ab0e64de5285df3368d7c4018c7230a1b6cf6bcc532","src/serializer.rs":"4521b58389bd57acced55c3c6130831b7f80eff48ef873c48c5363e0eca0a15c","src/tests.rs":"10e2f5358b4bbbb58ef4ee5fcff5e86db1bbc3462ee892de2171f63cb46125c3","src/tokenizer.rs":"ef1f220224365d46299160191facd2d9e0534e10ef362129cf56cd3dbb87106a","src/unicode_range.rs":"a3accaf00b8e0e93ba9af0863024507b97ddc2646e65c5f7421597a269317ac0"},"package":"d8352ccd22c5ebab558d179e32f6d3dd26eed30252f8420d636bfae5052eb50e"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"e32812a8f09b0c5b0b972e2e090f8929eb5b600a37ca7aac2ed07ba10c30291e",".travis.yml":"f1fb4b65964c81bc1240544267ea334f554ca38ae7a74d57066f4d47d2b5d568","Cargo.toml":"ef633aeb8f29bb5577a87178daaae3dbeb37ca792696be08cce3d48ce5a0f5f4","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"9afe084d70a5d9396674a2624012d6ac749df35f81e322d2d75b042bf208f523","build.rs":"950bcc47a196f07f99f59637c28cc65e02a885130011f90a2b2608248b4724a2","build/match_byte.rs":"89e8b941af74df2c204abf808672d3ff278bdec75abc918c41a843260b924677","docs/.nojekyll":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","docs/404.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","docs/index.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","src/big-data-url.css":"04a8f6197ea1181123bca48bd1ebd016268e1da40f01b8f21055814e44bf62b8","src/color.rs":"1534825f7462378ad830954168b8d257d82b95709c140ba8e463a6ada05727b7","src/css-parsing-tests/An+B.json":"d24559c1dad55d3da9d1fca29383edefdfc6046988435d6388a9bc0f28850257","src/css-parsing-tests/LICENSE":"5f9019a92f4aa8917aadc8e035aa673c2c1bf08d5ca2e535a0564106599f44eb","src/css-parsing-tests/README.rst":"775c5f957dd1d46d3ce954aaad219c821d2b64b4a9fb93c42e9737a11131ca44","src/css-parsing-tests/color3.json":"008f080f6f2dbae5ee403ff46aaa40a9a16e68a2b8923446ac6374f04da9e868","src/css-parsing-tests/color3_hsl.json":"09a4a1e51fb78276cdbf2e834cc9234f5b97c35426ddc879e35b2b09990327b5","src/css-parsing-tests/color3_keywords.json":"95609bf9fe762c316878a30f371fa375a2e51c21a6fda24fa188a95cd9118f5c","src/css-parsing-tests/component_value_list.json":"dda7244eb3a4fcf6d296762e285f7031028837d987065a09e584e8d973edc7f3","src/css-parsing-tests/declaration_list.json":"0b85cc3f19e945f838432acbfb9edb003abea13debc4ea27bcdcef25d117eac5","src/css-parsing-tests/make_color3_hsl.py":"df6f4c154c098641aab81d030de53c65d75d9bde429e9d1ff7069cc5b1827031","src/css-parsing-tests/make_color3_keywords.py":"66bccab3f1dea18698fcfd854be79b1fd1cd724dd487e25b1f057b522163aad2","src/css-parsing-tests/one_component_value.json":"8798017709002e14cf11e203c9d716f82d308ce6ba0f6e64ee4eea331b8485c6","src/css-parsing-tests/one_declaration.json":"a34c9da56edfff9e2e21615f059e141b0e878e90f794dc8fa58d65b47cd193ed","src/css-parsing-tests/one_rule.json":"88f7b1b6049be88e1e2827673b75fc9261986b216e8ee6bf09621fecbe274e3c","src/css-parsing-tests/rule_list.json":"97c45e80fb83abef149a4016c5625a74f053e7ad70a2ce5a95c02fce1c195686","src/css-parsing-tests/stylesheet.json":"05f1e10fc486bfbda2c059c313a74ff78c0063c0768b99737cab41969c0c87ce","src/css-parsing-tests/stylesheet_bytes.json":"890fd856a596e61f82cf7ed77920ffe95df89209fdb5ee0afe0b26bdfdb80a42","src/css-parsing-tests/urange.json":"7ce494811fcb64f20597bd11c88dc99bd72445290582e280bf7774f5d15e1ed3","src/from_bytes.rs":"331fe63af2123ae3675b61928a69461b5ac77799fff3ce9978c55cf2c558f4ff","src/lib.rs":"517ed8dc4520a1294ecd103b0ffa249550e51f8410124166dddaa2b5488f55af","src/macros.rs":"bd492479eee8c65850bdfc2c9de100eddc224e5d6629cd583219058901cd0ca7","src/nth.rs":"0a5e68bd8a597403e184ebf34e69230ae1e955f92b16b99b3f67cf8730a180a9","src/parser.rs":"99739b79e0829d868fc9d3ded5a20d54023dd4ff4bd71f2d0bf8e20df4f395ac","src/rules_and_declarations.rs":"6b66a986e411a56998546ab0e64de5285df3368d7c4018c7230a1b6cf6bcc532","src/serializer.rs":"4521b58389bd57acced55c3c6130831b7f80eff48ef873c48c5363e0eca0a15c","src/tests.rs":"bfaa3fd5892c6fd32a747d48251eb3262d514dc2b82329086e8c75febed98e95","src/tokenizer.rs":"ef1f220224365d46299160191facd2d9e0534e10ef362129cf56cd3dbb87106a","src/unicode_range.rs":"a3accaf00b8e0e93ba9af0863024507b97ddc2646e65c5f7421597a269317ac0"},"package":"112b0e846ce6b441564c908a2e74d98a2c6f2cbe838b0f32d037d5bfb9e982ca"}
\ No newline at end of file
--- a/third_party/rust/cssparser/Cargo.toml
+++ b/third_party/rust/cssparser/Cargo.toml
@@ -1,12 +1,12 @@
 [package]
 
 name = "cssparser"
-version = "0.11.0"
+version = "0.12.0"
 authors = [ "Simon Sapin <simon.sapin@exyr.org>" ]
 
 description = "Rust implementation of CSS Syntax Level 3"
 documentation = "https://docs.rs/cssparser/"
 repository = "https://github.com/servo/rust-cssparser"
 readme = "README.md"
 keywords = ["css", "syntax", "parser"]
 license = "MPL-2.0"
@@ -15,24 +15,25 @@ build = "build.rs"
 exclude = ["src/css-parsing-tests"]
 
 [dev-dependencies]
 rustc-serialize = "0.3"
 tempdir = "0.3"
 encoding_rs = "0.5"
 
 [dependencies]
-cssparser-macros = {path = "./macros", version = "0.1"}
+cssparser-macros = {path = "./macros", version = "0.2"}
 heapsize = {version = "0.3", optional = true}
 matches = "0.1"
 phf = "0.7"
+procedural-masquerade = {path = "./procedural-masquerade", version = "0.1"}
 serde = {version = "0.9", optional = true}
 
 [build-dependencies]
 syn = "0.11"
 quote = "0.3"
 
 [features]
 bench = []
 dummy_match_byte = []
 
 [workspace]
-members = [".", "./macros"]
+members = [".", "./macros", "./procedural-masquerade"]
--- a/third_party/rust/cssparser/build.rs
+++ b/third_party/rust/cssparser/build.rs
@@ -11,28 +11,28 @@ use std::path::Path;
 
 #[cfg(feature = "dummy_match_byte")]
 mod codegen {
     use std::path::Path;
     pub fn main(_: &Path) {}
 }
 
 #[cfg(not(feature = "dummy_match_byte"))]
-#[path = "src/macros/mod.rs"]
-mod macros;
+#[path = "build/match_byte.rs"]
+mod match_byte;
 
 #[cfg(not(feature = "dummy_match_byte"))]
 mod codegen {
-    use macros;
+    use match_byte;
     use std::env;
     use std::path::Path;
 
     pub fn main(tokenizer_rs: &Path) {
-        macros::match_byte::expand(tokenizer_rs,
-                                   &Path::new(&env::var("OUT_DIR").unwrap()).join("tokenizer.rs"));
+        match_byte::expand(tokenizer_rs,
+                           &Path::new(&env::var("OUT_DIR").unwrap()).join("tokenizer.rs"));
 
     }
 }
 
 fn main() {
     let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
     let tokenizer_rs = Path::new(&manifest_dir).join("src/tokenizer.rs");
     codegen::main(&tokenizer_rs);
rename from third_party/rust/cssparser/src/macros/match_byte.rs
rename to third_party/rust/cssparser/build/match_byte.rs
--- a/third_party/rust/cssparser/src/color.rs
+++ b/third_party/rust/cssparser/src/color.rs
@@ -175,172 +175,172 @@ pub fn parse_color_keyword(ident: &str) 
                 red: $red,
                 green: $green,
                 blue: $blue,
                 alpha: 255,
             })
         }
     }
     ascii_case_insensitive_phf_map! {
-        KEYWORDS: Map<Color> = {
-            "black" => "rgb!(0, 0, 0)",
-            "silver" => "rgb!(192, 192, 192)",
-            "gray" => "rgb!(128, 128, 128)",
-            "white" => "rgb!(255, 255, 255)",
-            "maroon" => "rgb!(128, 0, 0)",
-            "red" => "rgb!(255, 0, 0)",
-            "purple" => "rgb!(128, 0, 128)",
-            "fuchsia" => "rgb!(255, 0, 255)",
-            "green" => "rgb!(0, 128, 0)",
-            "lime" => "rgb!(0, 255, 0)",
-            "olive" => "rgb!(128, 128, 0)",
-            "yellow" => "rgb!(255, 255, 0)",
-            "navy" => "rgb!(0, 0, 128)",
-            "blue" => "rgb!(0, 0, 255)",
-            "teal" => "rgb!(0, 128, 128)",
-            "aqua" => "rgb!(0, 255, 255)",
+        keyword -> Color = {
+            "black" => rgb!(0, 0, 0),
+            "silver" => rgb!(192, 192, 192),
+            "gray" => rgb!(128, 128, 128),
+            "white" => rgb!(255, 255, 255),
+            "maroon" => rgb!(128, 0, 0),
+            "red" => rgb!(255, 0, 0),
+            "purple" => rgb!(128, 0, 128),
+            "fuchsia" => rgb!(255, 0, 255),
+            "green" => rgb!(0, 128, 0),
+            "lime" => rgb!(0, 255, 0),
+            "olive" => rgb!(128, 128, 0),
+            "yellow" => rgb!(255, 255, 0),
+            "navy" => rgb!(0, 0, 128),
+            "blue" => rgb!(0, 0, 255),
+            "teal" => rgb!(0, 128, 128),
+            "aqua" => rgb!(0, 255, 255),
 
-            "aliceblue" => "rgb!(240, 248, 255)",
-            "antiquewhite" => "rgb!(250, 235, 215)",
-            "aquamarine" => "rgb!(127, 255, 212)",
-            "azure" => "rgb!(240, 255, 255)",
-            "beige" => "rgb!(245, 245, 220)",
-            "bisque" => "rgb!(255, 228, 196)",
-            "blanchedalmond" => "rgb!(255, 235, 205)",
-            "blueviolet" => "rgb!(138, 43, 226)",
-            "brown" => "rgb!(165, 42, 42)",
-            "burlywood" => "rgb!(222, 184, 135)",
-            "cadetblue" => "rgb!(95, 158, 160)",
-            "chartreuse" => "rgb!(127, 255, 0)",
-            "chocolate" => "rgb!(210, 105, 30)",
-            "coral" => "rgb!(255, 127, 80)",
-            "cornflowerblue" => "rgb!(100, 149, 237)",
-            "cornsilk" => "rgb!(255, 248, 220)",
-            "crimson" => "rgb!(220, 20, 60)",
-            "cyan" => "rgb!(0, 255, 255)",
-            "darkblue" => "rgb!(0, 0, 139)",
-            "darkcyan" => "rgb!(0, 139, 139)",
-            "darkgoldenrod" => "rgb!(184, 134, 11)",
-            "darkgray" => "rgb!(169, 169, 169)",
-            "darkgreen" => "rgb!(0, 100, 0)",
-            "darkgrey" => "rgb!(169, 169, 169)",
-            "darkkhaki" => "rgb!(189, 183, 107)",
-            "darkmagenta" => "rgb!(139, 0, 139)",
-            "darkolivegreen" => "rgb!(85, 107, 47)",
-            "darkorange" => "rgb!(255, 140, 0)",
-            "darkorchid" => "rgb!(153, 50, 204)",
-            "darkred" => "rgb!(139, 0, 0)",
-            "darksalmon" => "rgb!(233, 150, 122)",
-            "darkseagreen" => "rgb!(143, 188, 143)",
-            "darkslateblue" => "rgb!(72, 61, 139)",
-            "darkslategray" => "rgb!(47, 79, 79)",
-            "darkslategrey" => "rgb!(47, 79, 79)",
-            "darkturquoise" => "rgb!(0, 206, 209)",
-            "darkviolet" => "rgb!(148, 0, 211)",
-            "deeppink" => "rgb!(255, 20, 147)",
-            "deepskyblue" => "rgb!(0, 191, 255)",
-            "dimgray" => "rgb!(105, 105, 105)",
-            "dimgrey" => "rgb!(105, 105, 105)",
-            "dodgerblue" => "rgb!(30, 144, 255)",
-            "firebrick" => "rgb!(178, 34, 34)",
-            "floralwhite" => "rgb!(255, 250, 240)",
-            "forestgreen" => "rgb!(34, 139, 34)",
-            "gainsboro" => "rgb!(220, 220, 220)",
-            "ghostwhite" => "rgb!(248, 248, 255)",
-            "gold" => "rgb!(255, 215, 0)",
-            "goldenrod" => "rgb!(218, 165, 32)",
-            "greenyellow" => "rgb!(173, 255, 47)",
-            "grey" => "rgb!(128, 128, 128)",
-            "honeydew" => "rgb!(240, 255, 240)",
-            "hotpink" => "rgb!(255, 105, 180)",
-            "indianred" => "rgb!(205, 92, 92)",
-            "indigo" => "rgb!(75, 0, 130)",
-            "ivory" => "rgb!(255, 255, 240)",
-            "khaki" => "rgb!(240, 230, 140)",
-            "lavender" => "rgb!(230, 230, 250)",
-            "lavenderblush" => "rgb!(255, 240, 245)",
-            "lawngreen" => "rgb!(124, 252, 0)",
-            "lemonchiffon" => "rgb!(255, 250, 205)",
-            "lightblue" => "rgb!(173, 216, 230)",
-            "lightcoral" => "rgb!(240, 128, 128)",
-            "lightcyan" => "rgb!(224, 255, 255)",
-            "lightgoldenrodyellow" => "rgb!(250, 250, 210)",
-            "lightgray" => "rgb!(211, 211, 211)",
-            "lightgreen" => "rgb!(144, 238, 144)",
-            "lightgrey" => "rgb!(211, 211, 211)",
-            "lightpink" => "rgb!(255, 182, 193)",
-            "lightsalmon" => "rgb!(255, 160, 122)",
-            "lightseagreen" => "rgb!(32, 178, 170)",
-            "lightskyblue" => "rgb!(135, 206, 250)",
-            "lightslategray" => "rgb!(119, 136, 153)",
-            "lightslategrey" => "rgb!(119, 136, 153)",
-            "lightsteelblue" => "rgb!(176, 196, 222)",
-            "lightyellow" => "rgb!(255, 255, 224)",
-            "limegreen" => "rgb!(50, 205, 50)",
-            "linen" => "rgb!(250, 240, 230)",
-            "magenta" => "rgb!(255, 0, 255)",
-            "mediumaquamarine" => "rgb!(102, 205, 170)",
-            "mediumblue" => "rgb!(0, 0, 205)",
-            "mediumorchid" => "rgb!(186, 85, 211)",
-            "mediumpurple" => "rgb!(147, 112, 219)",
-            "mediumseagreen" => "rgb!(60, 179, 113)",
-            "mediumslateblue" => "rgb!(123, 104, 238)",
-            "mediumspringgreen" => "rgb!(0, 250, 154)",
-            "mediumturquoise" => "rgb!(72, 209, 204)",
-            "mediumvioletred" => "rgb!(199, 21, 133)",
-            "midnightblue" => "rgb!(25, 25, 112)",
-            "mintcream" => "rgb!(245, 255, 250)",
-            "mistyrose" => "rgb!(255, 228, 225)",
-            "moccasin" => "rgb!(255, 228, 181)",
-            "navajowhite" => "rgb!(255, 222, 173)",
-            "oldlace" => "rgb!(253, 245, 230)",
-            "olivedrab" => "rgb!(107, 142, 35)",
-            "orange" => "rgb!(255, 165, 0)",
-            "orangered" => "rgb!(255, 69, 0)",
-            "orchid" => "rgb!(218, 112, 214)",
-            "palegoldenrod" => "rgb!(238, 232, 170)",
-            "palegreen" => "rgb!(152, 251, 152)",
-            "paleturquoise" => "rgb!(175, 238, 238)",
-            "palevioletred" => "rgb!(219, 112, 147)",
-            "papayawhip" => "rgb!(255, 239, 213)",
-            "peachpuff" => "rgb!(255, 218, 185)",
-            "peru" => "rgb!(205, 133, 63)",
-            "pink" => "rgb!(255, 192, 203)",
-            "plum" => "rgb!(221, 160, 221)",
-            "powderblue" => "rgb!(176, 224, 230)",
-            "rebeccapurple" => "rgb!(102, 51, 153)",
-            "rosybrown" => "rgb!(188, 143, 143)",
-            "royalblue" => "rgb!(65, 105, 225)",
-            "saddlebrown" => "rgb!(139, 69, 19)",
-            "salmon" => "rgb!(250, 128, 114)",
-            "sandybrown" => "rgb!(244, 164, 96)",
-            "seagreen" => "rgb!(46, 139, 87)",
-            "seashell" => "rgb!(255, 245, 238)",
-            "sienna" => "rgb!(160, 82, 45)",
-            "skyblue" => "rgb!(135, 206, 235)",
-            "slateblue" => "rgb!(106, 90, 205)",
-            "slategray" => "rgb!(112, 128, 144)",
-            "slategrey" => "rgb!(112, 128, 144)",
-            "snow" => "rgb!(255, 250, 250)",
-            "springgreen" => "rgb!(0, 255, 127)",
-            "steelblue" => "rgb!(70, 130, 180)",
-            "tan" => "rgb!(210, 180, 140)",
-            "thistle" => "rgb!(216, 191, 216)",
-            "tomato" => "rgb!(255, 99, 71)",
-            "turquoise" => "rgb!(64, 224, 208)",
-            "violet" => "rgb!(238, 130, 238)",
-            "wheat" => "rgb!(245, 222, 179)",
-            "whitesmoke" => "rgb!(245, 245, 245)",
-            "yellowgreen" => "rgb!(154, 205, 50)",
+            "aliceblue" => rgb!(240, 248, 255),
+            "antiquewhite" => rgb!(250, 235, 215),
+            "aquamarine" => rgb!(127, 255, 212),
+            "azure" => rgb!(240, 255, 255),
+            "beige" => rgb!(245, 245, 220),
+            "bisque" => rgb!(255, 228, 196),
+            "blanchedalmond" => rgb!(255, 235, 205),
+            "blueviolet" => rgb!(138, 43, 226),
+            "brown" => rgb!(165, 42, 42),
+            "burlywood" => rgb!(222, 184, 135),
+            "cadetblue" => rgb!(95, 158, 160),
+            "chartreuse" => rgb!(127, 255, 0),
+            "chocolate" => rgb!(210, 105, 30),
+            "coral" => rgb!(255, 127, 80),
+            "cornflowerblue" => rgb!(100, 149, 237),
+            "cornsilk" => rgb!(255, 248, 220),
+            "crimson" => rgb!(220, 20, 60),
+            "cyan" => rgb!(0, 255, 255),
+            "darkblue" => rgb!(0, 0, 139),
+            "darkcyan" => rgb!(0, 139, 139),
+            "darkgoldenrod" => rgb!(184, 134, 11),
+            "darkgray" => rgb!(169, 169, 169),
+            "darkgreen" => rgb!(0, 100, 0),
+            "darkgrey" => rgb!(169, 169, 169),
+            "darkkhaki" => rgb!(189, 183, 107),
+            "darkmagenta" => rgb!(139, 0, 139),
+            "darkolivegreen" => rgb!(85, 107, 47),
+            "darkorange" => rgb!(255, 140, 0),
+            "darkorchid" => rgb!(153, 50, 204),
+            "darkred" => rgb!(139, 0, 0),
+            "darksalmon" => rgb!(233, 150, 122),
+            "darkseagreen" => rgb!(143, 188, 143),
+            "darkslateblue" => rgb!(72, 61, 139),
+            "darkslategray" => rgb!(47, 79, 79),
+            "darkslategrey" => rgb!(47, 79, 79),
+            "darkturquoise" => rgb!(0, 206, 209),
+            "darkviolet" => rgb!(148, 0, 211),
+            "deeppink" => rgb!(255, 20, 147),
+            "deepskyblue" => rgb!(0, 191, 255),
+            "dimgray" => rgb!(105, 105, 105),
+            "dimgrey" => rgb!(105, 105, 105),
+            "dodgerblue" => rgb!(30, 144, 255),
+            "firebrick" => rgb!(178, 34, 34),
+            "floralwhite" => rgb!(255, 250, 240),
+            "forestgreen" => rgb!(34, 139, 34),
+            "gainsboro" => rgb!(220, 220, 220),
+            "ghostwhite" => rgb!(248, 248, 255),
+            "gold" => rgb!(255, 215, 0),
+            "goldenrod" => rgb!(218, 165, 32),
+            "greenyellow" => rgb!(173, 255, 47),
+            "grey" => rgb!(128, 128, 128),
+            "honeydew" => rgb!(240, 255, 240),
+            "hotpink" => rgb!(255, 105, 180),
+            "indianred" => rgb!(205, 92, 92),
+            "indigo" => rgb!(75, 0, 130),
+            "ivory" => rgb!(255, 255, 240),
+            "khaki" => rgb!(240, 230, 140),
+            "lavender" => rgb!(230, 230, 250),
+            "lavenderblush" => rgb!(255, 240, 245),
+            "lawngreen" => rgb!(124, 252, 0),
+            "lemonchiffon" => rgb!(255, 250, 205),
+            "lightblue" => rgb!(173, 216, 230),
+            "lightcoral" => rgb!(240, 128, 128),
+            "lightcyan" => rgb!(224, 255, 255),
+            "lightgoldenrodyellow" => rgb!(250, 250, 210),
+            "lightgray" => rgb!(211, 211, 211),
+            "lightgreen" => rgb!(144, 238, 144),
+            "lightgrey" => rgb!(211, 211, 211),
+            "lightpink" => rgb!(255, 182, 193),
+            "lightsalmon" => rgb!(255, 160, 122),
+            "lightseagreen" => rgb!(32, 178, 170),
+            "lightskyblue" => rgb!(135, 206, 250),
+            "lightslategray" => rgb!(119, 136, 153),
+            "lightslategrey" => rgb!(119, 136, 153),
+            "lightsteelblue" => rgb!(176, 196, 222),
+            "lightyellow" => rgb!(255, 255, 224),
+            "limegreen" => rgb!(50, 205, 50),
+            "linen" => rgb!(250, 240, 230),
+            "magenta" => rgb!(255, 0, 255),
+            "mediumaquamarine" => rgb!(102, 205, 170),
+            "mediumblue" => rgb!(0, 0, 205),
+            "mediumorchid" => rgb!(186, 85, 211),
+            "mediumpurple" => rgb!(147, 112, 219),
+            "mediumseagreen" => rgb!(60, 179, 113),
+            "mediumslateblue" => rgb!(123, 104, 238),
+            "mediumspringgreen" => rgb!(0, 250, 154),
+            "mediumturquoise" => rgb!(72, 209, 204),
+            "mediumvioletred" => rgb!(199, 21, 133),
+            "midnightblue" => rgb!(25, 25, 112),
+            "mintcream" => rgb!(245, 255, 250),
+            "mistyrose" => rgb!(255, 228, 225),
+            "moccasin" => rgb!(255, 228, 181),
+            "navajowhite" => rgb!(255, 222, 173),
+            "oldlace" => rgb!(253, 245, 230),
+            "olivedrab" => rgb!(107, 142, 35),
+            "orange" => rgb!(255, 165, 0),
+            "orangered" => rgb!(255, 69, 0),
+            "orchid" => rgb!(218, 112, 214),
+            "palegoldenrod" => rgb!(238, 232, 170),
+            "palegreen" => rgb!(152, 251, 152),
+            "paleturquoise" => rgb!(175, 238, 238),
+            "palevioletred" => rgb!(219, 112, 147),
+            "papayawhip" => rgb!(255, 239, 213),
+            "peachpuff" => rgb!(255, 218, 185),
+            "peru" => rgb!(205, 133, 63),
+            "pink" => rgb!(255, 192, 203),
+            "plum" => rgb!(221, 160, 221),
+            "powderblue" => rgb!(176, 224, 230),
+            "rebeccapurple" => rgb!(102, 51, 153),
+            "rosybrown" => rgb!(188, 143, 143),
+            "royalblue" => rgb!(65, 105, 225),
+            "saddlebrown" => rgb!(139, 69, 19),
+            "salmon" => rgb!(250, 128, 114),
+            "sandybrown" => rgb!(244, 164, 96),
+            "seagreen" => rgb!(46, 139, 87),
+            "seashell" => rgb!(255, 245, 238),
+            "sienna" => rgb!(160, 82, 45),
+            "skyblue" => rgb!(135, 206, 235),
+            "slateblue" => rgb!(106, 90, 205),
+            "slategray" => rgb!(112, 128, 144),
+            "slategrey" => rgb!(112, 128, 144),
+            "snow" => rgb!(255, 250, 250),
+            "springgreen" => rgb!(0, 255, 127),
+            "steelblue" => rgb!(70, 130, 180),
+            "tan" => rgb!(210, 180, 140),
+            "thistle" => rgb!(216, 191, 216),
+            "tomato" => rgb!(255, 99, 71),
+            "turquoise" => rgb!(64, 224, 208),
+            "violet" => rgb!(238, 130, 238),
+            "wheat" => rgb!(245, 222, 179),
+            "whitesmoke" => rgb!(245, 245, 245),
+            "yellowgreen" => rgb!(154, 205, 50),
 
-            "transparent" => "Color::RGBA(RGBA { red: 0, green: 0, blue: 0, alpha: 0 })",
-            "currentcolor" => "Color::CurrentColor",
+            "transparent" => Color::RGBA(RGBA { red: 0, green: 0, blue: 0, alpha: 0 }),
+            "currentcolor" => Color::CurrentColor,
         }
     }
-    KEYWORDS::get(ident).cloned().ok_or(())
+    keyword(ident).cloned().ok_or(())
 }
 
 
 #[inline]
 fn from_hex(c: u8) -> Result<u8, ()> {
     match c {
         b'0' ... b'9' => Ok(c - b'0'),
         b'a' ... b'f' => Ok(c - b'a' + 10),
--- a/third_party/rust/cssparser/src/lib.rs
+++ b/third_party/rust/cssparser/src/lib.rs
@@ -65,229 +65,50 @@ fn parse_border_spacing(_context: &Parse
 ```
 
 */
 
 #![recursion_limit="200"]  // For color::parse_color_keyword
 
 #[macro_use] extern crate cssparser_macros;
 #[macro_use] extern crate matches;
-extern crate phf;
+#[macro_use] extern crate procedural_masquerade;
+#[doc(hidden)] pub extern crate phf as _internal__phf;
 #[cfg(test)] extern crate encoding_rs;
 #[cfg(test)] extern crate tempdir;
 #[cfg(test)] extern crate rustc_serialize;
 #[cfg(feature = "serde")] extern crate serde;
 #[cfg(feature = "heapsize")] #[macro_use] extern crate heapsize;
 
+pub use cssparser_macros::*;
+
 pub use tokenizer::{Token, NumericValue, PercentageValue, SourceLocation};
 pub use rules_and_declarations::{parse_important};
 pub use rules_and_declarations::{DeclarationParser, DeclarationListParser, parse_one_declaration};
 pub use rules_and_declarations::{RuleListParser, parse_one_rule};
 pub use rules_and_declarations::{AtRuleType, QualifiedRuleParser, AtRuleParser};
 pub use from_bytes::{stylesheet_encoding, EncodingSupport};
 pub use color::{RGBA, Color, parse_color_keyword};
 pub use nth::parse_nth;
 pub use serializer::{ToCss, CssStringWriter, serialize_identifier, serialize_string, TokenSerializationType};
 pub use parser::{Parser, Delimiter, Delimiters, SourcePosition};
 pub use unicode_range::UnicodeRange;
 
-/// Expands to an expression equivalent to a `match` with string patterns,
-/// but matching is case-insensitive in the ASCII range.
-///
-/// Requirements:
-///
-/// * The `cssparser_macros` crate must also be imported at the crate root
-/// * The patterns must not contain ASCII upper case letters. (They must be already be lower-cased.)
-///
-/// # Example
-///
-/// ```rust
-/// #[macro_use] extern crate cssparser;
-/// #[macro_use] extern crate cssparser_macros;
-///
-/// # fn main() {}  // Make doctest not wrap everythig in its own main
-/// # fn dummy(function_name: &String) { let _ =
-/// match_ignore_ascii_case! { &function_name,
-///     "rgb" => parse_rgb(..),
-///     "rgba" => parse_rgba(..),
-///     "hsl" => parse_hsl(..),
-///     "hsla" => parse_hsla(..),
-///     _ => Err("unknown function")
-/// }
-/// # ;}
-/// # use std::ops::RangeFull;
-/// # fn parse_rgb(_: RangeFull) -> Result<(), &'static str> { Err("") }
-/// # fn parse_rgba(_: RangeFull) -> Result<(), &'static str> { Err("") }
-/// # fn parse_hsl(_: RangeFull) -> Result<(), &'static str> { Err("") }
-/// # fn parse_hsla(_: RangeFull) -> Result<(), &'static str> { Err("") }
-/// ```
-#[macro_export]
-macro_rules! match_ignore_ascii_case {
-    // parse the last case plus the fallback
-    (@inner $value:expr, ($string:expr => $result:expr, _ => $fallback:expr) -> ($($parsed:tt)*) ) => {
-        match_ignore_ascii_case!(@inner $value, () -> ($($parsed)* ($string => $result)) $fallback)
-    };
-
-    // parse a case (not the last one)
-    (@inner $value:expr, ($string:expr => $result:expr, $($rest:tt)*) -> ($($parsed:tt)*) ) => {
-        match_ignore_ascii_case!(@inner $value, ($($rest)*) -> ($($parsed)* ($string => $result)))
-    };
-
-    // finished parsing
-    (@inner $value:expr, () -> ($(($string:expr => $result:expr))*) $fallback:expr ) => {
-        {
-            #[derive(cssparser__assert_ascii_lowercase)]
-            #[cssparser__assert_ascii_lowercase__data($(string = $string),+)]
-            #[allow(dead_code)]
-            struct Dummy;
-
-            _cssparser_internal__to_lowercase!($value => lowercase, $($string),+);
-            match lowercase {
-                $(
-                    Some($string) => $result,
-                )+
-                _ => $fallback
-            }
-        }
-    };
-
-    // entry point, start parsing
-    ( $value:expr, $($rest:tt)* ) => {
-        match_ignore_ascii_case!(@inner $value, ($($rest)*) -> ())
-    };
-}
+// For macros
+#[doc(hidden)] pub use macros::_internal__to_lowercase;
 
-/// Define a placeholder type `$Name`
-/// with a method `fn get(input: &str) -> Option<&'static $ValueType>`.
-///
-/// This method uses finds a match for the input string
-/// in a [`phf` map](https://github.com/sfackler/rust-phf).
-/// Matching is case-insensitive in the ASCII range.
-///
-/// Requirements:
-///
-/// * The `phf` and `cssparser_macros` crates must also be imported at the crate root
-/// * The values must be given a strings that contain Rust syntax for a constant expression.
-///
-/// ## Example:
-///
-/// ```rust
-/// extern crate phf;
-/// #[macro_use] extern crate cssparser;
-/// #[macro_use] extern crate cssparser_macros;
-///
-/// # fn main() {}  // Make doctest not wrap everythig in its own main
-///
-/// fn color_rgb(input: &str) -> Option<(u8, u8, u8)> {
-///     ascii_case_insensitive_phf_map! {
-///         KEYWORDS: Map<(u8, u8, u8)> = {
-///             "red" => "(255, 0, 0)",
-///             "green" => "(0, 255, 0)",
-///             "blue" => "(0, 0, 255)",
-///         }
-///     }
-///     KEYWORDS::get(input).cloned()
-/// }
-#[macro_export]
-macro_rules! ascii_case_insensitive_phf_map {
-    ($Name: ident : Map<$ValueType: ty> = {
-        $( $key: expr => $value: expr, )*
-    }) => {
-        #[derive(cssparser__phf_map)]
-        #[cssparser__phf_map__kv_pairs(
-            $(
-                key = $key,
-                value = $value
-            ),+
-        )]
-        struct $Name($ValueType);
-
-        impl $Name {
-            #[inline]
-            fn get(input: &str) -> Option<&'static $ValueType> {
-                _cssparser_internal__to_lowercase!(input => lowercase, $($key),+);
-                lowercase.and_then(|string| $Name::map().get(string))
-            }
-        }
-    }
-}
+// For macros when used in this crate. Unsure how $crate works with procedural-masquerade.
+mod cssparser { pub use _internal__phf; }
 
-/// Implementation detail of match_ignore_ascii_case! and ascii_case_insensitive_phf_map! macros.
-///
-/// **This macro is not part of the public API. It can change or be removed between any versions.**
-///
-/// * Check at compile-time that none of the `$string`s contain ASCII uppercase letters
-/// * Define a local variable named `$output` to the result of calling `_internal__to_lowercase`
-///   with a stack-allocated buffer as long as the longest `$string`.
-#[macro_export]
-#[doc(hidden)]
-macro_rules! _cssparser_internal__to_lowercase {
-    ($input: expr => $output: ident, $($string: expr),+) => {
-        #[derive(cssparser__max_len)]
-        #[cssparser__max_len__data($(string = $string),+)]
-        #[allow(dead_code)]
-        struct Dummy2;
-
-        // mem::uninitialized() is ok because `buffer` is only used in `_internal__to_lowercase`,
-        // which initializes with `copy_from_slice` the part of the buffer it uses,
-        // before it uses it.
-        #[allow(unsafe_code)]
-        // MAX_LENGTH is generated by cssparser__max_len
-        let mut buffer: [u8; MAX_LENGTH] = unsafe {
-            ::std::mem::uninitialized()
-        };
-        let input: &str = $input;
-        let $output = $crate::_internal__to_lowercase(&mut buffer, input);
-    }
-}
-
-
-/// Implementation detail of match_ignore_ascii_case! and ascii_case_insensitive_phf_map! macros.
-///
-/// **This function is not part of the public API. It can change or be removed between any verisons.**
-///
-/// Return `input`, lower-cased, unless larger than `buffer`
-/// which is used temporary space for lower-casing a copy of `input` if necessary.
-#[doc(hidden)]
-#[allow(non_snake_case)]
-pub fn _internal__to_lowercase<'a>(buffer: &'a mut [u8], input: &'a str) -> Option<&'a str> {
-    if let Some(buffer) = buffer.get_mut(..input.len()) {
-        if let Some(first_uppercase) = input.bytes().position(|byte| matches!(byte, b'A'...b'Z')) {
-            buffer.copy_from_slice(input.as_bytes());
-            std::ascii::AsciiExt::make_ascii_lowercase(&mut buffer[first_uppercase..]);
-            // `buffer` was initialized to a copy of `input` (which is &str so well-formed UTF-8)
-            // then lowercased (which preserves UTF-8 well-formedness)
-            unsafe {
-                Some(::std::str::from_utf8_unchecked(buffer))
-            }
-        } else {
-            // Input is already lower-case
-            Some(input)
-        }
-    } else {
-        // Input is longer than buffer, which has the length of the longest expected string:
-        // none of the expected strings would match.
-        None
-    }
-}
+#[macro_use]
+mod macros;
 
 mod rules_and_declarations;
 
 #[cfg(feature = "dummy_match_byte")]
-macro_rules! match_byte {
-    ($value:expr, $($rest:tt)* ) => {
-        match $value {
-            $(
-                $rest
-            )+
-        }
-    };
-}
-
-#[cfg(feature = "dummy_match_byte")]
 mod tokenizer;
 
 #[cfg(not(feature = "dummy_match_byte"))]
 mod tokenizer {
     include!(concat!(env!("OUT_DIR"), "/tokenizer.rs"));
 }
 mod parser;
 mod from_bytes;
new file mode 100644
--- /dev/null
+++ b/third_party/rust/cssparser/src/macros.rs
@@ -0,0 +1,163 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/// See docs of the `procedural-masquerade` crate.
+define_invoke_proc_macro!(cssparser_internal__invoke_proc_macro);
+
+/// Expands to a `match` expression with string patterns,
+/// matching case-insensitively in the ASCII range.
+///
+/// The patterns must not contain ASCII upper case letters. (They must be already be lower-cased.)
+///
+/// # Example
+///
+/// ```rust
+/// #[macro_use] extern crate cssparser;
+///
+/// # fn main() {}  // Make doctest not wrap everythig in its own main
+/// # fn dummy(function_name: &String) { let _ =
+/// match_ignore_ascii_case! { &function_name,
+///     "rgb" => parse_rgb(..),
+///     "rgba" => parse_rgba(..),
+///     "hsl" => parse_hsl(..),
+///     "hsla" => parse_hsla(..),
+///     name @ _ => Err(format!("unknown function: {}", name))
+/// }
+/// # ;}
+/// # use std::ops::RangeFull;
+/// # fn parse_rgb(_: RangeFull) -> Result<(), String> { Ok(()) }
+/// # fn parse_rgba(_: RangeFull) -> Result<(), String> { Ok(()) }
+/// # fn parse_hsl(_: RangeFull) -> Result<(), String> { Ok(()) }
+/// # fn parse_hsla(_: RangeFull) -> Result<(), String> { Ok(()) }
+/// ```
+#[macro_export]
+macro_rules! match_ignore_ascii_case {
+    ( $input:expr, $( $match_body:tt )* ) => {
+        {
+            cssparser_internal__invoke_proc_macro! {
+                cssparser_internal__assert_ascii_lowercase__max_len!( $( $match_body )* )
+            }
+
+            {
+                // MAX_LENGTH is generated by cssparser_internal__assert_ascii_lowercase__max_len
+                cssparser_internal__to_lowercase!($input, MAX_LENGTH => lowercase);
+                // "A" is a short string that we know is different for every string pattern,
+                // since we’ve verified that none of them include ASCII upper case letters.
+                match lowercase.unwrap_or("A") {
+                    $( $match_body )*
+                }
+            }
+        }
+    };
+}
+
+/// Define a function `$name(&str) -> Option<&'static $ValueType>`
+///
+/// The function finds a match for the input string
+/// in a [`phf` map](https://github.com/sfackler/rust-phf)
+/// and returns a reference to the corresponding value.
+/// Matching is case-insensitive in the ASCII range.
+///
+/// ## Example:
+///
+/// ```rust
+/// #[macro_use] extern crate cssparser;
+///
+/// # fn main() {}  // Make doctest not wrap everything in its own main
+///
+/// fn color_rgb(input: &str) -> Option<(u8, u8, u8)> {
+///     ascii_case_insensitive_phf_map! {
+///         keyword -> (u8, u8, u8) = {
+///             "red" => (255, 0, 0),
+///             "green" => (0, 255, 0),
+///             "blue" => (0, 0, 255),
+///         }
+///     }
+///     keyword(input).cloned()
+/// }
+#[macro_export]
+macro_rules! ascii_case_insensitive_phf_map {
+    ($name: ident -> $ValueType: ty = { $( $key: expr => $value: expr ),* }) => {
+        ascii_case_insensitive_phf_map!($name -> $ValueType = { $( $key => $value, )* })
+    };
+    ($name: ident -> $ValueType: ty = { $( $key: expr => $value: expr, )* }) => {
+        fn $name(input: &str) -> Option<&'static $ValueType> {
+            cssparser_internal__invoke_proc_macro! {
+                cssparser_internal__phf_map!( ($ValueType) $( $key ($value) )+ )
+            }
+
+            {
+                cssparser_internal__invoke_proc_macro! {
+                    cssparser_internal__max_len!( $( $key )+ )
+                }
+                // MAX_LENGTH is generated by cssparser_internal__max_len
+                cssparser_internal__to_lowercase!(input, MAX_LENGTH => lowercase);
+                lowercase.and_then(|s| MAP.get(s))
+            }
+        }
+    }
+}
+
+/// Implementation detail of match_ignore_ascii_case! and ascii_case_insensitive_phf_map! macros.
+///
+/// **This macro is not part of the public API. It can change or be removed between any versions.**
+///
+/// Define a local variable named `$output`
+/// and assign it the result of calling `_internal__to_lowercase`
+/// with a stack-allocated buffer of length `$BUFFER_SIZE`.
+#[macro_export]
+#[doc(hidden)]
+macro_rules! cssparser_internal__to_lowercase {
+    ($input: expr, $BUFFER_SIZE: expr => $output: ident) => {
+        // mem::uninitialized() is ok because `buffer` is only used in `_internal__to_lowercase`,
+        // which initializes with `copy_from_slice` the part of the buffer it uses,
+        // before it uses it.
+        #[allow(unsafe_code)]
+        let mut buffer: [u8; $BUFFER_SIZE] = unsafe {
+            ::std::mem::uninitialized()
+        };
+        let input: &str = $input;
+        let $output = $crate::_internal__to_lowercase(&mut buffer, input);
+    }
+}
+
+/// Implementation detail of match_ignore_ascii_case! and ascii_case_insensitive_phf_map! macros.
+///
+/// **This function is not part of the public API. It can change or be removed between any verisons.**
+///
+/// If `input` is larger than buffer, return `None`.
+/// Otherwise, return `input` ASCII-lowercased, using `buffer` as temporary space if necessary.
+#[doc(hidden)]
+#[allow(non_snake_case)]
+pub fn _internal__to_lowercase<'a>(buffer: &'a mut [u8], input: &'a str) -> Option<&'a str> {
+    if let Some(buffer) = buffer.get_mut(..input.len()) {
+        if let Some(first_uppercase) = input.bytes().position(|byte| matches!(byte, b'A'...b'Z')) {
+            buffer.copy_from_slice(input.as_bytes());
+            ::std::ascii::AsciiExt::make_ascii_lowercase(&mut buffer[first_uppercase..]);
+            // `buffer` was initialized to a copy of `input` (which is &str so well-formed UTF-8)
+            // then lowercased (which preserves UTF-8 well-formedness)
+            unsafe {
+                Some(::std::str::from_utf8_unchecked(buffer))
+            }
+        } else {
+            // Input is already lower-case
+            Some(input)
+        }
+    } else {
+        // Input is longer than buffer, which has the length of the longest expected string:
+        // none of the expected strings would match.
+        None
+    }
+}
+
+#[cfg(feature = "dummy_match_byte")]
+macro_rules! match_byte {
+    ($value:expr, $($rest:tt)* ) => {
+        match $value {
+            $(
+                $rest
+            )+
+        }
+    };
+}
deleted file mode 100644
--- a/third_party/rust/cssparser/src/macros/mod.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-pub mod match_byte;
--- a/third_party/rust/cssparser/src/tests.rs
+++ b/third_party/rust/cssparser/src/tests.rs
@@ -812,8 +812,34 @@ fn one_component_value_to_json(token: To
         }),
         Token::BadUrl => JArray!["error", "bad-url"],
         Token::BadString => JArray!["error", "bad-string"],
         Token::CloseParenthesis => JArray!["error", ")"],
         Token::CloseSquareBracket => JArray!["error", "]"],
         Token::CloseCurlyBracket => JArray!["error", "}"],
     }
 }
+
+/// A previous version of procedural-masquerade had a bug where it
+/// would normalize consecutive whitespace to a single space,
+/// including in string literals.
+#[test]
+fn procedural_masquerade_whitespace() {
+    ascii_case_insensitive_phf_map! {
+        map -> () = {
+            "  \t\n" => ()
+        }
+    }
+    assert_eq!(map("  \t\n"), Some(&()));
+    assert_eq!(map(" "), None);
+
+    match_ignore_ascii_case! { "  \t\n",
+        " " => panic!("1"),
+        "  \t\n" => {},
+        _ => panic!("2"),
+    }
+
+    match_ignore_ascii_case! { " ",
+        "  \t\n" => panic!("3"),
+        " " => {},
+        _ => panic!("4"),
+    }
+}
--- a/third_party/rust/env_logger/.cargo-checksum.json
+++ b/third_party/rust/env_logger/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"909cbbdd1eb19266cfdb4074e02dbefde878656aa2ebfc8c65c58fba4b02c376","src/lib.rs":"484cec14a5f18a25b71d7b1842f7b184f0530165021b71b36dde9fc57b7fc15a","src/regex.rs":"d8e2a6958d4ed8084867063aae4b5c77ffc5d271dc2e17909d56c5a5e1552034","src/string.rs":"26ede9ab41a2673c3ad6001bc1802c005ce9a4f190f55860a24aa66b6b71bbc7","tests/regexp_filter.rs":"a3f9c01623e90e54b247a62c53b25caf5f502d054f28c0bdf92abbea486a95b5"},"package":"99971fb1b635fe7a0ee3c4d065845bb93cca80a23b5613b5613391ece5de4144"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"7e71042ee2dbb7e40f1f821cee50d83426eaf875fab8435315f60cf7d46cae75","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","src/lib.rs":"484cec14a5f18a25b71d7b1842f7b184f0530165021b71b36dde9fc57b7fc15a","src/regex.rs":"d8e2a6958d4ed8084867063aae4b5c77ffc5d271dc2e17909d56c5a5e1552034","src/string.rs":"26ede9ab41a2673c3ad6001bc1802c005ce9a4f190f55860a24aa66b6b71bbc7","tests/regexp_filter.rs":"a3f9c01623e90e54b247a62c53b25caf5f502d054f28c0bdf92abbea486a95b5"},"package":"ed39959122ea027670b704fb70539f4286ddf4a49eefede23bf0b4b2a069ec03"}
\ No newline at end of file
--- a/third_party/rust/env_logger/Cargo.toml
+++ b/third_party/rust/env_logger/Cargo.toml
@@ -1,11 +1,11 @@
 [package]
 name = "env_logger"
-version = "0.4.0"
+version = "0.4.1"
 authors = ["The Rust Project Developers"]
 license = "MIT/Apache-2.0"
 repository = "https://github.com/rust-lang/log"
 documentation = "http://doc.rust-lang.org/log/env_logger"
 homepage = "https://github.com/rust-lang/log"
 description = """
 A logging implementation for `log` which is configured via an environment
 variable.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/env_logger/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/env_logger/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.
--- a/third_party/rust/num-integer/.cargo-checksum.json
+++ b/third_party/rust/num-integer/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"be0aaf0c998d1913f40d901850f561ace784587152bfa23ebb14ed781774307a","src/lib.rs":"0bc63c3c812abf24179b104306a2a5b87329752269cc4d76570ed3c273f1baa7"},"package":"fb24d9bfb3f222010df27995441ded1e954f8f69cd35021f6bef02ca9552fb92"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"69c84ad73d7c646a1ef4672b6d8f958c5f18d43e43c17b902f1198f9fed4ae5e","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","src/lib.rs":"c49cb1f2c2c5b414d28556ba7076d0243fe73378dd3a3ae97d29b3b4dc060a58"},"package":"21e4df1098d1d797d27ef0c69c178c3fab64941559b290fcae198e0825c9c8b5"}
\ No newline at end of file
--- a/third_party/rust/num-integer/Cargo.toml
+++ b/third_party/rust/num-integer/Cargo.toml
@@ -2,13 +2,13 @@
 authors = ["The Rust Project Developers"]
 description = "Integer traits and functions"
 documentation = "http://rust-num.github.io/num"
 homepage = "https://github.com/rust-num/num"
 keywords = ["mathematics", "numerics"]
 license = "MIT/Apache-2.0"
 repository = "https://github.com/rust-num/num"
 name = "num-integer"
-version = "0.1.32"
+version = "0.1.33"
 
 [dependencies.num-traits]
 path = "../traits"
 version = "0.1.32"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/num-integer/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/num-integer/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.
--- a/third_party/rust/num-integer/src/lib.rs
+++ b/third_party/rust/num-integer/src/lib.rs
@@ -4,16 +4,20 @@
 //
 // 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.
 
 //! Integer trait and functions.
+#![doc(html_logo_url = "https://rust-num.github.io/num/rust-logo-128x128-blk-v2.png",
+       html_favicon_url = "https://rust-num.github.io/num/favicon.ico",
+       html_root_url = "https://rust-num.github.io/num/",
+       html_playground_url = "http://play.integer32.com/")]
 
 extern crate num_traits as traits;
 
 use traits::{Num, Signed};
 
 pub trait Integer: Sized + Num + PartialOrd + Ord + Eq {
     /// Floored integer division.
     ///
--- a/third_party/rust/num-traits/.cargo-checksum.json
+++ b/third_party/rust/num-traits/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"3befa332314f31a68e226930e393fd79b0215fab661519f3163b04ef6fbccaac","src/bounds.rs":"32f69f86640520478eff7978951a6d2dc0d51fe263782970185fb31ffcc4a9e1","src/cast.rs":"d76053ff336eadb80a18725c174226b4be147b876c6aa70d7aa81a16d85e9f25","src/float.rs":"1f9d571bd3946d1d93dc7f4f4ae344bfabf5fd871243145aad120e242599c2e4","src/identities.rs":"188c63de57997fb8468732251a3a8d7f665b8f61d512222c2553baefe1c827bb","src/int.rs":"8ef622da766cb69586981e5eb5bd6c608ce9db0e345aeb34347023730561cb87","src/lib.rs":"3e56bafef9c32e10ff8d70241f64a0d811cd6dfc8f57924c094d1735f32fc3b2","src/ops/checked.rs":"f02fd815b99edf079043d3621c1566e0ab3e755fe284d0b8fdf5d7ca56d546e7","src/ops/mod.rs":"2ed0ec81f58958665f251348fa670375ab863a628182a2dec20308b249a8087a","src/ops/saturating.rs":"46821d815c90c16b2f6bec0b94b4d7ebdbddf3ea42edc0467de738c56abf6436","src/pow.rs":"73b611ad8d595ef917871ba859ff0c25efc2382220d30568e5fbb930bf6b4daa","src/sign.rs":"c08ad1647d393571cc73344b174b1764d7d7d5fb57170cc8f1d26e7ab9527e7c"},"package":"a16a42856a256b39c6d3484f097f6713e14feacd9bfb02290917904fae46c81c"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"c1f571e6884f2643c11053465800afe4056253687fd332e7a9c2d32fb30704ed","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","src/bounds.rs":"32f69f86640520478eff7978951a6d2dc0d51fe263782970185fb31ffcc4a9e1","src/cast.rs":"d76053ff336eadb80a18725c174226b4be147b876c6aa70d7aa81a16d85e9f25","src/float.rs":"1f9d571bd3946d1d93dc7f4f4ae344bfabf5fd871243145aad120e242599c2e4","src/identities.rs":"188c63de57997fb8468732251a3a8d7f665b8f61d512222c2553baefe1c827bb","src/int.rs":"b7b42dfa10423308f858216ac63fa52e26c49a7bc8900cd98de210992efc3f5f","src/lib.rs":"f99d825e652698d9b39b1e26132139542e12e968d87cf804d46e95ec0c21f14f","src/ops/checked.rs":"f02fd815b99edf079043d3621c1566e0ab3e755fe284d0b8fdf5d7ca56d546e7","src/ops/mod.rs":"668ea4d117bc1fdf7eaf0fe16692fa40dfbdfcbc7a2010237fe395ce0086e02e","src/ops/saturating.rs":"46821d815c90c16b2f6bec0b94b4d7ebdbddf3ea42edc0467de738c56abf6436","src/ops/wrapping.rs":"aa750486640063fad24175fd3b622eba2d4453d4de5a3d8bc93e1c3f50ced485","src/pow.rs":"73b611ad8d595ef917871ba859ff0c25efc2382220d30568e5fbb930bf6b4daa","src/sign.rs":"c08ad1647d393571cc73344b174b1764d7d7d5fb57170cc8f1d26e7ab9527e7c"},"package":"e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99"}
\ No newline at end of file
--- a/third_party/rust/num-traits/Cargo.toml
+++ b/third_party/rust/num-traits/Cargo.toml
@@ -2,11 +2,11 @@
 authors = ["The Rust Project Developers"]
 description = "Numeric traits for generic mathematics"
 documentation = "http://rust-num.github.io/num"
 homepage = "https://github.com/rust-num/num"
 keywords = ["mathematics", "numerics"]
 license = "MIT/Apache-2.0"
 repository = "https://github.com/rust-num/num"
 name = "num-traits"
-version = "0.1.36"
+version = "0.1.37"
 
 [dependencies]
new file mode 100644
--- /dev/null
+++ b/third_party/rust/num-traits/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/num-traits/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.
--- a/third_party/rust/num-traits/src/int.rs
+++ b/third_party/rust/num-traits/src/int.rs
@@ -269,17 +269,17 @@ pub trait PrimInt
     ///
     /// # Examples
     ///
     /// ```
     /// use num_traits::PrimInt;
     ///
     /// assert_eq!(2i32.pow(4), 16);
     /// ```
-    fn pow(self, mut exp: u32) -> Self;
+    fn pow(self, exp: u32) -> Self;
 }
 
 macro_rules! prim_int_impl {
     ($T:ty, $S:ty, $U:ty) => (
         impl PrimInt for $T {
             #[inline]
             fn count_ones(self) -> u32 {
                 <$T>::count_ones(self)
--- a/third_party/rust/num-traits/src/lib.rs
+++ b/third_party/rust/num-traits/src/lib.rs
@@ -4,23 +4,28 @@
 //
 // 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.
 
 //! Numeric traits for generic mathematics
+#![doc(html_logo_url = "https://rust-num.github.io/num/rust-logo-128x128-blk-v2.png",
+       html_favicon_url = "https://rust-num.github.io/num/favicon.ico",
+       html_root_url = "https://rust-num.github.io/num/",
+       html_playground_url = "http://play.integer32.com/")]
 
 use std::ops::{Add, Sub, Mul, Div, Rem};
 
 pub use bounds::Bounded;
 pub use float::{Float, FloatConst};
 pub use identities::{Zero, One, zero, one};
 pub use ops::checked::*;
+pub use ops::wrapping::*;
 pub use ops::saturating::Saturating;
 pub use sign::{Signed, Unsigned, abs, abs_sub, signum};
 pub use cast::*;
 pub use int::PrimInt;
 pub use pow::{pow, checked_pow};
 
 pub mod identities;
 pub mod sign;
@@ -34,16 +39,28 @@ pub mod pow;
 /// The base trait for numeric types
 pub trait Num: PartialEq + Zero + One
     + Add<Output = Self> + Sub<Output = Self>
     + Mul<Output = Self> + Div<Output = Self> + Rem<Output = Self>
 {
     type FromStrRadixErr;
 
     /// Convert from a string and radix <= 36.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use num_traits::Num;
+    ///
+    /// let result = <i32 as Num>::from_str_radix("27", 10);
+    /// assert_eq!(result, Ok(27));
+    ///
+    /// let result = <i32 as Num>::from_str_radix("foo", 10);
+    /// assert!(result.is_err());
+    /// ```
     fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr>;
 }
 
 macro_rules! int_trait_impl {
     ($name:ident for $($t:ty)*) => ($(
         impl $name for $t {
             type FromStrRadixErr = ::std::num::ParseIntError;
             #[inline]
@@ -219,16 +236,46 @@ macro_rules! float_trait_impl {
 
                 Ok(sig * exp)
             }
         }
     )*)
 }
 float_trait_impl!(Num for f32 f64);
 
+/// A value bounded by a minimum and a maximum
+///
+///  If input is less than min then this returns min. 
+///  If input is greater than max then this returns max.  
+///  Otherwise this returns input. 
+#[inline]
+pub fn clamp<T: PartialOrd>(input: T, min: T, max: T) -> T {
+    debug_assert!(min <= max, "min must be less than or equal to max");
+    if input < min {
+        min
+    } else if input > max {
+        max
+    } else {
+        input
+    }
+}
+
+#[test]
+fn clamp_test() {
+    // Int test
+    assert_eq!(1, clamp(1, -1, 2));
+    assert_eq!(-1, clamp(-2, -1, 2));
+    assert_eq!(2, clamp(3, -1, 2));
+
+    // Float test
+    assert_eq!(1.0, clamp(1.0, -1.0, 2.0));
+    assert_eq!(-1.0, clamp(-2.0, -1.0, 2.0));
+    assert_eq!(2.0, clamp(3.0, -1.0, 2.0));
+}
+
 #[test]
 fn from_str_radix_unwrap() {
     // The Result error must impl Debug to allow unwrap()
 
     let i: i32 = Num::from_str_radix("0", 10).unwrap();
     assert_eq!(i, 0);
 
     let f: f32 = Num::from_str_radix("0.0", 10).unwrap();
--- a/third_party/rust/num-traits/src/ops/mod.rs
+++ b/third_party/rust/num-traits/src/ops/mod.rs
@@ -1,2 +1,3 @@
 pub mod saturating;
 pub mod checked;
+pub mod wrapping;
new file mode 100644
--- /dev/null
+++ b/third_party/rust/num-traits/src/ops/wrapping.rs
@@ -0,0 +1,88 @@
+use std::ops::{Add, Sub, Mul};
+
+macro_rules! wrapping_impl {
+    ($trait_name:ident, $method:ident, $t:ty) => {
+        impl $trait_name for $t {
+            #[inline]
+            fn $method(&self, v: &Self) -> Self {
+                <$t>::$method(*self, *v)
+            }
+        }
+    };
+    ($trait_name:ident, $method:ident, $t:ty, $rhs:ty) => {
+        impl $trait_name<$rhs> for $t {
+            #[inline]
+            fn $method(&self, v: &$rhs) -> Self {
+                <$t>::$method(*self, *v)
+            }
+        }
+    }
+}
+
+/// Performs addition that wraps around on overflow.
+pub trait WrappingAdd: Sized + Add<Self, Output=Self> {
+    /// Wrapping (modular) addition. Computes `self + other`, wrapping around at the boundary of
+    /// the type.
+    fn wrapping_add(&self, v: &Self) -> Self;
+}
+
+wrapping_impl!(WrappingAdd, wrapping_add, u8);
+wrapping_impl!(WrappingAdd, wrapping_add, u16);
+wrapping_impl!(WrappingAdd, wrapping_add, u32);
+wrapping_impl!(WrappingAdd, wrapping_add, u64);
+wrapping_impl!(WrappingAdd, wrapping_add, usize);
+
+wrapping_impl!(WrappingAdd, wrapping_add, i8);
+wrapping_impl!(WrappingAdd, wrapping_add, i16);
+wrapping_impl!(WrappingAdd, wrapping_add, i32);
+wrapping_impl!(WrappingAdd, wrapping_add, i64);
+wrapping_impl!(WrappingAdd, wrapping_add, isize);
+
+/// Performs subtraction that wraps around on overflow.
+pub trait WrappingSub: Sized + Sub<Self, Output=Self> {
+    /// Wrapping (modular) subtraction. Computes `self - other`, wrapping around at the boundary
+    /// of the type.
+    fn wrapping_sub(&self, v: &Self) -> Self;
+}
+
+wrapping_impl!(WrappingSub, wrapping_sub, u8);
+wrapping_impl!(WrappingSub, wrapping_sub, u16);
+wrapping_impl!(WrappingSub, wrapping_sub, u32);
+wrapping_impl!(WrappingSub, wrapping_sub, u64);
+wrapping_impl!(WrappingSub, wrapping_sub, usize);
+
+wrapping_impl!(WrappingSub, wrapping_sub, i8);
+wrapping_impl!(WrappingSub, wrapping_sub, i16);
+wrapping_impl!(WrappingSub, wrapping_sub, i32);
+wrapping_impl!(WrappingSub, wrapping_sub, i64);
+wrapping_impl!(WrappingSub, wrapping_sub, isize);
+
+/// Performs multiplication that wraps around on overflow.
+pub trait WrappingMul: Sized + Mul<Self, Output=Self> {
+    /// Wrapping (modular) multiplication. Computes `self * other`, wrapping around at the boundary
+    /// of the type.
+    fn wrapping_mul(&self, v: &Self) -> Self;
+}
+
+wrapping_impl!(WrappingMul, wrapping_mul, u8);
+wrapping_impl!(WrappingMul, wrapping_mul, u16);
+wrapping_impl!(WrappingMul, wrapping_mul, u32);
+wrapping_impl!(WrappingMul, wrapping_mul, u64);
+wrapping_impl!(WrappingMul, wrapping_mul, usize);
+
+wrapping_impl!(WrappingMul, wrapping_mul, i8);
+wrapping_impl!(WrappingMul, wrapping_mul, i16);
+wrapping_impl!(WrappingMul, wrapping_mul, i32);
+wrapping_impl!(WrappingMul, wrapping_mul, i64);
+wrapping_impl!(WrappingMul, wrapping_mul, isize);
+
+
+#[test]
+fn test_wrapping_traits() {
+    fn wrapping_add<T: WrappingAdd>(a: T, b: T) -> T { a.wrapping_add(&b) }
+    fn wrapping_sub<T: WrappingSub>(a: T, b: T) -> T { a.wrapping_sub(&b) }
+    fn wrapping_mul<T: WrappingMul>(a: T, b: T) -> T { a.wrapping_mul(&b) }
+    assert_eq!(wrapping_add(255, 1), 0u8);
+    assert_eq!(wrapping_sub(0, 1), 255u8);
+    assert_eq!(wrapping_mul(255, 2), 254u8);
+}
--- a/third_party/rust/parking_lot/.cargo-checksum.json
+++ b/third_party/rust/parking_lot/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"f9b1ca6ae27d1c18215265024629a8960c31379f206d9ed20f64e0b2dcf79805",".travis.yml":"9b39b9d42d077d028d5742450256c9f11f3456ff185ce2a987f4606b152bf440","Cargo.toml":"3324e491e6872435e4131dbe8312c3ffeff4a1c7c29814da3de796a8d34025e5","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"c9a75f18b9ab2927829a208fc6aa2cf4e63b8420887ba29cdb265d6619ae82d5","README.md":"d7bb9d24f29da05ef02c232f6354c01a93a8205f55d137f8b7d7a74f88163994","appveyor.yml":"1181ecde6a5df38051107a3ef4051751499f5a462ed761c1eafd6d4c62fde73e","src/condvar.rs":"227cd171d14ee54b115a5d1bff38ac4a01460ca2d85a40773b08035b6f39e94e","src/elision.rs":"0fef04d2991afeabafb041e81afeec74e89095d0eca49e5516bdcd5bc90c086f","src/lib.rs":"50951210148941266ce3a7d4017c339f8ad4419a9a8db6f915023890ed27d638","src/mutex.rs":"956b58465f78ac97d8ecf4dda7bbd973998cb29c4057f51cc3d8c8bdfa47f460","src/once.rs":"dee225c5472d152ed820eb90a3dcb96f7af409d8315f006b2179fa3f350de4ed","src/raw_mutex.rs":"225cbf0ef951be062866da674e5eea8245fcc43ecd8a26da7097dea03b770bf5","src/raw_remutex.rs":"a451cc3ce7bf11bc94777148b81d39b07b5a2a2fc698f6db2ca2fc765b158fa8","src/raw_rwlock.rs":"f7a206d0d401dae475d42f06d8a8fe6d8f2ca986b60633aaa4d3d588a997793e","src/remutex.rs":"a5cefa1a97e4669e3b2dffa9007988e6a6088500472d9eefea1a28ed1443e1b0","src/rwlock.rs":"9bdafa8eabc0b6720deed380799db1c1219f5344933437196f67332a6d9e1740","src/stable.rs":"cc18c58404dc6017924d88fb9f4ed94e5320b8cb0a36985162b23130b8cd7480","src/util.rs":"2d07c0c010a857790ae2ed6a1215eeed8af76859e076797ea1ba8dec82169e84"},"package":"3771b463ebf30418ef54378e647d01cc33123b2e7a4958b1cec284edc71054f6"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"f9b1ca6ae27d1c18215265024629a8960c31379f206d9ed20f64e0b2dcf79805",".travis.yml":"9b39b9d42d077d028d5742450256c9f11f3456ff185ce2a987f4606b152bf440","Cargo.toml":"8a0938f1fd49ceae700f27333cdacd754d7b2205664265de4bd67be3d37a9525","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"c9a75f18b9ab2927829a208fc6aa2cf4e63b8420887ba29cdb265d6619ae82d5","README.md":"d7bb9d24f29da05ef02c232f6354c01a93a8205f55d137f8b7d7a74f88163994","appveyor.yml":"1181ecde6a5df38051107a3ef4051751499f5a462ed761c1eafd6d4c62fde73e","src/condvar.rs":"227cd171d14ee54b115a5d1bff38ac4a01460ca2d85a40773b08035b6f39e94e","src/elision.rs":"0fef04d2991afeabafb041e81afeec74e89095d0eca49e5516bdcd5bc90c086f","src/lib.rs":"50951210148941266ce3a7d4017c339f8ad4419a9a8db6f915023890ed27d638","src/mutex.rs":"956b58465f78ac97d8ecf4dda7bbd973998cb29c4057f51cc3d8c8bdfa47f460","src/once.rs":"dee225c5472d152ed820eb90a3dcb96f7af409d8315f006b2179fa3f350de4ed","src/raw_mutex.rs":"225cbf0ef951be062866da674e5eea8245fcc43ecd8a26da7097dea03b770bf5","src/raw_remutex.rs":"a451cc3ce7bf11bc94777148b81d39b07b5a2a2fc698f6db2ca2fc765b158fa8","src/raw_rwlock.rs":"f7a206d0d401dae475d42f06d8a8fe6d8f2ca986b60633aaa4d3d588a997793e","src/remutex.rs":"a5cefa1a97e4669e3b2dffa9007988e6a6088500472d9eefea1a28ed1443e1b0","src/rwlock.rs":"3de0dded88f3dd339e962aba1cc778a03d5a10ac743325a81859617c455c31d3","src/stable.rs":"cc18c58404dc6017924d88fb9f4ed94e5320b8cb0a36985162b23130b8cd7480","src/util.rs":"2d07c0c010a857790ae2ed6a1215eeed8af76859e076797ea1ba8dec82169e84"},"package":"fa12d706797d42551663426a45e2db2e0364bd1dbf6aeada87e89c5f981f43e9"}
\ No newline at end of file
--- a/third_party/rust/parking_lot/Cargo.toml
+++ b/third_party/rust/parking_lot/Cargo.toml
@@ -1,11 +1,11 @@
 [package]
 name = "parking_lot"
-version = "0.3.7"
+version = "0.3.8"
 authors = ["Amanieu d'Antras <amanieu@gmail.com>"]
 description = "More compact and efficient implementations of the standard synchronization primitives."
 documentation = "https://amanieu.github.io/parking_lot/parking_lot/index.html"
 license = "Apache-2.0/MIT"
 repository = "https://github.com/Amanieu/parking_lot"
 readme = "README.md"
 keywords = ["mutex", "condvar", "rwlock", "once", "thread"]
 
--- a/third_party/rust/parking_lot/src/rwlock.rs
+++ b/third_party/rust/parking_lot/src/rwlock.rs
@@ -373,16 +373,32 @@ impl<T: ?Sized> RwLock<T> {
     /// This function must only be called if the rwlock was locked using
     /// `raw_write` or `raw_try_write`, or if an `RwLockWriteGuard` from this
     /// rwlock was leaked (e.g. with `mem::forget`). The rwlock must be locked
     /// with exclusive write access.
     #[inline]
     pub unsafe fn raw_unlock_write_fair(&self) {
         self.raw.unlock_exclusive(true);
     }
+
+    /// Atomically downgrades a write lock into a read lock without allowing any
+    /// writers to take exclusive access of the lock in the meantime.
+    ///
+    /// See `RwLockWriteGuard::downgrade`.
+    ///
+    /// # Safety
+    ///
+    /// This function must only be called if the rwlock was locked using
+    /// `raw_write` or `raw_try_write`, or if an `RwLockWriteGuard` from this
+    /// rwlock was leaked (e.g. with `mem::forget`). The rwlock must be locked
+    /// with exclusive write access.
+    #[inline]
+    pub unsafe fn raw_downgrade(&self) {
+        self.raw.downgrade();
+    }
 }
 
 impl RwLock<()> {
     /// Locks this rwlock with shared read access, blocking the current thread
     /// until it can be acquired.
     ///
     /// This is similar to `read`, except that a `RwLockReadGuard` is not
     /// returned. Instead you will need to call `raw_unlock` to release the
--- a/third_party/rust/pdqsort/.cargo-checksum.json
+++ b/third_party/rust/pdqsort/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"f9b1ca6ae27d1c18215265024629a8960c31379f206d9ed20f64e0b2dcf79805",".travis.yml":"85e71e3082a4d00de52505b07957cca71718d9a1cc531f66d77ad8f54dd190a2","Cargo.toml":"40c50f26b3d9369da246b6f7be656afe86cbc80940bb8ba1f16fd5971bd20213","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0621878e61f0d0fda054bcbe02df75192c28bde1ecc8289cbd86aeba2dd72720","README.md":"1f81d0b3d68ae7fde22059e956541697e053dc335177013fe8c367210fff77d0","benches/bench.rs":"11adfc56ff91ddaf780a46ef45ed359c06d4086ce7787951bbb8dbfd9b11898f","src/lib.rs":"abc5f8a647f046f3d002901be4d2f365549a603a5f218bc374184a5ca26c109c"},"package":"9b488405652f1d330f26e3112a477b12b49a70589372cb50aea2e29ebeb5ba54"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"f9b1ca6ae27d1c18215265024629a8960c31379f206d9ed20f64e0b2dcf79805",".travis.yml":"85e71e3082a4d00de52505b07957cca71718d9a1cc531f66d77ad8f54dd190a2","Cargo.toml":"72b56d640b72470dedf71dead0d4ceda51ec82ac048dea9a97ab6be440eb41a9","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0621878e61f0d0fda054bcbe02df75192c28bde1ecc8289cbd86aeba2dd72720","README.md":"795851777c3d915da30f2b11b21f478fb46f793170321b1ffa64b6eb27d93127","benches/bench.rs":"4e5e084d25ce4fe5824e653438249206278f3f428c4c2bfb96f98ad8622dfa5e","src/lib.rs":"c3a7cff009a399f1d180b23daaf483798021a117a352c81704dd8ff470ba9f16"},"package":"ceca1642c89148ca05611cc775a0c383abef355fc4907c4e95f49f7b09d6287c"}
\ No newline at end of file
--- a/third_party/rust/pdqsort/Cargo.toml
+++ b/third_party/rust/pdqsort/Cargo.toml
@@ -1,11 +1,11 @@
 [package]
 name = "pdqsort"
-version = "0.1.1"
+version = "0.1.2"
 authors = ["Stjepan Glavina <stjepang@gmail.com>"]
 description = "Pattern-defeating quicksort"
 repository = "https://github.com/stjepang/pdqsort"
 documentation = "https://docs.rs/pdqsort"
 readme = "README.md"
 license = "Apache-2.0/MIT"
 keywords = ["sort", "sorting", "no_std", "quicksort", "introsort"]
 categories = ["algorithms"]
--- a/third_party/rust/pdqsort/README.md
+++ b/third_party/rust/pdqsort/README.md
@@ -1,20 +1,20 @@
 # Pattern-defeating quicksort
 
 [![Build Status](https://travis-ci.org/stjepang/pdqsort.svg?branch=master)](https://travis-ci.org/stjepang/pdqsort)
 [![License](https://img.shields.io/badge/license-Apache--2.0%2FMIT-blue.svg)](https://github.com/stjepang/pdqsort)
 [![Cargo](https://img.shields.io/crates/v/pdqsort.svg)](https://crates.io/crates/pdqsort)
 [![Documentation](https://docs.rs/pdqsort/badge.svg)](https://docs.rs/pdqsort)
 
 This sort is significantly faster than the standard sort in Rust. In particular, it sorts
-random arrays of integers approximately 40% faster. The key drawback is that it is an unstable
+random arrays of integers approximately 45% faster. The key drawback is that it is an unstable
 sort (i.e. may reorder equal elements). However, in most cases stability doesn't matter anyway.
 
-The algorithm was designed by Orson Peters and first published at: https://github.com/orlp/pdqsort
+The algorithm is based on pdqsort by Orson Peters, published at: https://github.com/orlp/pdqsort
 
 #### Properties
 
 * Best-case running time is `O(n)`.
 * Worst-case running time is `O(n log n)`.
 * Unstable, i.e. may reorder equal elements.
 * Does not allocate additional memory.
 * Uses `#![no_std]`.
@@ -37,27 +37,29 @@ assert!(v == [1, 2, -3, 4, -5]);
 ```
 
 #### A simple benchmark
 
 Sorting 10 million random numbers of type `u64`:
 
 | Sort              | Time       |
 |-------------------|-----------:|
-| pdqsort           | **396 ms** |
+| pdqsort           | **370 ms** |
 | slice::sort       |     668 ms |
 | [quickersort][qs] |     777 ms |
 | [dmsort][ds]      |     728 ms |
 | [rdxsort][rs]     |     602 ms |
 
 #### Extensive benchmarks
 
-The benchmarks that follow are [used in Rust][bench] for testing the performance of slice::sort.
+The following benchmarks are [used in Rust][bench] for testing the performance of slice::sort.
 
-| Benchmark               | pdqsort       | slice::sort   | [quickersort][qs] | [dmsort][ds] | [rdxsort][rs] |
+*Note: The numbers for dmsort are outdated.*
+
+| Benchmark               | pdqsort       | slice::sort   | [quickersort][qs] | ~~[dmsort][ds]~~ | [rdxsort][rs] |
 |-------------------------|--------------:|--------------:|------------------:|-------------:|--------------:|
 | large_ascending         |         11 us |      **9 us** |             12 us |        22 us |        358 us |
 | large_descending        |     **14 us** |     **14 us** |             46 us |       144 us |        347 us |
 | large_random            |    **342 us** |        509 us |            534 us |       544 us |        399 us |
 | large_random_expensive  |         63 ms |     **24 ms** |                -  |        31 ms |            -  |
 | large_mostly_ascending  |         82 us |        239 us |            129 us |    **45 us** |        353 us |
 | large_mostly_descending |     **93 us** |        267 us |            135 us |       282 us |        349 us |
 | large_big_ascending     |        375 us |    **370 us** |            374 us |       412 us |     49,597 us |
--- a/third_party/rust/pdqsort/benches/bench.rs
+++ b/third_party/rust/pdqsort/benches/bench.rs
@@ -87,23 +87,21 @@ sort_bench!(sort_large_mostly_descending
 sort_bench!(sort_large_big_random, gen_big_random, 10000);
 sort_bench!(sort_large_big_ascending, gen_big_ascending, 10000);
 sort_bench!(sort_large_big_descending, gen_big_descending, 10000);
 
 #[bench]
 fn sort_large_random_expensive(b: &mut Bencher) {
     let len = 10000;
     b.iter(|| {
+        let mut v = gen_random(len);
         let mut count = 0;
-        let mut cmp = move |a: &u64, b: &u64| {
+        pdqsort::sort_by(&mut v, |a: &u64, b: &u64| {
             count += 1;
             if count % 1_000_000_000 == 0 {
                 panic!("should not happen");
             }
             (*a as f64).cos().partial_cmp(&(*b as f64).cos()).unwrap()
-        };
-
-        let mut v = gen_random(len);
-        pdqsort::sort_by(&mut v, &mut cmp);
+        });
         test::black_box(count);
     });
     b.bytes = len as u64 * mem::size_of::<u64>() as u64;
 }
--- a/third_party/rust/pdqsort/src/lib.rs
+++ b/third_party/rust/pdqsort/src/lib.rs
@@ -1,21 +1,15 @@
 //! Pattern-defeating quicksort.
 //!
 //! This sort is significantly faster than the standard sort in Rust. In particular, it sorts
-//! random arrays of integers approximately 40% faster. The key drawback is that it is an unstable
+//! random arrays of integers approximately 45% faster. The key drawback is that it is an unstable
 //! sort (i.e. may reorder equal elements). However, in most cases stability doesn't matter anyway.
 //!
-//! The algorithm was designed by Orson Peters and first published at:
-//! https://github.com/orlp/pdqsort
-//!
-//! Quoting it's designer: "Pattern-defeating quicksort (pdqsort) is a novel sorting algorithm
-//! that combines the fast average case of randomized quicksort with the fast worst case of
-//! heapsort, while achieving linear time on inputs with certain patterns. pdqsort is an extension
-//! and improvement of David Musser's introsort."
+//! The algorithm is based on pdqsort by Orson Peters, published at: https://github.com/orlp/pdqsort
 //!
 //! # Properties
 //!
 //! - Best-case running time is `O(n)`.
 //! - Worst-case running time is `O(n log n)`.
 //! - Unstable, i.e. may reorder equal elements.
 //! - Does not allocate additional memory.
 //! - Uses `#![no_std]`.
@@ -38,17 +32,17 @@
 //! ```
 
 #![no_std]
 
 use core::cmp::{self, Ordering};
 use core::mem;
 use core::ptr;
 
-/// On drop, takes the value out of `Option` and writes it into `dest`.
+/// When dropped, takes the value out of `Option` and writes it into `dest`.
 ///
 /// This allows us to safely read the pivot into a stack-allocated variable for efficiency, and
 /// write it back into the slice after partitioning. This way we ensure that the write happens
 /// even if `is_less` panics in the meantime.
 struct WriteOnDrop<T> {
     value: Option<T>,
     dest: *mut T,
 }
@@ -56,65 +50,68 @@ struct WriteOnDrop<T> {
 impl<T> Drop for WriteOnDrop<T> {
     fn drop(&mut self) {
         unsafe {
             ptr::write(self.dest, self.value.take().unwrap());
         }
     }
 }
 
-/// Inserts `v[0]` into pre-sorted sequence `v[1..]` so that whole `v[..]` becomes sorted.
-///
-/// This is the integral subroutine of insertion sort.
-fn insert_head<T, F>(v: &mut [T], is_less: &mut F)
+/// Sorts a slice using insertion sort, which is `O(n^2)` worst-case.
+fn insertion_sort<T, F>(v: &mut [T], is_less: &mut F)
     where F: FnMut(&T, &T) -> bool
 {
-    if v.len() >= 2 && is_less(&v[1], &v[0]) {
-        unsafe {
-            // There are three ways to implement insertion here:
-            //
-            // 1. Swap adjacent elements until the first one gets to its final destination.
-            //    However, this way we copy data around more than is necessary. If elements are big
-            //    structures (costly to copy), this method will be slow.
-            //
-            // 2. Iterate until the right place for the first element is found. Then shift the
-            //    elements succeeding it to make room for it and finally place it into the
-            //    remaining hole. This is a good method.
-            //
-            // 3. Copy the first element into a temporary variable. Iterate until the right place
-            //    for it is found. As we go along, copy every traversed element into the slot
-            //    preceding it. Finally, copy data from the temporary variable into the remaining
-            //    hole. This method is very good. Benchmarks demonstrated slightly better
-            //    performance than with the 2nd method.
-            //
-            // All methods were benchmarked, and the 3rd showed best results. So we chose that one.
-            let mut tmp = NoDrop { value: Some(ptr::read(&v[0])) };
+    let len = v.len();
 
-            // Intermediate state of the insertion process is always tracked by `hole`, which
-            // serves two purposes:
-            // 1. Protects integrity of `v` from panics in `is_less`.
-            // 2. Fills the remaining hole in `v` in the end.
-            //
-            // Panic safety:
-            //
-            // If `is_less` panics at any point during the process, `hole` will get dropped and
-            // fill the hole in `v` with `tmp`, thus ensuring that `v` still holds every object it
-            // initially held exactly once.
-            let mut hole = InsertionHole {
-                src: tmp.value.as_mut().unwrap(),
-                dest: &mut v[1],
-            };
-            ptr::copy_nonoverlapping(&v[1], &mut v[0], 1);
+    for i in 1..len {
+        unsafe {
+            if is_less(v.get_unchecked(i), v.get_unchecked(i - 1)) {
+                // There are three ways to implement insertion here:
+                //
+                // 1. Swap adjacent elements until the first one gets to its final destination.
+                //    However, this way we copy data around more than is necessary. If elements are
+                //    big structures (costly to copy), this method will be slow.
+                //
+                // 2. Iterate until the right place for the first element is found. Then shift the
+                //    elements succeeding it to make room for it and finally place it into the
+                //    remaining hole. This is a good method.
+                //
+                // 3. Copy the first element into a temporary variable. Iterate until the right
+                //    place for it is found. As we go along, copy every traversed element into the
+                //    slot preceding it. Finally, copy data from the temporary variable into the
+                //    remaining hole. This method is very good. Benchmarks demonstrated slightly
+                //    better performance than with the 2nd method.
+                //
+                // All methods were benchmarked, and the 3rd showed best results. So we chose that
+                // one.
+                let mut tmp = NoDrop { value: Some(ptr::read(v.get_unchecked(i))) };
 
-            for i in 2..v.len() {
-                if !is_less(&v[i], &tmp.value.as_ref().unwrap()) {
-                    break;
+                // Intermediate state of the insertion process is always tracked by `hole`, which
+                // serves two purposes:
+                // 1. Protects integrity of `v` from panics in `is_less`.
+                // 2. Fills the remaining hole in `v` in the end.
+                //
+                // Panic safety:
+                //
+                // If `is_less` panics at any point during the process, `hole` will get dropped and
+                // fill the hole in `v` with `tmp`, thus ensuring that `v` still holds every object
+                // it initially held exactly once.
+                let mut hole = InsertionHole {
+                    src: tmp.value.as_mut().unwrap(),
+                    dest: v.get_unchecked_mut(i - 1),
+                };
+                ptr::copy_nonoverlapping(v.get_unchecked(i - 1), v.get_unchecked_mut(i), 1);
+
+                for j in (0..i-1).rev() {
+                    if !is_less(&tmp.value.as_ref().unwrap(), v.get_unchecked(j)) {
+                        break;
+                    }
+                    ptr::copy_nonoverlapping(v.get_unchecked(j), v.get_unchecked_mut(j + 1), 1);
+                    hole.dest = v.get_unchecked_mut(j);
                 }
-                ptr::copy_nonoverlapping(&v[i], &mut v[i - 1], 1);
-                hole.dest = &mut v[i];
             }
             // `hole` gets dropped and thus copies `tmp` into the remaining hole in `v`.
         }
     }
 
     // Holds a value, but never drops it.
     struct NoDrop<T> {
         value: Option<T>,
@@ -134,28 +131,16 @@ fn insert_head<T, F>(v: &mut [T], is_les
 
     impl<T> Drop for InsertionHole<T> {
         fn drop(&mut self) {
             unsafe { ptr::copy_nonoverlapping(self.src, self.dest, 1); }
         }
     }
 }
 
-/// Sorts a slice using insertion sort, which is `O(n^2)` worst-case.
-fn insertion_sort<T, F>(v: &mut [T], is_less: &mut F)
-    where F: FnMut(&T, &T) -> bool
-{
-    let len = v.len();
-    if len >= 2 {
-        for i in (0..len-1).rev() {
-            insert_head(&mut v[i..], is_less);
-        }
-    }
-}
-
 /// Sorts `v` using heapsort, which guarantees `O(n log n)` worst-case.
 #[cold]
 fn heapsort<T, F>(v: &mut [T], is_less: &mut F)
     where F: FnMut(&T, &T) -> bool
 {
     // This binary heap respects the invariant `parent >= child`.
     let mut sift_down = |v: &mut [T], mut node| {
         loop {
@@ -198,17 +183,17 @@ fn heapsort<T, F>(v: &mut [T], is_less: 
 ///
 /// Partitioning is performed block-by-block in order to minimize the cost of branching operations.
 /// This idea is presented in the [BlockQuicksort][pdf] paper.
 ///
 /// [pdf]: http://drops.dagstuhl.de/opus/volltexte/2016/6389/pdf/LIPIcs-ESA-2016-38.pdf
 fn partition_in_blocks<T, F>(v: &mut [T], pivot: &T, is_less: &mut F) -> usize
     where F: FnMut(&T, &T) -> bool
 {
-    const BLOCK: usize = 64;
+    const BLOCK: usize = 128;
 
     // State on the left side.
     let mut l = v.as_mut_ptr();
     let mut block_l = BLOCK;
     let mut start_l = ptr::null_mut();
     let mut end_l = ptr::null_mut();
     let mut offsets_l: [u8; BLOCK] = unsafe { mem::uninitialized() };
 
@@ -216,16 +201,17 @@ fn partition_in_blocks<T, F>(v: &mut [T]
     let mut r = unsafe { l.offset(v.len() as isize) };
     let mut block_r = BLOCK;
     let mut start_r = ptr::null_mut();
     let mut end_r = ptr::null_mut();
     let mut offsets_r: [u8; BLOCK] = unsafe { mem::uninitialized() };
 
     // Returns the number of elements between pointers `l` (inclusive) and `r` (exclusive).
     fn width<T>(l: *mut T, r: *mut T) -> usize {
+        assert!(mem::size_of::<T>() > 0);
         (r as usize - l as usize) / mem::size_of::<T>()
     }
 
     // Roughly speaking, the idea is to repeat the following steps until completion:
     //
     // 1. Trace a block from the left side to identify elements greater than or equal to the pivot.
     // 2. Trace a block from the right side to identify elements less than the pivot.
     // 3. Exchange the identified elements between the left and right side.
@@ -278,17 +264,17 @@ fn partition_in_blocks<T, F>(v: &mut [T]
                     // Branchless comparison.
                     elem = elem.offset(-1);
                     *end_r = i as u8;
                     end_r = end_r.offset(is_less(&*elem, pivot) as isize);
                 }
             }
         }
 
-        // Number of displaced elements to swap between the left and right side.
+        // Number of out-of-order elements to swap between the left and right side.
         let count = cmp::min(width(start_l, end_l), width(start_r, end_r));
 
         if count > 0 {
             macro_rules! left { () => { l.offset(*start_l as isize) } }
             macro_rules! right { () => { r.offset(-(*start_r as isize) - 1) } }
 
             // Instead of swapping one pair at the time, it is more efficient to perform a cyclic
             // permutation. This is not strictly equivalent to swapping, but produces a similar
@@ -366,17 +352,17 @@ fn partition<T, F>(v: &mut [T], pivot: u
 
         // Read the pivot into a stack-allocated variable for efficiency.
         let write_on_drop = WriteOnDrop {
             value: unsafe { Some(ptr::read(&pivot[0])) },
             dest: &mut pivot[0],
         };
         let pivot = write_on_drop.value.as_ref().unwrap();
 
-        // Find the first pair of displaced elements.
+        // Find the first pair of out-of-order elements.
         let mut l = 0;
         let mut r = v.len();
         unsafe {
             while l < r && is_less(v.get_unchecked(l), pivot) {
                 l += 1;
             }
             while l < r && !is_less(v.get_unchecked(r - 1), pivot) {
                 r -= 1;
@@ -464,17 +450,17 @@ fn choose_pivot<T, F>(v: &mut [T], is_le
     const MAX_SWAPS: usize = 4 * 3;
 
     let len = v.len();
     let mut a = len / 4 * 1;
     let mut b = len / 4 * 2;
     let mut c = len / 4 * 3;
     let mut swaps = 0;
 
-    if len >= 4 {
+    if len >= 8 {
         let mut sort2 = |a: &mut usize, b: &mut usize| unsafe {
             if is_less(v.get_unchecked(*b), v.get_unchecked(*a)) {
                 ptr::swap(a, b);
                 swaps += 1;
             }
         };
 
         let mut sort3 = |a: &mut usize, b: &mut usize, c: &mut usize| {
@@ -505,74 +491,85 @@ fn choose_pivot<T, F>(v: &mut [T], is_le
 }
 
 /// Sorts `v` recursively.
 ///
 /// If the slice had a predecessor in the original array, it is specified as `pred`.
 ///
 /// `limit` is the number of allowed imbalanced partitions before switching to `heapsort`. If zero,
 /// this function will immediately switch to heapsort.
-fn recurse<T, F>(v: &mut [T], is_less: &mut F, pred: Option<&T>, mut limit: usize)
+fn recurse<'a, T, F>(mut v: &'a mut [T], is_less: &mut F, mut pred: Option<&'a T>, mut limit: usize)
     where F: FnMut(&T, &T) -> bool
 {
     // If `v` has length up to `insertion_len`, simply switch to insertion sort because it is going
     // to perform better than quicksort. For bigger types `T`, the threshold is smaller.
     let max_insertion = if mem::size_of::<T>() <= 2 * mem::size_of::<usize>() {
         32
     } else {
         16
     };
 
-    let len = v.len();
+    // This is `true` if the last partitioning was balanced.
+    let mut was_balanced = true;
+
+    loop {
+        let len = v.len();
+        if len <= max_insertion {
+            insertion_sort(v, is_less);
+            return;
+        }
 
-    if len <= max_insertion {
-        insertion_sort(v, is_less);
-        return;
-    }
+        if limit == 0 {
+            heapsort(v, is_less);
+            return;
+        }
+
+        // If the last partitioning was imbalanced, try breaking patterns in the slice by shuffling
+        // some elements around. Hopefully we'll choose a better pivot this time.
+        if !was_balanced {
+            break_patterns(v);
+            limit -= 1;
+        }
+
+        let pivot = choose_pivot(v, is_less);
 
-    if limit == 0 {
-        heapsort(v, is_less);
-        return;
-    }
+        // If the chosen pivot is equal to the predecessor, then it's the smallest element in the
+        // slice. Partition the slice into elements equal to and elements greater than the pivot.
+        // This case is usually hit when the slice contains many duplicate elements.
+        if let Some(p) = pred {
+            if !is_less(p, &v[pivot]) {
+                let mid = partition_equal(v, pivot, is_less);
+                v = &mut {v}[mid..];
+                continue;
+            }
+        }
 
-    let pivot = choose_pivot(v, is_less);
+        let (mid, was_partitioned) = partition(v, pivot, is_less);
+        was_balanced = cmp::min(mid, len - mid) >= len / 8;
 
-    // If the chosen pivot is equal to the predecessor, then it's the smallest element in the
-    // slice. Partition the slice into elements equal to and elements greater than the pivot.
-    // This case is often hit when the slice contains many duplicate elements.
-    if let Some(p) = pred {
-        if !is_less(p, &v[pivot]) {
-            let mid = partition_equal(v, pivot, is_less);
-            recurse(&mut v[mid..], is_less, pred, limit);
+        // If the partitioning is decently balanced and the slice was already partitioned, there
+        // are good chances it is also completely sorted. If so, we're done.
+        if was_balanced && was_partitioned && v.windows(2).all(|w| !is_less(&w[1], &w[0])) {
             return;
         }
+
+        let (left, right) = {v}.split_at_mut(mid);
+        let (pivot, right) = right.split_at_mut(1);
+
+        // Recurse into the smaller side only, in order to minimize the total number of recursive
+        // calls and consume less stack space.
+        if left.len() < right.len() {
+            recurse(left, is_less, pred, limit);
+            v = right;
+            pred = Some(&pivot[0]);
+        } else {
+            recurse(right, is_less, Some(&pivot[0]), limit);
+            v = left;
+        }
     }
-
-    let (mid, was_partitioned) = partition(v, pivot, is_less);
-    let is_balanced = cmp::min(mid, len - mid) >= len / 8;
-
-    // If the partitioning is decently balanced and the slice was already partitioned, there are
-    // good chances it is also completely sorted. If so, we're done.
-    if is_balanced && was_partitioned && v.windows(2).all(|w| !is_less(&w[1], &w[0])) {
-        return;
-    }
-
-    let (left, right) = v.split_at_mut(mid);
-    let (pivot, right) = right.split_at_mut(1);
-
-    // If the partitioning is imbalanced, try breaking patterns in the slice by shuffling
-    // potential future pivots around.
-    if !is_balanced {
-        break_patterns(left);
-        break_patterns(right);
-        limit -= 1;
-    }
-
-    recurse(left, is_less, pred, limit);
-    recurse(right, is_less, Some(&pivot[0]), limit);
 }
 
 /// Sorts `v` using quicksort.
 fn quicksort<T, F>(v: &mut [T], mut is_less: F)
     where F: FnMut(&T, &T) -> bool
 {
     // Sorting has no meaningful behavior on zero-sized types.
     if mem::size_of::<T>() == 0 {
new file mode 100644
--- /dev/null
+++ b/third_party/rust/procedural-masquerade/.cargo-checksum.json
@@ -0,0 +1,1 @@
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"3aad5ce464f7224e4b86fc0a70d89c354635ed624bf4bb12cf4ca597c45879b7","lib.rs":"f0f2793a21bc85ae3ee3e040ef703da87b558a1ce524873ef872bf44de795931"},"package":"9f566249236c6ca4340f7ca78968271f0ed2b0f234007a61b66f9ecd0af09260"}
\ No newline at end of file
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/third_party/rust/procedural-masquerade/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+name = "procedural-masquerade"
+version = "0.1.1"
+authors = ["Simon Sapin <simon.sapin@exyr.org>"]
+description = "macro_rules for making proc_macro_derive pretending to be proc_macro"
+documentation = "https://docs.rs/procedural-masquerade/"
+repository = "https://github.com/servo/rust-cssparser"
+license = "MIT/Apache-2.0"
+
+[lib]
+path = "lib.rs"
+doctest = false
new file mode 100644
--- /dev/null
+++ b/third_party/rust/procedural-masquerade/lib.rs
@@ -0,0 +1,250 @@
+//! # Custom `derive` pretending to be functional procedural macros on Rust 1.15
+//!
+//! This crate enables creating function-like macros (invoked as `foo!(...)`)
+//! with a procedural component,
+//! based on both custom `derive` (a.k.a. *Macros 1.1*) and `macro_rules!`.
+//!
+//! This convoluted mechanism enables such macros to run on stable Rust 1.15,
+//! even though functional procedural macros (a.k.a. *Macros 2.0*) are not available yet.
+//!
+//! A library defining such a macro needs two crates: a “normal” one, and a `proc-macro` one.
+//! In the example below we’ll call them `libfoo` and `libfoo-macros`, respectively.
+//!
+//! # Credits
+//!
+//! The trick that makes this crate work
+//! is based on an idea from [David Tolnay](https://github.com/dtolnay).
+//! Many thanks!
+//!
+//! # Example
+//!
+//! As a simple example, we’re going to re-implement the `stringify!` macro.
+//! This is useless since `stringify!` already exists in the standard library,
+//! and a bit absurd since this crate uses `stringify!` internally.
+//!
+//! Nevertheless, it serves as a simple example to demonstrate the use of this crate.
+//!
+//! ## The `proc-macro` crate
+//!
+//! The minimal `Cargo.toml` file is typical for Macros 1.1:
+//!
+//! ```toml
+//! [package]
+//! name = "libfoo-macros"
+//! version = "1.0.0"
+//!
+//! [lib]
+//! proc-macro = true
+//! ```
+//!
+//! In the code, we define the procedural part of our macro in a function.
+//! This function will not be used directly by end users,
+//! but it still needs to be re-exported to them
+//! (because of limitations in `macro_rules!`).
+//!
+//! To avoid name collisions, we and a long and explicit prefix in the function’s name.
+//!
+//! The function takes a string containing arbitrary Rust tokens,
+//! and returns a string that is parsed as *items*.
+//! The returned string can contain constants, statics, functions, `impl`s, etc.,
+//! but not expressions directly.
+//!
+//! ```rust
+//! #[macro_use] extern crate procedural_masquerade;
+//! extern crate proc_macro;
+//!
+//! define_proc_macros! {
+//!     #[allow(non_snake_case)]
+//!     pub fn foo_internal__stringify_const(input: &str) -> String {
+//!         format!("const STRINGIFIED: &'static str = {:?};", input)
+//!     }
+//! }
+//! ```
+//!
+//! A less trivial macro would probably use
+//! the [`syn`](https://github.com/dtolnay/syn/) crate to parse its input
+//! and the [`quote`](https://github.com/dtolnay/quote) crate to generate its output.
+//!
+//! ## The library crate
+//!
+//! ```toml
+//! [package]
+//! name = "libfoo"
+//! version = "1.0.0"
+//!
+//! [dependencies]
+//! cssparser-macros = {path = "./macros", version = "1.0"}
+//! ```
+//!
+//! ```rust
+//! #[macro_use] extern crate libfoo_macros;  // (1)
+//!
+//! pub use libfoo_macros::*;  // (2)
+//!
+//! define_invoke_proc_macro!(libfoo__invoke_proc_macro);  // (3)
+//!
+//! #[macro_export]
+//! macro_rules! foo_stringify {  // (4)
+//!     ( $( $tts: tt ) ) => {
+//!         {  // (5)
+//!             libfoo__invoke_proc_macro! {  // (6)
+//!                 foo_internal__stringify_const!( $( $tts ) )  // (7)
+//!             }
+//!             STRINGIFIED  // (8)
+//!         }
+//!     }
+//! }
+//! ```
+//!
+//! Let’s go trough the numbered lines one by one:
+//!
+//! 1. `libfoo` depends on the other `libfoo-macros`, and imports its macros.
+//! 2. Everything exported by `libfoo-macros` (which is one custom `derive`)
+//!    is re-exported to users of `libfoo`.
+//!    They’re not expected to use it directly,
+//!    but expansion of the `foo_stringify` macro needs it.
+//! 3. This macro invocation defines yet another macro, called `libfoo__invoke_proc_macro`,
+//!    which is also exported.
+//!    This indirection is necessary
+//!    because re-exporting `macro_rules!` macros doesn’t work currently,
+//!    and once again it is used by the expansion of `foo_stringify`.
+//!    Again, we use a long prefix to avoid name collisions.
+//! 4. Finally, we define the macro that we really want.
+//!    This one has a name that users will use.
+//! 5. The expansion of this macro will define some items,
+//!    whose names are not hygienic in `macro_rules`.
+//!    So we wrap everything in an extra `{…}` block to prevent these names for leaking.
+//! 6. Here we use the macro defined in (3),
+//!    which allows us to write something that look like invoking a functional procedural macro,
+//!    but really uses a custom `derive`.
+//!    This will define a type called `ProceduralMasqueradeDummyType`,
+//!    as a placeholder to use `derive`.
+//!    If `libfoo__invoke_proc_macro!` is to be used more than once,
+//!    each use needs to be nested in another block
+//!    so that the names of multiple dummy types don’t collide.
+//! 7. In addition to the dummy type,
+//!    the items returned by our procedural component are inserted here.
+//!    (In this case the `STRINGIFIED` constant.)
+//! 8. Finally, we write the expression that we want the macro to evaluate to.
+//!    This expression can use parts of `foo_stringify`’s input,
+//!    it can contain control-flow statements like `return` or `continue`,
+//!    and of course refer to procedurally-defined items.
+//!
+//! This macro can be used in an expression context.
+//! It expands to a block-expression that contains some items (as an implementation detail)
+//! and ends with another expression.
+//!
+//! ## For users
+//!
+//! Users of `libfoo` don’t need to worry about any of these implementation details.
+//! They can use the `foo_stringify` macro as if it were a simle `macro_rules` macro:
+//!
+//! ```rust
+//! #[macro_use] extern crate libfoo;
+//!
+//! fn main() {
+//!     do_something(foo_stringify!(1 + 2));
+//! }
+//!
+//! fn do_something(_: &str) { /* ... */ }
+//! ```
+//!
+//! # More
+//!
+//! To see a more complex example, look at
+//! [`cssparser`’s `src/macros.rs](https://github.com/servo/rust-cssparser/blob/master/src/macros.rs)
+//! and
+//! [`cssparser-macros`’s `macros/lib.rs](https://github.com/servo/rust-cssparser/blob/master/macros/lib.rs).
+
+/// This macro wraps `&str -> String` functions
+/// in custom `derive` implementations with `#[proc_macro_derive]`.
+///
+/// See crate documentation for details.
+#[macro_export]
+macro_rules! define_proc_macros {
+    (
+        $(
+            $( #[$attr:meta] )*
+            pub fn $proc_macro_name: ident ($input: ident : &str) -> String
+            $body: block
+        )+
+    ) => {
+        $(
+            $( #[$attr] )*
+            #[proc_macro_derive($proc_macro_name)]
+            pub fn $proc_macro_name(derive_input: ::proc_macro::TokenStream)
+                                    -> ::proc_macro::TokenStream {
+                let $input = derive_input.to_string();
+                let $input = $crate::_extract_input(&$input);
+                $body.parse().unwrap()
+            }
+        )+
+    }
+}
+
+/// Implementation detail of `define_proc_macros!`.
+///
+/// **This function is not part of the public API. It can change or be removed between any versions.**
+#[doc(hidden)]
+pub fn _extract_input(derive_input: &str) -> &str {
+    let mut input = derive_input;
+
+    for expected in &["#[allow(unused)]", "enum", "ProceduralMasqueradeDummyType", "{",
+                     "Input", "=", "(0,", "stringify!", "("] {
+        input = input.trim_left();
+        assert!(input.starts_with(expected),
+                "expected prefix {:?} not found in {:?}", expected, derive_input);
+        input = &input[expected.len()..];
+    }
+
+    for expected in [")", ").0,", "}"].iter().rev() {
+        input = input.trim_right();
+        assert!(input.ends_with(expected),
+                "expected suffix {:?} not found in {:?}", expected, derive_input);
+        let end = input.len() - expected.len();
+        input = &input[..end];
+    }
+
+    input
+}
+
+/// This macro expands to the definition of another macro (whose name is given as a parameter).
+///
+/// See crate documentation for details.
+#[macro_export]
+macro_rules! define_invoke_proc_macro {
+    ($macro_name: ident) => {
+        /// Implementation detail of other macros in this crate.
+        #[doc(hidden)]
+        #[macro_export]
+        macro_rules! $macro_name {
+            ($proc_macro_name: ident ! $paren: tt) => {
+                #[derive($proc_macro_name)]
+                #[allow(unused)]
+                enum ProceduralMasqueradeDummyType {
+                    // The magic happens here.
+                    //
+                    // We use an `enum` with an explicit discriminant
+                    // because that is the only case where a type definition
+                    // can contain a (const) expression.
+                    //
+                    // `(0, "foo").0` evalutes to 0, with the `"foo"` part ignored.
+                    //
+                    // By the time the `#[proc_macro_derive]` function
+                    // implementing `#[derive($proc_macro_name)]` is called,
+                    // `$paren` has already been replaced with the input of this inner macro,
+                    // but `stringify!` has not been expanded yet.
+                    //
+                    // This how arbitrary tokens can be inserted
+                    // in the input to the `#[proc_macro_derive]` function.
+                    //
+                    // Later, `stringify!(...)` is expanded into a string literal
+                    // which is then ignored.
+                    // Using `stringify!` enables passing arbitrary tokens
+                    // rather than only what can be parsed as a const expression.
+                    Input = (0, stringify! $paren ).0
+                }
+            }
+        }
+    }
+}
--- a/third_party/rust/quote/.cargo-checksum.json
+++ b/third_party/rust/quote/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"a5da41e07bf2d8af3fda684c7adb912e98047e9fe12a8288be3d9e3a494388ca","src/ident.rs":"830077b64dce8c8ede1fb6ab664cae72f5496f4ab6be21a5b4e3b5e4e57ec425","src/lib.rs":"f799c898057a4e8e1620b32c70e13d3fee7af3a0352a5a4a1da6393942d21cc7","src/to_tokens.rs":"a871cb84506fa9e0783ac29617d686327ce5d05a9711a3a10833430b00345ccc","src/tokens.rs":"a559a56905debae32a0e7852114812cca7173341a62b277894517264a759dfa6"},"package":"e7b44fd83db28b83c1c58187159934906e5e955c812e211df413b76b03c909a5"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"9e488340fc68d310f52d8b7d68fc305e0a8b76261d450f34b1ecb9772d42617a","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"c9a75f18b9ab2927829a208fc6aa2cf4e63b8420887ba29cdb265d6619ae82d5","README.md":"3390fa1362c73052a268ae97a4777c5bcd8e991f866f9cce88ddde8d0963fd4d","src/ident.rs":"830077b64dce8c8ede1fb6ab664cae72f5496f4ab6be21a5b4e3b5e4e57ec425","src/lib.rs":"f799c898057a4e8e1620b32c70e13d3fee7af3a0352a5a4a1da6393942d21cc7","src/to_tokens.rs":"a871cb84506fa9e0783ac29617d686327ce5d05a9711a3a10833430b00345ccc","src/tokens.rs":"ecf42295d45982ba63c9eb51dd1b3abb5498e14a880c607fd11cf78e51f99035","tests/test.rs":"823f836751f89d98ddee52c99194ab9d686583b365328425f56831c480e8a21b"},"package":"7375cf7ad34a92e8fd18dd9c42f58b9a11def59ab48bec955bf359a788335592"}
\ No newline at end of file
--- a/third_party/rust/quote/Cargo.toml
+++ b/third_party/rust/quote/Cargo.toml
@@ -1,10 +1,10 @@
 [package]
 name = "quote"
-version = "0.3.12" # don't forget to update version in readme for breaking changes
+version = "0.3.14" # don't forget to update version in readme for breaking changes
 authors = ["David Tolnay <dtolnay@gmail.com>"]
 license = "MIT/Apache-2.0"
 description = "Quasi-quoting macro quote!(...)"
 repository = "https://github.com/dtolnay/quote"
 documentation = "https://docs.rs/quote/"
 keywords = ["syn"]
-include = ["Cargo.toml", "src/**/*.rs"]
+include = ["Cargo.toml", "src/**/*.rs", "tests/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
new file mode 100644
--- /dev/null
+++ b/third_party/rust/quote/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/quote/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2016 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.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/quote/README.md
@@ -0,0 +1,104 @@
+Rust Quasi-Quoting
+==================
+
+[![Build Status](https://api.travis-ci.org/dtolnay/quote.svg?branch=master)](https://travis-ci.org/dtolnay/quote)
+[![Latest Version](https://img.shields.io/crates/v/quote.svg)](https://crates.io/crates/quote)
+[![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)](https://docs.rs/quote/)
+
+Quasi-quoting without a Syntex dependency, intended for use with [Macros
+1.1](https://github.com/rust-lang/rfcs/blob/master/text/1681-macros-1.1.md).
+
+```toml
+[dependencies]
+quote = "0.3"
+```
+
+```rust
+#[macro_use]
+extern crate quote;
+```
+
+## What is quasi-quoting?
+
+Quasi-quoting is a way of writing code and treating it as data, similar to
+writing code inside of a double-quoted string literal except more friendly to
+your text editor or IDE. It does not get in the way of syntax highlighting,
+brace matching, indentation, or autocompletion, all of which you would lose by
+writing code inside of double quotes.
+
+Check out
+[my meetup talk](https://air.mozilla.org/rust-meetup-december-2016-12-15/)
+on the topic to learn more about the use case. Start the video at 3:00.
+
+This crate is motivated by the Macros 1.1 use case, but is a general-purpose
+Rust quasi-quoting library and is not specific to procedural macros.
+
+## Syntax
+
+The quote crate provides a `quote!` macro within which you can write Rust code
+that gets packaged into a `quote::Tokens` and can be treated as data. You should
+think of `quote::Tokens` as representing a fragment of Rust source code. Call
+`to_string()` or `as_str()` on a Tokens to get back the fragment of source code
+as a string.
+
+Within the `quote!` macro, interpolation is done with `#var`. Any type
+implementing the `quote::ToTokens` trait can be interpolated. This includes most
+Rust primitive types as well as most of the syntax tree types from
+[`syn`](https://github.com/dtolnay/syn).
+
+```rust
+let tokens = quote! {
+    struct SerializeWith #generics #where_clause {
+        value: &'a #field_ty,
+        phantom: ::std::marker::PhantomData<#item_ty>,
+    }
+
+    impl #generics serde::Serialize for SerializeWith #generics #where_clause {
+        fn serialize<S>(&self, s: &mut S) -> Result<(), S::Error>
+            where S: serde::Serializer
+        {
+            #path(self.value, s)
+        }
+    }
+
+    SerializeWith {
+        value: #value,
+        phantom: ::std::marker::PhantomData::<#item_ty>,
+    }
+};
+```
+
+Repetition is done using `#(...)*` or `#(...),*` very similar to `macro_rules!`:
+
+- `#(#var)*` - no separators
+- `#(#var),*` - the character before the asterisk is used as a separator
+- `#( struct #var; )*` - the repetition can contain other things
+- `#( #k => println!("{}", #v), )*` - even multiple interpolations
+
+Tokens can be interpolated into other quotes:
+
+```rust
+let t = quote! { /* ... */ };
+return quote! { /* ... */ #t /* ... */ };
+```
+
+The `quote!` macro relies on deep recursion so some large invocations may fail
+with "recursion limit reached" when you compile. If it fails, bump up the
+recursion limit by adding `#![recursion_limit = "128"]` to your crate. An even
+higher limit may be necessary for especially large invocations. You don't need
+this unless the compiler tells you that you need it.
+
+## License
+
+Licensed under either of
+
+ * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
+ * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
+
+at your option.
+
+### Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in this crate by you, as defined in the Apache-2.0 license, shall
+be dual licensed as above, without any additional terms or conditions.
--- a/third_party/rust/quote/src/tokens.rs
+++ b/third_party/rust/quote/src/tokens.rs
@@ -127,16 +127,20 @@ impl Tokens {
             self.append(term);
         }
     }
 
     pub fn as_str(&self) -> &str {
         &self.0
     }
 
+    pub fn into_string(self) -> String {
+        self.0
+    }
+
     pub fn parse<T: FromStr>(&self) -> Result<T, T::Err> {
         FromStr::from_str(&self.0)
     }
 }
 
 impl Default for Tokens {
     fn default() -> Self {
         Tokens::new()
new file mode 100644
--- /dev/null
+++ b/third_party/rust/quote/tests/test.rs
@@ -0,0 +1,350 @@
+use std::{f32, f64};
+use std::borrow::Cow;
+
+#[macro_use]
+extern crate quote;
+
+struct X;
+
+impl quote::ToTokens for X {
+    fn to_tokens(&self, tokens: &mut quote::Tokens) {
+        tokens.append("X");
+    }
+}
+
+#[test]
+fn test_quote_impl() {
+    let tokens = quote!(
+        impl<'a, T: ToTokens> ToTokens for &'a T {
+            fn to_tokens(&self, tokens: &mut Tokens) {
+                (**self).to_tokens(tokens)
+            }
+        }
+    );
+
+    let expected = concat!(
+        "impl < 'a , T : ToTokens > ToTokens for & 'a T { ",
+            "fn to_tokens ( & self , tokens : & mut Tokens ) { ",
+                "( * * self ) . to_tokens ( tokens ) ",
+            "} ",
+        "}"
+    );
+
+    assert_eq!(expected, tokens.as_str());
+}
+
+#[test]
+fn test_substitution() {
+    let x = X;
+    let tokens = quote!(#x <#x> (#x) [#x] {#x});
+
+    let expected = "X < X > ( X ) [ X ] { X }";
+
+    assert_eq!(expected, tokens.as_str());
+}
+
+#[test]
+fn test_iter() {
+    let primes = &[X, X, X, X];
+
+    assert_eq!("X X X X", quote!(#(#primes)*).as_str());
+
+    assert_eq!("X , X , X , X ,", quote!(#(#primes,)*).as_str());
+
+    assert_eq!("X , X , X , X", quote!(#(#primes),*).as_str());
+}
+
+#[test]
+fn test_advanced() {
+    let generics = quote!( <'a, T> );
+
+    let where_clause = quote!( where T: Serialize );
+
+    let field_ty = quote!( String );
+
+    let item_ty = quote!( Cow<'a, str> );
+
+    let path = quote!( SomeTrait::serialize_with );
+
+    let value = quote!( self.x );
+
+    let tokens = quote! {
+        struct SerializeWith #generics #where_clause {
+            value: &'a #field_ty,
+            phantom: ::std::marker::PhantomData<#item_ty>,
+        }
+
+        impl #generics ::serde::Serialize for SerializeWith #generics #where_clause {
+            fn serialize<S>(&self, s: &mut S) -> Result<(), S::Error>
+                where S: ::serde::Serializer
+            {
+                #path(self.value, s)
+            }
+        }
+
+        SerializeWith {
+            value: #value,
+            phantom: ::std::marker::PhantomData::<#item_ty>,
+        }
+    };
+
+    let expected = concat!(
+        "struct SerializeWith < 'a , T > where T : Serialize { ",
+            "value : & 'a String , ",
+            "phantom : :: std :: marker :: PhantomData < Cow < 'a , str > > , ",
+        "} ",
+        "impl < 'a , T > :: serde :: Serialize for SerializeWith < 'a , T > where T : Serialize { ",
+            "fn serialize < S > ( & self , s : & mut S ) -> Result < ( ) , S :: Error > ",
+                "where S : :: serde :: Serializer ",
+            "{ ",
+                "SomeTrait :: serialize_with ( self . value , s ) ",
+            "} ",
+        "} ",
+        "SerializeWith { ",
+            "value : self . x , ",
+            "phantom : :: std :: marker :: PhantomData :: < Cow < 'a , str > > , ",
+        "}"
+    );
+
+    assert_eq!(expected, tokens.as_str());
+}
+
+#[test]
+fn test_unit() {
+    let x = ();
+    let tokens = quote!(#x);
+    let expected = "( )";
+    assert_eq!(expected, tokens.as_str());
+}
+
+#[test]
+fn test_tuple() {
+    let x = ("foo", 4_u32);
+    let tokens = quote!(#x);
+    let expected = "( \"foo\" , 4u32 , )";
+    assert_eq!(expected, tokens.as_str());
+}
+
+#[test]
+fn test_array() {
+    let x: [u32; 3] = [1, 2, 3];
+    let tokens = quote!(#x);
+    let expected = "[ 1u32 , 2u32 , 3u32 , ]";
+    assert_eq!(expected, tokens.as_str());
+}
+
+#[test]
+fn test_slice() {
+    let x: &[u32] = &[1, 2, 3];
+    let tokens = quote!(&#x);  // Note: explicit `&`
+    let expected = "& [ 1u32 , 2u32 , 3u32 , ]";
+    assert_eq!(expected, tokens.as_str());
+}
+
+#[test]
+fn test_vec() {
+    let x: Vec<u32> = vec![1, 2, 3];
+    let tokens = quote!(vec!#x);  // Note: explicit `vec!`
+    let expected = "vec ! [ 1u32 , 2u32 , 3u32 , ]";
+    assert_eq!(expected, tokens.as_str());
+}
+
+#[test]
+fn test_integer() {
+    let ii8 = -1i8;
+    let ii16 = -1i16;
+    let ii32 = -1i32;
+    let ii64 = -1i64;
+    let iisize = -1isize;
+    let uu8 = 1u8;
+    let uu16 = 1u16;
+    let uu32 = 1u32;
+    let uu64 = 1u64;
+    let uusize = 1usize;
+
+    let tokens = quote! {
+        #ii8 #ii16 #ii32 #ii64 #iisize
+        #uu8 #uu16 #uu32 #uu64 #uusize
+    };
+    let expected = "-1i8 -1i16 -1i32 -1i64 -1isize 1u8 1u16 1u32 1u64 1usize";
+    assert_eq!(expected, tokens.as_str());
+}
+
+#[test]
+fn test_hex() {
+    let hex = quote::Hex(0xFFFF_0000_u32);
+    let tokens = quote!(#hex);
+    let expected = "0xFFFF0000u32";
+    assert_eq!(expected, tokens.as_str());
+}
+
+#[test]
+fn test_floating() {
+    let e32 = 2.71828f32;
+    let nan32 = f32::NAN;
+    let inf32 = f32::INFINITY;
+    let neginf32 = f32::NEG_INFINITY;
+
+    let e64 = 2.71828f64;
+    let nan64 = f64::NAN;
+    let inf64 = f64::INFINITY;
+    let neginf64 = f64::NEG_INFINITY;
+
+    let tokens = quote! {
+        #e32 @ #nan32 @ #inf32 @ #neginf32
+        #e64 @ #nan64 @ #inf64 @ #neginf64
+    };
+    let expected = concat!(
+        "2.71828f32 @ :: std :: f32 :: NAN @ :: std :: f32 :: INFINITY @ :: std :: f32 :: NEG_INFINITY ",
+        "2.71828f64 @ :: std :: f64 :: NAN @ :: std :: f64 :: INFINITY @ :: std :: f64 :: NEG_INFINITY",
+    );
+    assert_eq!(expected, tokens.as_str());
+}
+
+#[test]
+fn test_char() {
+    let zero = '\0';
+    let pound = '#';
+    let quote = '"';
+    let apost = '\'';
+    let newline = '\n';
+    let heart = '\u{2764}';
+
+    let tokens = quote! {
+        #zero #pound #quote #apost #newline #heart
+    };
+    let expected = "'\\0' '#' '\"' '\\'' '\\n' '\u{2764}'";
+    assert_eq!(expected, tokens.as_str());
+}
+
+#[test]
+fn test_str() {
+    let s = "\0 a 'b \" c";
+    let tokens = quote!(#s);
+    let expected = "\"\\0 a 'b \\\" c\"";
+    assert_eq!(expected, tokens.as_str());
+}
+
+#[test]
+fn test_string() {
+    let s = "\0 a 'b \" c".to_string();
+    let tokens = quote!(#s);
+    let expected = "\"\\0 a 'b \\\" c\"";
+    assert_eq!(expected, tokens.as_str());
+}
+
+#[test]
+fn test_byte_str() {
+    let s = quote::ByteStr("\0 a 'b \" c");
+    let tokens = quote!(#s);
+    let expected = "b\"\\0 a 'b \\\" c\"";
+    assert_eq!(expected, tokens.as_str());
+}
+
+#[test]
+fn test_byte_str_escape() {
+    let s = quote::ByteStr("\u{3c3} \\ \" \n");
+    let tokens = quote!(#s);
+    let expected = "b\"\\xCF\\x83 \\\\ \\\" \\n\"";
+    assert_eq!(expected, tokens.as_str());
+}
+
+#[test]
+fn test_ident() {
+    let foo = quote::Ident::from("Foo");
+    let bar = quote::Ident::from(format!("Bar{}", 7));
+    let tokens = quote!(struct #foo; enum #bar {});
+    let expected = "struct Foo ; enum Bar7 { }";
+    assert_eq!(expected, tokens.as_str());
+}
+
+#[test]
+fn test_duplicate() {
+    let ch = 'x';
+
+    let tokens = quote!(#ch #ch);
+
+    let expected = "'x' 'x'";
+    assert_eq!(expected, tokens.as_str());
+}
+
+#[test]
+fn test_fancy_repetition() {
+    let foo = vec!["a", "b"];
+    let bar = vec![true, false];
+
+    let tokens = quote! {
+        #(#foo: #bar),*
+    };
+
+    let expected = r#""a" : true , "b" : false"#;
+    assert_eq!(expected, tokens.as_str());
+}
+
+#[test]
+fn test_nested_fancy_repetition() {
+    let nested = vec![vec!['a', 'b', 'c'], vec!['x', 'y', 'z']];
+
+    let tokens = quote! {
+        #(
+            #(#nested)*
+        ),*
+    };
+
+    let expected = "'a' 'b' 'c' , 'x' 'y' 'z'";
+    assert_eq!(expected, tokens.as_str());
+}
+
+#[test]
+fn test_empty_repetition() {
+    let tokens = quote!(#(a b)* #(c d),*);
+    assert_eq!("", tokens.as_str());
+}
+
+#[test]
+fn test_variable_name_conflict() {
+    // The implementation of `#(...),*` uses the variable `_i` but it should be
+    // fine, if a little confusing when debugging.
+    let _i = vec!['a', 'b'];
+    let tokens = quote! { #(#_i),* };
+    let expected = "'a' , 'b'";
+    assert_eq!(expected, tokens.as_str());
+}
+
+#[test]
+fn test_empty_quote() {
+    let tokens = quote!();
+    assert_eq!("", tokens.as_str());
+}
+
+#[test]
+fn test_box_str() {
+    let b = "str".to_owned().into_boxed_str();
+    let tokens = quote! { #b };
+    assert_eq!("\"str\"", tokens.as_str());
+}
+
+#[test]
+fn test_cow() {
+    let owned: Cow<quote::Ident> = Cow::Owned(quote::Ident::from("owned"));
+
+    let ident = quote::Ident::from("borrowed");
+    let borrowed = Cow::Borrowed(&ident);
+
+    let tokens = quote! { #owned #borrowed };
+    assert_eq!("owned borrowed", tokens.as_str());
+}
+
+#[test]
+fn test_closure() {
+    fn field_i(i: usize) -> quote::Ident {
+        quote::Ident::new(format!("__field{}", i))
+    }
+
+    let fields = (0usize..3)
+        .map(field_i as fn(_) -> _)
+        .map(|var| quote! { #var });
+
+    let tokens = quote! { #(#fields)* };
+    assert_eq!("__field0 __field1 __field2", tokens.as_str());
+}
--- a/third_party/rust/serde/.cargo-checksum.json
+++ b/third_party/rust/serde/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"52cbed9713eaf849002a7aa53e0ead1deeb665c342b19c12ae36fe912cd0a40f","src/bytes.rs":"1f7846e870cf00b06a927896309b8b32457f2fe7d9944783eb1b715ce0459bd1","src/de/content.rs":"1887e6d7ff6bf15d9f74d4a88f7f21c5263a179cbc5ba0a7151f37c1b1a72345","src/de/from_primitive.rs":"b1bd165e343a4380965551709119ef9ed895e4b025045a810dabd671511ba3ab","src/de/impls.rs":"399dd33fbb9d66aae720b2ac1cbaa528aaace6a714dd26fd76307985bcd20798","src/de/mod.rs":"0f68ba1dcc40954b4f8283561fe73d7df3449d35e02817d056b260eacb953834","src/de/private.rs":"818364e2750fa09a2e9baa8be9fcbf44f4eac15f7ab29daf563d96fd18c481b0","src/de/value.rs":"948b4d8f0c2fdfd82699dbbba6c4b1175fbfc89e4cc8522bb78d34e76aa1f00f","src/error.rs":"7e8d8f3d09527598574d3d12a110bd34e1b835bb9b702fd7ac0b758fa55a1011","src/export.rs":"0b8e6b642010ad6a71f13f5facfd91e9da1d7c99d479dba020dec10e88fb6b0f","src/iter.rs":"30090fe6ab49bb1d8c7fec362cace52981b2c4e1a1a8e3fad4117eab558cdde6","src/lib.rs":"1471f32b6ffb8e049ab5177327420a72499fff79b9f58636412d36ce592ff517","src/macros.rs":"6c1ab6568717a882c7ed619319cf00c9966803474c3f45be5cb1dc496ba474a5","src/ser/impls.rs":"c27bb83e3ff78a6038f551db584322910dd97b1a988cf5c533aefb27b98298ca","src/ser/impossible.rs":"8700bd05e21e4ce20187e0c0d8e1c08df78d68ccceaaec8cc6b900e46a6b83f0","src/ser/mod.rs":"eeb43ee845375c815b247d2ee1c024ac5221584299359c1dc94ad85118dbd391","src/ser/private.rs":"9e7805dbb79516e297fa00432b6ae75d268ad9cd0b8857a302dea44fd8991fe8","src/utils.rs":"b0d1a54af90e3620abd66479d757a2eb442449788c4ece93161916da0838affa"},"package":"1e0ed773960f90a78567fcfbe935284adf50c5d7cf119aa2cf43bb0b4afa69bb"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"e2817af66db5f058a55b5f126ca9a663925bfeb36a592a4121e7e9a44d3a3453","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"ebe318a04cf4e547e0f3ab97f1345ecb553358ee13ea81f99e3323e37d70ccdf","src/bytes.rs":"2b6a9c2c3d6eabe8633adee6655a3b94f0d1e931e740e72699b6965bee21e226","src/de/content.rs":"469d3298d4109d514a8cd630273a288a361544979e2ab23aaa325b2201f9361f","src/de/from_primitive.rs":"b1bd165e343a4380965551709119ef9ed895e4b025045a810dabd671511ba3ab","src/de/impls.rs":"762c3f32627d12555ccd08fcdf3dfb621403c35cde8a5af7866e2ad74c95a4c8","src/de/mod.rs":"365ee7038c53e88cddd451afd11d459f65185fd04523bd000a6b424ac4f71db7","src/de/private.rs":"2578dbc89c2f2a852caed3fdc40f710d4828d085c4e954dd96789d678583424e","src/de/value.rs":"67a34c03fda6521c082548984b0116494e5fbff7e60e30e06f0dda62d9d3e083","src/error.rs":"3af5286c1daad9bfd504693f8a8587f7044c9b9520e23e072549c43a72e4821d","src/export.rs":"0b8e6b642010ad6a71f13f5facfd91e9da1d7c99d479dba020dec10e88fb6b0f","src/iter.rs":"af3c43712c240b3a06870e0b0b6e837b142d5a65c62742fa358fe36a9d9319a7","src/lib.rs":"75df159c150e62c99887c0a4f23ed1271c9eb910ebc79a2d4bd279b0e11ce7e3","src/macros.rs":"af1f75bb34460b814e44f7bc67bdd1dc1bba97f1f2a31744c22e1bfcdc29499a","src/ser/content.rs":"f1cd3724e5ddeacb75b3585b2fd2be7c42fc764444b1f764e31ed9fe49f62025","src/ser/impls.rs":"51d4036b8309381af8267375778bf80c3a9114577c03a04da9a679462077efac","src/ser/impossible.rs":"f1332a1250f9c1d85d679653ade502cf99bdff0344b9f864e6cf1a1789d7c597","src/ser/mod.rs":"d1d821488453651a986bb4e4608f72868c09a71a8dbf693584758b25603ae8bf","src/ser/private.rs":"3999dc19d61d43a64d5d1bdda61f80ea16405a926b074b5441b39d87318be73b","src/utils.rs":"ed271c0825c01d7b24968bf47ce9e2475ca219faf733eb33831d6e19bf07aaf1"},"package":"05a67b8a53f885f4b6e3ed183806035819f9862474e747fe4488a6d63bcbfcb7"}
\ No newline at end of file
--- a/third_party/rust/serde/Cargo.toml
+++ b/third_party/rust/serde/Cargo.toml
@@ -1,21 +1,21 @@
 [package]
 name = "serde"
-version = "0.9.7"
+version = "0.9.9"
 authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
 license = "MIT/Apache-2.0"
 description = "A generic serialization/deserialization framework"
 homepage = "https://serde.rs"
 repository = "https://github.com/serde-rs/serde"
 documentation = "https://docs.serde.rs/serde/"
-readme = "../README.md"
 keywords = ["serde", "serialization", "no_std"]
 categories = ["encoding"]
-include = ["Cargo.toml", "src/**/*.rs"]
+readme = "../README.md"
+include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
 
 [badges]
 travis-ci = { repository = "serde-rs/serde" }
 
 [features]
 default = ["std"]
 
 std = []
new file mode 100644
--- /dev/null
+++ b/third_party/rust/serde/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/serde/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.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/serde/README.md
@@ -0,0 +1,71 @@
+# Serde &emsp; [![Build Status](https://api.travis-ci.org/serde-rs/serde.svg?branch=master)](https://travis-ci.org/serde-rs/serde) [![Latest Version](https://img.shields.io/crates/v/serde.svg)](https://crates.io/crates/serde)
+
+**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.**
+
+---
+
+You may be looking for:
+
+- [An overview of Serde](https://serde.rs/)
+- [Data formats supported by Serde](https://serde.rs/#data-formats)
+- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/codegen.html)
+- [Examples](https://serde.rs/examples.html)
+- [API documentation](https://docs.serde.rs/serde/)
+- [Release notes](https://github.com/serde-rs/serde/releases)
+
+## Serde in action
+
+```rust
+#[macro_use]
+extern crate serde_derive;
+
+extern crate serde_json;
+
+#[derive(Serialize, Deserialize, Debug)]
+struct Point {
+    x: i32,
+    y: i32,
+}
+
+fn main() {
+    let point = Point { x: 1, y: 2 };
+
+    // Convert the Point to a JSON string.
+    let serialized = serde_json::to_string(&point).unwrap();
+
+    // Prints serialized = {"x":1,"y":2}
+    println!("serialized = {}", serialized);
+
+    // Convert the JSON string back to a Point.
+    let deserialized: Point = serde_json::from_str(&serialized).unwrap();
+
+    // Prints deserialized = Point { x: 1, y: 2 }
+    println!("deserialized = {:?}", deserialized);
+}
+```
+
+## Getting help
+
+Serde developers live in the #serde channel on
+[`irc.mozilla.org`](https://wiki.mozilla.org/IRC). The #rust channel is also a
+good resource with generally faster response time but less specific knowledge
+about Serde. If IRC is not your thing or you don't get a good response, we are
+happy to respond to [GitHub issues](https://github.com/serde-rs/serde/issues/new)
+as well.
+
+## License
+
+Serde is licensed under either of
+
+ * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
+   http://www.apache.org/licenses/LICENSE-2.0)
+ * MIT license ([LICENSE-MIT](LICENSE-MIT) or
+   http://opensource.org/licenses/MIT)
+
+at your option.
+
+### Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in Serde by you, as defined in the Apache-2.0 license, shall be
+dual licensed as above, without any additional terms or conditions.
--- a/third_party/rust/serde/src/bytes.rs
+++ b/third_party/rust/serde/src/bytes.rs
@@ -55,19 +55,17 @@ use collections::Vec;
 #[derive(Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)]
 pub struct Bytes<'a> {
     bytes: &'a [u8],
 }
 
 impl<'a> Bytes<'a> {
     /// Wrap an existing `&[u8]`.
     pub fn new(bytes: &'a [u8]) -> Self {
-        Bytes {
-            bytes: bytes,
-        }
+        Bytes { bytes: bytes }
     }
 }
 
 impl<'a> fmt::Debug for Bytes<'a> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         try!(f.write_str("b\""));
         for c in escape_bytestring(self.bytes) {
             try!(f.write_char(c));
@@ -93,32 +91,35 @@ impl<'a> Into<&'a [u8]> for Bytes<'a> {
     fn into(self) -> &'a [u8] {
         self.bytes
     }
 }
 
 impl<'a> ops::Deref for Bytes<'a> {
     type Target = [u8];
 
-    fn deref(&self) -> &[u8] { self.bytes }
+    fn deref(&self) -> &[u8] {
+        self.bytes
+    }
 }
 
 impl<'a> ser::Serialize for Bytes<'a> {
     #[inline]
     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
         where S: ser::Serializer
     {
         serializer.serialize_bytes(self.bytes)
     }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 #[cfg(any(feature = "std", feature = "collections"))]
 mod bytebuf {
+    use core::cmp;
     use core::ops;
     use core::fmt;
     use core::fmt::Write;
 
     use ser;
     use de;
 
     #[cfg(feature = "collections")]
@@ -156,19 +157,17 @@ mod bytebuf {
 
         /// Construct a new, empty `ByteBuf` with the specified capacity.
         pub fn with_capacity(cap: usize) -> Self {
             ByteBuf::from(Vec::with_capacity(cap))
         }
 
         /// Wrap existing bytes in a `ByteBuf`.
         pub fn from<T: Into<Vec<u8>>>(bytes: T) -> Self {
-            ByteBuf {
-                bytes: bytes.into(),
-            }
+            ByteBuf { bytes: bytes.into() }
         }
     }
 
     impl fmt::Debug for ByteBuf {
         fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             try!(f.write_str("b\""));
             for c in super::escape_bytestring(self.bytes.as_ref()) {
                 try!(f.write_char(c));
@@ -211,21 +210,25 @@ mod bytebuf {
         fn as_mut(&mut self) -> &mut [u8] {
             &mut self.bytes
         }
     }
 
     impl ops::Deref for ByteBuf {
         type Target = [u8];
 
-        fn deref(&self) -> &[u8] { &self.bytes[..] }
+        fn deref(&self) -> &[u8] {
+            &self.bytes[..]
+        }
     }
 
     impl ops::DerefMut for ByteBuf {
-        fn deref_mut(&mut self) -> &mut [u8] { &mut self.bytes[..] }
+        fn deref_mut(&mut self) -> &mut [u8] {
+            &mut self.bytes[..]
+        }
     }
 
     impl ser::Serialize for ByteBuf {
         fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
             where S: ser::Serializer
         {
             serializer.serialize_bytes(self)
         }
@@ -238,57 +241,57 @@ mod bytebuf {
         type Value = ByteBuf;
 
         fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
             formatter.write_str("byte array")
         }
 
         #[inline]
         fn visit_unit<E>(self) -> Result<ByteBuf, E>
-            where E: de::Error,
+            where E: de::Error
         {
             Ok(ByteBuf::new())
         }
 
         #[inline]
         fn visit_seq<V>(self, mut visitor: V) -> Result<ByteBuf, V::Error>
-            where V: de::SeqVisitor,
+            where V: de::SeqVisitor
         {
-            let (len, _) = visitor.size_hint();
+            let len = cmp::min(visitor.size_hint().0, 4096);
             let mut values = Vec::with_capacity(len);
 
             while let Some(value) = try!(visitor.visit()) {
                 values.push(value);
             }
 
             Ok(ByteBuf::from(values))
         }
 
         #[inline]
         fn visit_bytes<E>(self, v: &[u8]) -> Result<ByteBuf, E>
-            where E: de::Error,
+            where E: de::Error
         {
             Ok(ByteBuf::from(v))
         }
 
         #[inline]
         fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<ByteBuf, E>
-            where E: de::Error,
+            where E: de::Error
         {
             Ok(ByteBuf::from(v))
         }
 
         fn visit_str<E>(self, v: &str) -> Result<ByteBuf, E>
-            where E: de::Error,
+            where E: de::Error
         {
             Ok(ByteBuf::from(v))
         }
 
         fn visit_string<E>(self, v: String) -> Result<ByteBuf, E>
-            where E: de::Error,
+            where E: de::Error
         {
             Ok(ByteBuf::from(v))
         }
     }
 
     impl de::Deserialize for ByteBuf {
         #[inline]
         fn deserialize<D>(deserializer: D) -> Result<ByteBuf, D::Error>
@@ -297,14 +300,16 @@ mod bytebuf {
             deserializer.deserialize_byte_buf(ByteBufVisitor)
         }
     }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 #[inline]
-fn escape_bytestring<'a>(bytes: &'a [u8]) -> iter::FlatMap<slice::Iter<'a, u8>, char::EscapeDefault, fn(&u8) -> char::EscapeDefault> {
+fn escape_bytestring<'a>
+    (bytes: &'a [u8])
+     -> iter::FlatMap<slice::Iter<'a, u8>, char::EscapeDefault, fn(&u8) -> char::EscapeDefault> {
     fn f(b: &u8) -> char::EscapeDefault {
         char::from_u32(*b as u32).unwrap().escape_default()
     }
     bytes.iter().flat_map(f as fn(&u8) -> char::EscapeDefault)
 }
--- a/third_party/rust/serde/src/de/content.rs
+++ b/third_party/rust/serde/src/de/content.rs
@@ -5,43 +5,35 @@
 // worry about backward compatibility for the `untagged` and `tag` attributes
 // rather than for this entire mechanism.
 //
 // This issue is tracking making some of this stuff public:
 // https://github.com/serde-rs/serde/issues/741
 
 #![doc(hidden)]
 
+use core::cmp;
 use core::fmt;
 use core::marker::PhantomData;
 
 #[cfg(all(not(feature = "std"), feature = "collections"))]
 use collections::{String, Vec};
 
 #[cfg(all(feature = "alloc", not(feature = "std")))]
 use alloc::boxed::Box;
 
-use de::{
-    self,
-    Deserialize,
-    DeserializeSeed,
-    Deserializer,
-    Visitor,
-    SeqVisitor,
-    MapVisitor,
-    EnumVisitor,
-};
+use de::{self, Deserialize, DeserializeSeed, Deserializer, Visitor, SeqVisitor, MapVisitor,
+         EnumVisitor, Unexpected};
 
 /// Used from generated code to buffer the contents of the Deserializer when
 /// deserializing untagged enums and internally tagged enums.
 ///
 /// Not public API. Use serde-value instead.
 #[derive(Debug)]
 pub enum Content {
-    // Don't mind the PhantomData, just need to use E somewhere.
     Bool(bool),
 
     U8(u8),
     U16(u16),
     U32(u32),
     U64(u64),
 
     I8(i8),
@@ -60,16 +52,42 @@ pub enum Content {
     Some(Box<Content>),
 
     Unit,
     Newtype(Box<Content>),
     Seq(Vec<Content>),
     Map(Vec<(Content, Content)>),
 }
 
+impl Content {
+    fn unexpected(&self) -> Unexpected {
+        match *self {
+            Content::Bool(b) => Unexpected::Bool(b),
+            Content::U8(n) => Unexpected::Unsigned(n as u64),
+            Content::U16(n) => Unexpected::Unsigned(n as u64),
+            Content::U32(n) => Unexpected::Unsigned(n as u64),
+            Content::U64(n) => Unexpected::Unsigned(n),
+            Content::I8(n) => Unexpected::Signed(n as i64),
+            Content::I16(n) => Unexpected::Signed(n as i64),
+            Content::I32(n) => Unexpected::Signed(n as i64),
+            Content::I64(n) => Unexpected::Signed(n),
+            Content::F32(f) => Unexpected::Float(f as f64),
+            Content::F64(f) => Unexpected::Float(f),
+            Content::Char(c) => Unexpected::Char(c),
+            Content::String(ref s) => Unexpected::Str(s),
+            Content::Bytes(ref b) => Unexpected::Bytes(b),
+            Content::None | Content::Some(_) => Unexpected::Option,
+            Content::Unit => Unexpected::Unit,
+            Content::Newtype(_) => Unexpected::NewtypeStruct,
+            Content::Seq(_) => Unexpected::Seq,
+            Content::Map(_) => Unexpected::Map,
+        }
+    }
+}
+
 impl Deserialize for Content {
     fn deserialize<D: Deserializer>(deserializer: D) -> Result<Self, D::Error> {
         // Untagged and internally tagged enums are only supported in
         // self-describing formats.
         deserializer.deserialize(ContentVisitor)
     }
 }
 
@@ -200,27 +218,27 @@ impl Visitor for ContentVisitor {
         where D: Deserializer
     {
         Deserialize::deserialize(deserializer).map(|v| Content::Newtype(Box::new(v)))
     }
 
     fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
         where V: SeqVisitor
     {
-        let mut vec = Vec::with_capacity(visitor.size_hint().0);
+        let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096));
         while let Some(e) = try!(visitor.visit()) {
             vec.push(e);
         }
         Ok(Content::Seq(vec))
     }
 
     fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
         where V: MapVisitor
     {
-        let mut vec = Vec::with_capacity(visitor.size_hint().0);
+        let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096));
         while let Some(kv) = try!(visitor.visit()) {
             vec.push(kv);
         }
         Ok(Content::Map(vec))
     }
 
     fn visit_enum<V>(self, _visitor: V) -> Result<Self::Value, V::Error>
         where V: EnumVisitor
@@ -238,19 +256,17 @@ pub enum TagOrContent {
 }
 
 struct TagOrContentVisitor {
     name: &'static str,
 }
 
 impl TagOrContentVisitor {
     fn new(name: &'static str) -> Self {
-        TagOrContentVisitor {
-            name: name,
-        }
+        TagOrContentVisitor { name: name }
     }
 }
 
 impl DeserializeSeed for TagOrContentVisitor {
     type Value = TagOrContent;
 
     fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
         where D: Deserializer
@@ -470,45 +486,87 @@ impl<T> Visitor for TaggedContentVisitor
     fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         fmt.write_str("any value")
     }
 
     fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
         where V: MapVisitor
     {
         let mut tag = None;
-        let mut vec = Vec::with_capacity(visitor.size_hint().0);
+        let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096));
         while let Some(k) = try!(visitor.visit_key_seed(TagOrContentVisitor::new(self.tag_name))) {
             match k {
                 TagOrContent::Tag => {
                     if tag.is_some() {
                         return Err(de::Error::duplicate_field(self.tag_name));
                     }
                     tag = Some(try!(visitor.visit_value()));
                 }
                 TagOrContent::Content(k) => {
                     let v = try!(visitor.visit_value());
                     vec.push((k, v));
                 }
             }
         }
         match tag {
-            None => {
-                Err(de::Error::missing_field(self.tag_name))
-            }
+            None => Err(de::Error::missing_field(self.tag_name)),
             Some(tag) => {
                 Ok(TaggedContent {
                     tag: tag,
                     content: Content::Map(vec),
                 })
             }
         }
     }
 }
 
+/// Used by generated code to deserialize an adjacently tagged enum.
+///
+/// Not public API.
+pub enum TagOrContentField {
+    Tag,
+    Content,
+}
+
+/// Not public API.
+pub struct TagOrContentFieldVisitor {
+    pub tag: &'static str,
+    pub content: &'static str,
+}
+
+impl DeserializeSeed for TagOrContentFieldVisitor {
+    type Value = TagOrContentField;
+
+    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+        where D: Deserializer
+    {
+        deserializer.deserialize_str(self)
+    }
+}
+
+impl Visitor for TagOrContentFieldVisitor {
+    type Value = TagOrContentField;
+
+    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        write!(formatter, "{:?} or {:?}", self.tag, self.content)
+    }
+
+    fn visit_str<E>(self, field: &str) -> Result<Self::Value, E>
+        where E: de::Error
+    {
+        if field == self.tag {
+            Ok(TagOrContentField::Tag)
+        } else if field == self.content {
+            Ok(TagOrContentField::Content)
+        } else {
+            Err(de::Error::invalid_value(Unexpected::Str(field), &self))
+        }
+    }
+}
+
 /// Not public API
 pub struct ContentDeserializer<E> {
     content: Content,
     err: PhantomData<E>,
 }
 
 /// Used when deserializing an internally tagged enum because the content will
 /// be used exactly once.
@@ -539,76 +597,305 @@ impl<E> Deserializer for ContentDeserial
             Content::Some(v) => visitor.visit_some(ContentDeserializer::new(*v)),
             Content::Newtype(v) => visitor.visit_newtype_struct(ContentDeserializer::new(*v)),
             Content::Seq(v) => {
                 let seq = v.into_iter().map(ContentDeserializer::new);
                 let mut seq_visitor = de::value::SeqDeserializer::new(seq);
                 let value = try!(visitor.visit_seq(&mut seq_visitor));
                 try!(seq_visitor.end());
                 Ok(value)
-            },
+            }
             Content::Map(v) => {
-                let map = v.into_iter().map(|(k, v)| (ContentDeserializer::new(k), ContentDeserializer::new(v)));
+                let map = v.into_iter()
+                    .map(|(k, v)| (ContentDeserializer::new(k), ContentDeserializer::new(v)));
                 let mut map_visitor = de::value::MapDeserializer::new(map);
                 let value = try!(visitor.visit_map(&mut map_visitor));
                 try!(map_visitor.end());
                 Ok(value)
-            },
+            }
             Content::Bytes(v) => visitor.visit_byte_buf(v),
         }
     }
 
     fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
         where V: Visitor
     {
         match self.content {
             Content::None => visitor.visit_none(),
             Content::Some(v) => visitor.visit_some(ContentDeserializer::new(*v)),
             Content::Unit => visitor.visit_unit(),
-            _ => visitor.visit_some(self)
+            _ => visitor.visit_some(self),
         }
     }
 
     fn deserialize_newtype_struct<V>(self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
         where V: Visitor
     {
         visitor.visit_newtype_struct(self)
     }
 
+    fn deserialize_enum<V>(self, _name: &str, _variants: &'static [&'static str], visitor: V) -> Result<V::Value, Self::Error>
+        where V: Visitor,
+    {
+        let (variant, value) = match self.content {
+            Content::Map(value) => {
+                let mut iter = value.into_iter();
+                let (variant, value) = match iter.next() {
+                    Some(v) => v,
+                    None => {
+                        return Err(de::Error::invalid_value(de::Unexpected::Map, &"map with a single key"));
+                    }
+                };
+                // enums are encoded in json as maps with a single key:value pair
+                if iter.next().is_some() {
+                    return Err(de::Error::invalid_value(de::Unexpected::Map, &"map with a single key"));
+                }
+                (variant, Some(value))
+            }
+            Content::String(variant) => (Content::String(variant), None),
+            other => {
+                return Err(de::Error::invalid_type(other.unexpected(), &"string or map"));
+            }
+        };
+
+        visitor.visit_enum(EnumDeserializer {
+            variant: variant,
+            value: value,
+            err: PhantomData,
+        })
+    }
+
     forward_to_deserialize! {
         bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq
         seq_fixed_size bytes byte_buf map unit_struct tuple_struct struct
-        struct_field tuple enum ignored_any
+        struct_field tuple ignored_any
     }
 }
 
 impl<E> ContentDeserializer<E> {
     /// private API, don't use
     pub fn new(content: Content) -> Self {
         ContentDeserializer {
             content: content,
             err: PhantomData,
         }
     }
 }
 
+struct EnumDeserializer<E> where E: de::Error {
+    variant: Content,
+    value: Option<Content>,
+    err: PhantomData<E>,
+}
+
+impl<E> de::EnumVisitor for EnumDeserializer<E> where E: de::Error {
+    type Error = E;
+    type Variant = VariantDeserializer<Self::Error>;
+
+    fn visit_variant_seed<V>(self, seed: V) -> Result<(V::Value, VariantDeserializer<E>), Self::Error>
+        where V: de::DeserializeSeed,
+    {
+        let visitor = VariantDeserializer { value: self.value, err: PhantomData, };
+        seed.deserialize(ContentDeserializer::new(self.variant)).map(|v| (v, visitor))
+    }
+}
+
+struct VariantDeserializer<E> where E: de::Error {
+    value: Option<Content>,
+    err: PhantomData<E>,
+}
+
+impl<E> de::VariantVisitor for VariantDeserializer<E> where E: de::Error {
+    type Error = E;
+
+    fn visit_unit(self) -> Result<(), E> {
+        match self.value {
+            Some(value) => de::Deserialize::deserialize(ContentDeserializer::new(value)),
+            None => Ok(()),
+        }
+    }
+
+    fn visit_newtype_seed<T>(self, seed: T) -> Result<T::Value, E>
+        where T: de::DeserializeSeed
+    {
+        match self.value {
+            Some(value) => seed.deserialize(ContentDeserializer::new(value)),
+            None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"newtype variant")),
+        }
+    }
+
+    fn visit_tuple<V>(
+        self,
+        _len: usize,
+        visitor: V
+    ) -> Result<V::Value, Self::Error>
+        where V: de::Visitor
+    {
+        match self.value {
+            Some(Content::Seq(v)) => {
+                de::Deserializer::deserialize(SeqDeserializer::new(v), visitor)
+            }
+            Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"tuple variant")),
+            None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"tuple variant"))
+        }
+    }
+
+    fn visit_struct<V>(
+        self,
+        _fields: &'static [&'static str],
+        visitor: V
+    ) -> Result<V::Value, Self::Error>
+        where V: de::Visitor
+    {
+        match self.value {
+            Some(Content::Map(v)) => {
+                de::Deserializer::deserialize(MapDeserializer::new(v), visitor)
+            }
+            Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant")),
+            _ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant"))
+        }
+    }
+}
+
+struct SeqDeserializer<E> where E: de::Error {
+    iter: <Vec<Content> as IntoIterator>::IntoIter,
+    err: PhantomData<E>,
+}
+
+impl<E> SeqDeserializer<E> where E: de::Error {
+    fn new(vec: Vec<Content>) -> Self {
+        SeqDeserializer {
+            iter: vec.into_iter(),
+            err: PhantomData,
+        }
+    }
+}
+
+impl<E> de::Deserializer for SeqDeserializer<E> where E: de::Error {
+    type Error = E;
+
+    #[inline]
+    fn deserialize<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
+        where V: de::Visitor,
+    {
+        let len = self.iter.len();
+        if len == 0 {
+            visitor.visit_unit()
+        } else {
+            let ret = try!(visitor.visit_seq(&mut self));
+            let remaining = self.iter.len();
+            if remaining == 0 {
+                Ok(ret)
+            } else {
+                Err(de::Error::invalid_length(len, &"fewer elements in array"))
+            }
+        }
+    }
+
+    forward_to_deserialize! {
+        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
+        seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct
+        tuple_struct struct struct_field tuple enum ignored_any
+    }
+}
+
+impl<E> de::SeqVisitor for SeqDeserializer<E> where E: de::Error {
+    type Error = E;
+
+    fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
+        where T: de::DeserializeSeed,
+    {
+        match self.iter.next() {
+            Some(value) => seed.deserialize(ContentDeserializer::new(value)).map(Some),
+            None => Ok(None),
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.iter.size_hint()
+    }
+}
+
+struct MapDeserializer<E> where E: de::Error {
+    iter: <Vec<(Content, Content)> as IntoIterator>::IntoIter,
+    value: Option<Content>,
+    err: PhantomData<E>,
+}
+
+impl<E> MapDeserializer<E> where E: de::Error {
+    fn new(map: Vec<(Content, Content)>) -> Self {
+        MapDeserializer {
+            iter: map.into_iter(),
+            value: None,
+            err: PhantomData,
+        }
+    }
+}
+
+impl<E> de::MapVisitor for MapDeserializer<E> where E: de::Error {
+    type Error = E;
+
+    fn visit_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
+        where T: de::DeserializeSeed,
+    {
+        match self.iter.next() {
+            Some((key, value)) => {
+                self.value = Some(value);
+                seed.deserialize(ContentDeserializer::new(key)).map(Some)
+            }
+            None => Ok(None),
+        }
+    }
+
+    fn visit_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
+        where T: de::DeserializeSeed,
+    {
+        match self.value.take() {
+            Some(value) => seed.deserialize(ContentDeserializer::new(value)),
+            None => Err(de::Error::custom("value is missing")),
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.iter.size_hint()
+    }
+}
+
+impl<E> de::Deserializer for MapDeserializer<E> where E: de::Error {
+    type Error = E;
+
+    #[inline]
+    fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+        where V: de::Visitor,
+    {
+        visitor.visit_map(self)
+    }
+
+    forward_to_deserialize! {
+        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
+        seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct
+        tuple_struct struct struct_field tuple enum ignored_any
+    }
+}
+
+
 /// Not public API.
 pub struct ContentRefDeserializer<'a, E> {
     content: &'a Content,
     err: PhantomData<E>,
 }
 
 /// Used when deserializing an untagged enum because the content may need to be
 /// used more than once.
 impl<'a, E> Deserializer for ContentRefDeserializer<'a, E>
     where E: de::Error
 {
     type Error = E;
 
-    fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+    fn deserialize<V>(self, visitor: V) -> Result<V::Value, E>
         where V: Visitor
     {
         match *self.content {
             Content::Bool(v) => visitor.visit_bool(v),
             Content::U8(v) => visitor.visit_u8(v),
             Content::U16(v) => visitor.visit_u16(v),
             Content::U32(v) => visitor.visit_u32(v),
             Content::U64(v) => visitor.visit_u64(v),
@@ -625,62 +912,291 @@ impl<'a, E> Deserializer for ContentRefD
             Content::Some(ref v) => visitor.visit_some(ContentRefDeserializer::new(v)),
             Content::Newtype(ref v) => visitor.visit_newtype_struct(ContentRefDeserializer::new(v)),
             Content::Seq(ref v) => {
                 let seq = v.into_iter().map(ContentRefDeserializer::new);
                 let mut seq_visitor = de::value::SeqDeserializer::new(seq);
                 let value = try!(visitor.visit_seq(&mut seq_visitor));
                 try!(seq_visitor.end());
                 Ok(value)
-            },
+            }
             Content::Map(ref v) => {
-                let map = v.into_iter().map(|&(ref k, ref v)| (ContentRefDeserializer::new(k), ContentRefDeserializer::new(v)));
+                let map = v.into_iter().map(|&(ref k, ref v)| {
+                    (ContentRefDeserializer::new(k), ContentRefDeserializer::new(v))
+                });
                 let mut map_visitor = de::value::MapDeserializer::new(map);
                 let value = try!(visitor.visit_map(&mut map_visitor));
                 try!(map_visitor.end());
                 Ok(value)
-            },
+            }
             Content::Bytes(ref v) => visitor.visit_bytes(v),
         }
     }
 
-    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, E>
         where V: Visitor
     {
         match *self.content {
             Content::None => visitor.visit_none(),
             Content::Some(ref v) => visitor.visit_some(ContentRefDeserializer::new(v)),
             Content::Unit => visitor.visit_unit(),
-            _ => visitor.visit_some(self)
+            _ => visitor.visit_some(self),
         }
     }
 
-    fn deserialize_newtype_struct<V>(self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
+    fn deserialize_newtype_struct<V>(self, _name: &str, visitor: V) -> Result<V::Value, E>
         where V: Visitor
     {
         visitor.visit_newtype_struct(self)
     }
 
+    fn deserialize_enum<V>(self, _name: &str, _variants: &'static [&'static str], visitor: V) -> Result<V::Value, Self::Error>
+        where V: Visitor,
+    {
+        let (variant, value) = match *self.content {
+            Content::Map(ref value) => {
+                let mut iter = value.into_iter();
+                let &(ref variant, ref value) = match iter.next() {
+                    Some(v) => v,
+                    None => {
+                        return Err(de::Error::invalid_value(de::Unexpected::Map, &"map with a single key"));
+                    }
+                };
+                // enums are encoded in json as maps with a single key:value pair
+                if iter.next().is_some() {
+                    return Err(de::Error::invalid_value(de::Unexpected::Map, &"map with a single key"));
+                }
+                (variant, Some(value))
+            }
+            ref s @ Content::String(_) => (s, None),
+            ref other => {
+                return Err(de::Error::invalid_type(other.unexpected(), &"string or map"));
+            }
+        };
+
+        visitor.visit_enum(EnumRefDeserializer {
+            variant: variant,
+            value: value,
+            err: PhantomData,
+        })
+    }
+
     forward_to_deserialize! {
         bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq
         seq_fixed_size bytes byte_buf map unit_struct tuple_struct struct
-        struct_field tuple enum ignored_any
+        struct_field tuple ignored_any
     }
 }
 
 impl<'a, E> ContentRefDeserializer<'a, E> {
     /// private API, don't use
     pub fn new(content: &'a Content) -> Self {
         ContentRefDeserializer {
             content: content,
             err: PhantomData,
         }
     }
 }
 
+struct EnumRefDeserializer<'a, E> where E: de::Error {
+    variant: &'a Content,
+    value: Option<&'a Content>,
+    err: PhantomData<E>,
+}
+
+impl<'a, E> de::EnumVisitor for EnumRefDeserializer<'a, E> where E: de::Error {
+    type Error = E;
+    type Variant = VariantRefDeserializer<'a, Self::Error>;
+
+    fn visit_variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
+        where V: de::DeserializeSeed,
+    {
+        let visitor = VariantRefDeserializer { value: self.value, err: PhantomData, };
+        seed.deserialize(ContentRefDeserializer::new(self.variant)).map(|v| (v, visitor))
+    }
+}
+
+struct VariantRefDeserializer<'a, E> where E: de::Error {
+    value: Option<&'a Content>,
+    err: PhantomData<E>,
+}
+
+impl<'a, E> de::VariantVisitor for VariantRefDeserializer<'a, E> where E: de::Error {
+    type Error = E;
+
+    fn visit_unit(self) -> Result<(), E> {
+        match self.value {
+            Some(value) => de::Deserialize::deserialize(ContentRefDeserializer::new(value)),
+            None => Ok(()),
+        }
+    }
+
+    fn visit_newtype_seed<T>(self, seed: T) -> Result<T::Value, E>
+        where T: de::DeserializeSeed
+    {
+        match self.value {
+            Some(value) => seed.deserialize(ContentRefDeserializer::new(value)),
+            None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"newtype variant")),
+        }
+    }
+
+    fn visit_tuple<V>(
+        self,
+        _len: usize,
+        visitor: V
+    ) -> Result<V::Value, Self::Error>
+        where V: de::Visitor
+    {
+        match self.value {
+            Some(&Content::Seq(ref v)) => {
+                de::Deserializer::deserialize(SeqRefDeserializer::new(v), visitor)
+            }
+            Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"tuple variant")),
+            None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"tuple variant"))
+        }
+    }
+
+    fn visit_struct<V>(
+        self,
+        _fields: &'static [&'static str],
+        visitor: V
+    ) -> Result<V::Value, Self::Error>
+        where V: de::Visitor
+    {
+        match self.value {
+            Some(&Content::Map(ref v)) => {
+                de::Deserializer::deserialize(MapRefDeserializer::new(v), visitor)
+            }
+            Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant")),
+            _ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant"))
+        }
+    }
+}
+
+struct SeqRefDeserializer<'a, E> where E: de::Error {
+    iter: <&'a [Content] as IntoIterator>::IntoIter,
+    err: PhantomData<E>,
+}
+
+impl<'a, E> SeqRefDeserializer<'a, E> where E: de::Error {
+    fn new(vec: &'a [Content]) -> Self {
+        SeqRefDeserializer {
+            iter: vec.into_iter(),
+            err: PhantomData,
+        }
+    }
+}
+
+impl<'a, E> de::Deserializer for SeqRefDeserializer<'a, E> where E: de::Error {
+    type Error = E;
+
+    #[inline]
+    fn deserialize<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
+        where V: de::Visitor,
+    {
+        let len = self.iter.len();
+        if len == 0 {
+            visitor.visit_unit()
+        } else {
+            let ret = try!(visitor.visit_seq(&mut self));
+            let remaining = self.iter.len();
+            if remaining == 0 {
+                Ok(ret)
+            } else {
+                Err(de::Error::invalid_length(len, &"fewer elements in array"))
+            }
+        }
+    }
+
+    forward_to_deserialize! {
+        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
+        seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct
+        tuple_struct struct struct_field tuple enum ignored_any
+    }
+}
+
+impl<'a, E> de::SeqVisitor for SeqRefDeserializer<'a, E> where E: de::Error {
+    type Error = E;
+
+    fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
+        where T: de::DeserializeSeed,
+    {
+        match self.iter.next() {
+            Some(value) => seed.deserialize(ContentRefDeserializer::new(value)).map(Some),
+            None => Ok(None),
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.iter.size_hint()
+    }
+}
+
+struct MapRefDeserializer<'a, E> where E: de::Error {
+    iter: <&'a [(Content, Content)] as IntoIterator>::IntoIter,
+    value: Option<&'a Content>,
+    err: PhantomData<E>,
+}
+
+impl<'a, E> MapRefDeserializer<'a, E> where E: de::Error {
+    fn new(map: &'a [(Content, Content)]) -> Self {
+        MapRefDeserializer {
+            iter: map.into_iter(),
+            value: None,
+            err: PhantomData,
+        }
+    }
+}
+
+impl<'a, E> de::MapVisitor for MapRefDeserializer<'a, E> where E: de::Error {
+    type Error = E;
+
+    fn visit_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
+        where T: de::DeserializeSeed,
+    {
+        match self.iter.next() {
+            Some(&(ref key, ref value)) => {
+                self.value = Some(value);
+                seed.deserialize(ContentRefDeserializer::new(key)).map(Some)
+            }
+            None => Ok(None),
+        }
+    }
+
+    fn visit_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
+        where T: de::DeserializeSeed,
+    {
+        match self.value.take() {
+            Some(value) => seed.deserialize(ContentRefDeserializer::new(value)),
+            None => Err(de::Error::custom("value is missing")),
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.iter.size_hint()
+    }
+}
+
+impl<'a, E> de::Deserializer for MapRefDeserializer<'a, E> where E: de::Error {
+    type Error = E;
+
+    #[inline]
+    fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+        where V: de::Visitor,
+    {
+        visitor.visit_map(self)
+    }
+
+    forward_to_deserialize! {
+        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
+        seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct
+        tuple_struct struct struct_field tuple enum ignored_any
+    }
+}
+
 impl<E> de::value::ValueDeserializer<E> for ContentDeserializer<E>
     where E: de::Error
 {
     type Deserializer = Self;
 
     fn into_deserializer(self) -> Self {
         self
     }
--- a/third_party/rust/serde/src/de/impls.rs
+++ b/third_party/rust/serde/src/de/impls.rs
@@ -1,40 +1,26 @@
 //! This module contains `Deserialize` and `Visitor` implementations.
 
 #[cfg(feature = "std")]
 use std::borrow::Cow;
 #[cfg(all(feature = "collections", not(feature = "std")))]
 use collections::borrow::Cow;
 
 #[cfg(all(feature = "collections", not(feature = "std")))]
-use collections::{
-    BinaryHeap,
-    BTreeMap,
-    BTreeSet,
-    LinkedList,
-    VecDeque,
-    Vec,
-    String,
-};
+use collections::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque, Vec, String};
 
 #[cfg(feature = "std")]
-use std::collections::{
-    HashMap,
-    HashSet,
-    BinaryHeap,
-    BTreeMap,
-    BTreeSet,
-    LinkedList,
-    VecDeque,
-};
+use std::collections::{HashMap, HashSet, BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque};
 
 #[cfg(feature = "collections")]
 use collections::borrow::ToOwned;
 
+#[cfg(any(feature = "std", feature = "collections"))]
+use core::cmp;
 use core::fmt;
 #[cfg(feature = "std")]
 use core::hash::{Hash, BuildHasher};
 use core::marker::PhantomData;
 #[cfg(feature = "std")]
 use std::net;
 #[cfg(feature = "std")]
 use std::path;
@@ -58,57 +44,48 @@ use std::time::Duration;
 
 #[cfg(feature = "unstable")]
 use core::nonzero::{NonZero, Zeroable};
 
 #[cfg(feature = "unstable")]
 #[allow(deprecated)] // required for impl Deserialize for NonZero<T>
 use core::num::Zero;
 
-use de::{
-    Deserialize,
-    Deserializer,
-    EnumVisitor,
-    Error,
-    MapVisitor,
-    SeqVisitor,
-    Unexpected,
-    VariantVisitor,
-    Visitor,
-};
+use de::{Deserialize, Deserializer, EnumVisitor, Error, MapVisitor, SeqVisitor, Unexpected,
+         VariantVisitor, Visitor};
 use de::from_primitive::FromPrimitive;
 
 ///////////////////////////////////////////////////////////////////////////////
 
 /// A visitor that produces a `()`.
 pub struct UnitVisitor;
 
 impl Visitor for UnitVisitor {
     type Value = ();
 
     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         formatter.write_str("unit")
     }
 
     fn visit_unit<E>(self) -> Result<(), E>
-        where E: Error,
+        where E: Error
     {
         Ok(())
     }
 
     fn visit_seq<V>(self, _: V) -> Result<(), V::Error>
-        where V: SeqVisitor,
+        where V: SeqVisitor
     {
         Ok(())
     }
 }
 
 impl Deserialize for () {
     fn deserialize<D>(deserializer: D) -> Result<(), D::Error>
-        where D: Deserializer,
+        where D: Deserializer
     {
         deserializer.deserialize_unit(UnitVisitor)
     }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 /// A visitor that produces a `bool`.
@@ -117,35 +94,35 @@ pub struct BoolVisitor;
 impl Visitor for BoolVisitor {
     type Value = bool;
 
     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         formatter.write_str("a boolean")
     }
 
     fn visit_bool<E>(self, v: bool) -> Result<bool, E>
-        where E: Error,
+        where E: Error
     {
         Ok(v)
     }
 
     fn visit_str<E>(self, s: &str) -> Result<bool, E>
-        where E: Error,
+        where E: Error
     {
         match s.trim_matches(::utils::Pattern_White_Space) {
             "true" => Ok(true),
             "false" => Ok(false),
             _ => Err(Error::invalid_type(Unexpected::Str(s), &self)),
         }
     }
 }
 
 impl Deserialize for bool {
     fn deserialize<D>(deserializer: D) -> Result<bool, D::Error>
-        where D: Deserializer,
+        where D: Deserializer
     {
         deserializer.deserialize_bool(BoolVisitor)
     }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 macro_rules! impl_deserialize_num_method {
@@ -226,37 +203,37 @@ impl Visitor for CharVisitor {
     type Value = char;
 
     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         formatter.write_str("a character")
     }
 
     #[inline]
     fn visit_char<E>(self, v: char) -> Result<char, E>
-        where E: Error,
+        where E: Error
     {
         Ok(v)
     }
 
     #[inline]
     fn visit_str<E>(self, v: &str) -> Result<char, E>
-        where E: Error,
+        where E: Error
     {
         let mut iter = v.chars();
         match (iter.next(), iter.next()) {
             (Some(c), None) => Ok(c),
             _ => Err(Error::invalid_value(Unexpected::Str(v), &self)),
         }
     }
 }
 
 impl Deserialize for char {
     #[inline]
     fn deserialize<D>(deserializer: D) -> Result<char, D::Error>
-        where D: Deserializer,
+        where D: Deserializer
     {
         deserializer.deserialize_char(CharVisitor)
     }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 #[cfg(any(feature = "std", feature = "collections"))]
@@ -266,101 +243,101 @@ struct StringVisitor;
 impl Visitor for StringVisitor {
     type Value = String;
 
     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         formatter.write_str("a string")
     }
 
     fn visit_str<E>(self, v: &str) -> Result<String, E>
-        where E: Error,
+        where E: Error
     {
         Ok(v.to_owned())
     }
 
     fn visit_string<E>(self, v: String) -> Result<String, E>
-        where E: Error,
+        where E: Error
     {
         Ok(v)
     }
 
     fn visit_unit<E>(self) -> Result<String, E>
-        where E: Error,
+        where E: Error
     {
         Ok(String::new())
     }
 
     fn visit_bytes<E>(self, v: &[u8]) -> Result<String, E>
-        where E: Error,
+        where E: Error
     {
         match str::from_utf8(v) {
             Ok(s) => Ok(s.to_owned()),
             Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)),
         }
     }
 
     fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<String, E>
-        where E: Error,
+        where E: Error
     {
         match String::from_utf8(v) {
             Ok(s) => Ok(s),
             Err(e) => Err(Error::invalid_value(Unexpected::Bytes(&e.into_bytes()), &self)),
         }
     }
 }
 
 #[cfg(any(feature = "std", feature = "collections"))]
 impl Deserialize for String {
     fn deserialize<D>(deserializer: D) -> Result<String, D::Error>
-        where D: Deserializer,
+        where D: Deserializer
     {
         deserializer.deserialize_string(StringVisitor)
     }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 struct OptionVisitor<T> {
     marker: PhantomData<T>,
 }
 
-impl<
-    T: Deserialize,
-> Visitor for OptionVisitor<T> {
+impl<T: Deserialize> Visitor for OptionVisitor<T> {
     type Value = Option<T>;
 
     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         formatter.write_str("option")
     }
 
     #[inline]
     fn visit_unit<E>(self) -> Result<Option<T>, E>
-        where E: Error,
+        where E: Error
     {
         Ok(None)
     }
 
     #[inline]
     fn visit_none<E>(self) -> Result<Option<T>, E>
-        where E: Error,
+        where E: Error
     {
         Ok(None)
     }
 
     #[inline]
     fn visit_some<D>(self, deserializer: D) -> Result<Option<T>, D::Error>
-        where D: Deserializer,
+        where D: Deserializer
     {
         Ok(Some(try!(Deserialize::deserialize(deserializer))))
     }
 }
 
-impl<T> Deserialize for Option<T> where T: Deserialize {
+impl<T> Deserialize for Option<T>
+    where T: Deserialize
+{
     fn deserialize<D>(deserializer: D) -> Result<Option<T>, D::Error>
-        where D: Deserializer,
+        where D: Deserializer
     {
         deserializer.deserialize_option(OptionVisitor { marker: PhantomData })
     }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 /// A visitor that produces a `PhantomData`.
@@ -372,25 +349,25 @@ impl<T> Visitor for PhantomDataVisitor<T
     type Value = PhantomData<T>;
 
     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         formatter.write_str("unit")
     }
 
     #[inline]
     fn visit_unit<E>(self) -> Result<PhantomData<T>, E>
-        where E: Error,
+        where E: Error
     {
         Ok(PhantomData)
     }
 }
 
 impl<T> Deserialize for PhantomData<T> {
     fn deserialize<D>(deserializer: D) -> Result<PhantomData<T>, D::Error>
-        where D: Deserializer,
+        where D: Deserializer
     {
         let visitor = PhantomDataVisitor { marker: PhantomData };
         deserializer.deserialize_unit_struct("PhantomData", visitor)
     }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -462,17 +439,17 @@ macro_rules! seq_impl {
 }
 
 #[cfg(any(feature = "std", feature = "collections"))]
 seq_impl!(
     BinaryHeap<T>,
     BinaryHeapVisitor<T: Deserialize + Ord>,
     visitor,
     BinaryHeap::new(),
-    BinaryHeap::with_capacity(visitor.size_hint().0),
+    BinaryHeap::with_capacity(cmp::min(visitor.size_hint().0, 4096)),
     BinaryHeap::push);
 
 #[cfg(any(feature = "std", feature = "collections"))]
 seq_impl!(
     BTreeSet<T>,
     BTreeSetVisitor<T: Deserialize + Eq + Ord>,
     visitor,
     BTreeSet::new(),
@@ -490,78 +467,78 @@ seq_impl!(
 
 #[cfg(feature = "std")]
 seq_impl!(
     HashSet<T, S>,
     HashSetVisitor<T: Deserialize + Eq + Hash,
                    S: BuildHasher + Default>,
     visitor,
     HashSet::with_hasher(S::default()),
-    HashSet::with_capacity_and_hasher(visitor.size_hint().0, S::default()),
+    HashSet::with_capacity_and_hasher(cmp::min(visitor.size_hint().0, 4096), S::default()),
     HashSet::insert);
 
 #[cfg(any(feature = "std", feature = "collections"))]
 seq_impl!(
     Vec<T>,
     VecVisitor<T: Deserialize>,
     visitor,
     Vec::new(),
-    Vec::with_capacity(visitor.size_hint().0),
+    Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)),
     Vec::push);
 
 #[cfg(any(feature = "std", feature = "collections"))]
 seq_impl!(
     VecDeque<T>,
     VecDequeVisitor<T: Deserialize>,
     visitor,
     VecDeque::new(),
-    VecDeque::with_capacity(visitor.size_hint().0),
+    VecDeque::with_capacity(cmp::min(visitor.size_hint().0, 4096)),
     VecDeque::push_back);
 
 ///////////////////////////////////////////////////////////////////////////////
 
 struct ArrayVisitor<A> {
     marker: PhantomData<A>,
 }
 
 impl<A> ArrayVisitor<A> {
     pub fn new() -> Self {
-        ArrayVisitor {
-            marker: PhantomData,
-        }
+        ArrayVisitor { marker: PhantomData }
     }
 }
 
-impl<T> Visitor for ArrayVisitor<[T; 0]> where T: Deserialize {
+impl<T> Visitor for ArrayVisitor<[T; 0]>
+    where T: Deserialize
+{
     type Value = [T; 0];
 
     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         formatter.write_str("an empty array")
     }
 
     #[inline]
     fn visit_unit<E>(self) -> Result<[T; 0], E>
-        where E: Error,
+        where E: Error
     {
         Ok([])
     }
 
     #[inline]
     fn visit_seq<V>(self, _: V) -> Result<[T; 0], V::Error>
-        where V: SeqVisitor,
+        where V: SeqVisitor
     {
         Ok([])
     }
 }
 
 impl<T> Deserialize for [T; 0]
     where T: Deserialize
 {
     fn deserialize<D>(deserializer: D) -> Result<[T; 0], D::Error>
-        where D: Deserializer,
+        where D: Deserializer
     {
         deserializer.deserialize_seq_fixed_size(0, ArrayVisitor::<[T; 0]>::new())
     }
 }
 
 macro_rules! array_impls {
     ($($len:expr => ($($n:tt $name:ident)+))+) => {
         $(
@@ -786,91 +763,91 @@ map_impl!(
 #[cfg(feature = "std")]
 map_impl!(
     HashMap<K, V, S>,
     HashMapVisitor<K: Deserialize + Eq + Hash,
                    V: Deserialize,
                    S: BuildHasher + Default>,
     visitor,
     HashMap::with_hasher(S::default()),
-    HashMap::with_capacity_and_hasher(visitor.size_hint().0, S::default()));
+    HashMap::with_capacity_and_hasher(cmp::min(visitor.size_hint().0, 4096), S::default()));
 
 ///////////////////////////////////////////////////////////////////////////////
 
 #[cfg(feature = "std")]
 impl Deserialize for net::IpAddr {
     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-        where D: Deserializer,
+        where D: Deserializer
     {
         let s = try!(String::deserialize(deserializer));
         match s.parse() {
             Ok(s) => Ok(s),
             Err(err) => Err(D::Error::custom(err)),
         }
     }
 }
 
 #[cfg(feature = "std")]
 impl Deserialize for net::Ipv4Addr {
     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-        where D: Deserializer,
+        where D: Deserializer
     {
         let s = try!(String::deserialize(deserializer));
         match s.parse() {
             Ok(s) => Ok(s),
             Err(err) => Err(D::Error::custom(err)),
         }
     }
 }
 
 #[cfg(feature = "std")]
 impl Deserialize for net::Ipv6Addr {
     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-        where D: Deserializer,
+        where D: Deserializer
     {
         let s = try!(String::deserialize(deserializer));
         match s.parse() {
             Ok(s) => Ok(s),
             Err(err) => Err(D::Error::custom(err)),
         }
     }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 #[cfg(feature = "std")]
 impl Deserialize for net::SocketAddr {
     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-        where D: Deserializer,
+        where D: Deserializer
     {
         let s = try!(String::deserialize(deserializer));
         match s.parse() {
             Ok(s) => Ok(s),
             Err(err) => Err(D::Error::custom(err)),
         }
     }
 }
 
 #[cfg(feature = "std")]
 impl Deserialize for net::SocketAddrV4 {
     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-        where D: Deserializer,
+        where D: Deserializer
     {
         let s = try!(String::deserialize(deserializer));
         match s.parse() {
             Ok(s) => Ok(s),
             Err(err) => Err(D::Error::custom(err)),
         }
     }
 }
 
 #[cfg(feature = "std")]
 impl Deserialize for net::SocketAddrV6 {
     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-        where D: Deserializer,
+        where D: Deserializer
     {
         let s = try!(String::deserialize(deserializer));
         match s.parse() {
             Ok(s) => Ok(s),
             Err(err) => Err(D::Error::custom(err)),
         }
     }
 }
@@ -884,53 +861,53 @@ struct PathBufVisitor;
 impl Visitor for PathBufVisitor {
     type Value = path::PathBuf;
 
     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         formatter.write_str("path string")
     }
 
     fn visit_str<E>(self, v: &str) -> Result<path::PathBuf, E>
-        where E: Error,
+        where E: Error
     {
         Ok(From::from(v))
     }
 
     fn visit_string<E>(self, v: String) -> Result<path::PathBuf, E>
-        where E: Error,
+        where E: Error
     {
         Ok(From::from(v))
     }
 }
 
 #[cfg(feature = "std")]
 impl Deserialize for path::PathBuf {
     fn deserialize<D>(deserializer: D) -> Result<path::PathBuf, D::Error>
-        where D: Deserializer,
+        where D: Deserializer
     {
         deserializer.deserialize_string(PathBufVisitor)
     }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 #[cfg(any(feature = "std", feature = "alloc"))]
 impl<T: Deserialize> Deserialize for Box<T> {
     fn deserialize<D>(deserializer: D) -> Result<Box<T>, D::Error>
-        where D: Deserializer,
+        where D: Deserializer
     {
         let val = try!(Deserialize::deserialize(deserializer));
         Ok(Box::new(val))
     }
 }
 
 #[cfg(any(feature = "std", feature = "collections"))]
 impl<T: Deserialize> Deserialize for Box<[T]> {
     fn deserialize<D>(deserializer: D) -> Result<Box<[T]>, D::Error>
-        where D: Deserializer,
+        where D: Deserializer
     {
         let v: Vec<T> = try!(Deserialize::deserialize(deserializer));
         Ok(v.into_boxed_slice())
     }
 }
 
 #[cfg(any(feature = "std", feature = "collections"))]
 impl Deserialize for Box<str> {
@@ -940,38 +917,41 @@ impl Deserialize for Box<str> {
         let s = try!(String::deserialize(deserializer));
         Ok(s.into_boxed_str())
     }
 }
 
 #[cfg(any(feature = "std", feature = "alloc"))]
 impl<T: Deserialize> Deserialize for Arc<T> {
     fn deserialize<D>(deserializer: D) -> Result<Arc<T>, D::Error>
-        where D: Deserializer,
+        where D: Deserializer
     {
         let val = try!(Deserialize::deserialize(deserializer));
         Ok(Arc::new(val))
     }
 }
 
 #[cfg(any(feature = "std", feature = "alloc"))]
 impl<T: Deserialize> Deserialize for Rc<T> {
     fn deserialize<D>(deserializer: D) -> Result<Rc<T>, D::Error>
-        where D: Deserializer,
+        where D: Deserializer
     {
         let val = try!(Deserialize::deserialize(deserializer));
         Ok(Rc::new(val))
     }
 }
 
 #[cfg(any(feature = "std", feature = "collections"))]
-impl<'a, T: ?Sized> Deserialize for Cow<'a, T> where T: ToOwned, T::Owned: Deserialize, {
+impl<'a, T: ?Sized> Deserialize for Cow<'a, T>
+    where T: ToOwned,
+          T::Owned: Deserialize
+{
     #[inline]
     fn deserialize<D>(deserializer: D) -> Result<Cow<'a, T>, D::Error>
-        where D: Deserializer,
+        where D: Deserializer
     {
         let val = try!(Deserialize::deserialize(deserializer));
         Ok(Cow::Owned(val))
     }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -981,45 +961,48 @@ impl<'a, T: ?Sized> Deserialize for Cow<
 //     #[serde(deny_unknown_fields)]
 //     struct Duration {
 //         secs: u64,
 //         nanos: u32,
 //     }
 #[cfg(feature = "std")]
 impl Deserialize for Duration {
     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-        where D: Deserializer,
+        where D: Deserializer
     {
-        enum Field { Secs, Nanos };
+        enum Field {
+            Secs,
+            Nanos,
+        };
 
         impl Deserialize for Field {
             fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
-                where D: Deserializer,
+                where D: Deserializer
             {
                 struct FieldVisitor;
 
                 impl Visitor for FieldVisitor {
                     type Value = Field;
 
                     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                         formatter.write_str("`secs` or `nanos`")
                     }
 
                     fn visit_str<E>(self, value: &str) -> Result<Field, E>
-                        where E: Error,
+                        where E: Error
                     {
                         match value {
                             "secs" => Ok(Field::Secs),
                             "nanos" => Ok(Field::Nanos),
                             _ => Err(Error::unknown_field(value, FIELDS)),
                         }
                     }
 
                     fn visit_bytes<E>(self, value: &[u8]) -> Result<Field, E>
-                        where E: Error,
+                        where E: Error
                     {
                         match value {
                             b"secs" => Ok(Field::Secs),
                             b"nanos" => Ok(Field::Nanos),
                             _ => {
                                 let value = String::from_utf8_lossy(value);
                                 Err(Error::unknown_field(&value, FIELDS))
                             }
@@ -1036,17 +1019,17 @@ impl Deserialize for Duration {
         impl Visitor for DurationVisitor {
             type Value = Duration;
 
             fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                 formatter.write_str("struct Duration")
             }
 
             fn visit_seq<V>(self, mut visitor: V) -> Result<Duration, V::Error>
-                where V: SeqVisitor,
+                where V: SeqVisitor
             {
                 let secs: u64 = match try!(visitor.visit()) {
                     Some(value) => value,
                     None => {
                         return Err(Error::invalid_length(0, &self));
                     }
                 };
                 let nanos: u32 = match try!(visitor.visit()) {
@@ -1054,17 +1037,17 @@ impl Deserialize for Duration {
                     None => {
                         return Err(Error::invalid_length(1, &self));
                     }
                 };
                 Ok(Duration::new(secs, nanos))
             }
 
             fn visit_map<V>(self, mut visitor: V) -> Result<Duration, V::Error>
-                where V: MapVisitor,
+                where V: MapVisitor
             {
                 let mut secs: Option<u64> = None;
                 let mut nanos: Option<u32> = None;
                 while let Some(key) = try!(visitor.visit_key::<Field>()) {
                     match key {
                         Field::Secs => {
                             if secs.is_some() {
                                 return Err(<V::Error as Error>::duplicate_field("secs"));
@@ -1095,34 +1078,40 @@ impl Deserialize for Duration {
         deserializer.deserialize_struct("Duration", FIELDS, DurationVisitor)
     }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 #[cfg(feature = "unstable")]
 #[allow(deprecated)] // num::Zero is deprecated but there is no replacement
-impl<T> Deserialize for NonZero<T> where T: Deserialize + PartialEq + Zeroable + Zero {
-    fn deserialize<D>(deserializer: D) -> Result<NonZero<T>, D::Error> where D: Deserializer {
+impl<T> Deserialize for NonZero<T>
+    where T: Deserialize + PartialEq + Zeroable + Zero
+{
+    fn deserialize<D>(deserializer: D) -> Result<NonZero<T>, D::Error>
+        where D: Deserializer
+    {
         let value = try!(Deserialize::deserialize(deserializer));
         if value == Zero::zero() {
-            return Err(Error::custom("expected a non-zero value"))
+            return Err(Error::custom("expected a non-zero value"));
         }
-        unsafe {
-            Ok(NonZero::new(value))
-        }
+        unsafe { Ok(NonZero::new(value)) }
     }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 
-impl<T, E> Deserialize for Result<T, E> where T: Deserialize, E: Deserialize {
+impl<T, E> Deserialize for Result<T, E>
+    where T: Deserialize,
+          E: Deserialize
+{
     fn deserialize<D>(deserializer: D) -> Result<Result<T, E>, D::Error>
-                      where D: Deserializer {
+        where D: Deserializer
+    {
         enum Field {
             Ok,
             Err,
         }
 
         impl Deserialize for Field {
             #[inline]
             fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
@@ -1132,40 +1121,50 @@ impl<T, E> Deserialize for Result<T, E> 
 
                 impl Visitor for FieldVisitor {
                     type Value = Field;
 
                     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                         formatter.write_str("`Ok` or `Err`")
                     }
 
-                    fn visit_u32<E>(self, value: u32) -> Result<Field, E> where E: Error {
+                    fn visit_u32<E>(self, value: u32) -> Result<Field, E>
+                        where E: Error
+                    {
                         match value {
                             0 => Ok(Field::Ok),
                             1 => Ok(Field::Err),
-                            _ => Err(Error::invalid_value(Unexpected::Unsigned(value as u64), &self)),
+                            _ => {
+                                Err(Error::invalid_value(Unexpected::Unsigned(value as u64), &self))
+                            }
                         }
                     }
 
-                    fn visit_str<E>(self, value: &str) -> Result<Field, E> where E: Error {
+                    fn visit_str<E>(self, value: &str) -> Result<Field, E>
+                        where E: Error
+                    {
                         match value {
                             "Ok" => Ok(Field::Ok),
                             "Err" => Ok(Field::Err),
                             _ => Err(Error::unknown_variant(value, VARIANTS)),
                         }
                     }
 
-                    fn visit_bytes<E>(self, value: &[u8]) -> Result<Field, E> where E: Error {
+                    fn visit_bytes<E>(self, value: &[u8]) -> Result<Field, E>
+                        where E: Error
+                    {
                         match value {
                             b"Ok" => Ok(Field::Ok),
                             b"Err" => Ok(Field::Err),
                             _ => {
                                 match str::from_utf8(value) {
                                     Ok(value) => Err(Error::unknown_variant(value, VARIANTS)),
-                                    Err(_) => Err(Error::invalid_value(Unexpected::Bytes(value), &self)),
+                                    Err(_) => {
+                                        Err(Error::invalid_value(Unexpected::Bytes(value), &self))
+                                    }
                                 }
                             }
                         }
                     }
                 }
 
                 deserializer.deserialize(FieldVisitor)
             }
@@ -1203,17 +1202,17 @@ impl<T, E> Deserialize for Result<T, E> 
 
 /// A target for deserializers that want to ignore data. Implements
 /// Deserialize and silently eats data given to it.
 pub struct IgnoredAny;
 
 impl Deserialize for IgnoredAny {
     #[inline]
     fn deserialize<D>(deserializer: D) -> Result<IgnoredAny, D::Error>
-        where D: Deserializer,
+        where D: Deserializer
     {
         struct IgnoredAnyVisitor;
 
         impl Visitor for IgnoredAnyVisitor {
             type Value = IgnoredAny;
 
             fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                 formatter.write_str("anything at all")
@@ -1236,68 +1235,68 @@ impl Deserialize for IgnoredAny {
 
             #[inline]
             fn visit_f64<E>(self, _: f64) -> Result<IgnoredAny, E> {
                 Ok(IgnoredAny)
             }
 
             #[inline]
             fn visit_str<E>(self, _: &str) -> Result<IgnoredAny, E>
-                where E: Error,
+                where E: Error
             {
                 Ok(IgnoredAny)
             }
 
             #[inline]
             fn visit_none<E>(self) -> Result<IgnoredAny, E> {
                 Ok(IgnoredAny)
             }
 
             #[inline]
             fn visit_some<D>(self, _: D) -> Result<IgnoredAny, D::Error>
-                where D: Deserializer,
+                where D: Deserializer
             {
                 Ok(IgnoredAny)
             }
 
             #[inline]
             fn visit_newtype_struct<D>(self, _: D) -> Result<IgnoredAny, D::Error>
-                where D: Deserializer,
+                where D: Deserializer
             {
                 Ok(IgnoredAny)
             }
 
             #[inline]
             fn visit_unit<E>(self) -> Result<IgnoredAny, E> {
                 Ok(IgnoredAny)
             }
 
             #[inline]
             fn visit_seq<V>(self, mut visitor: V) -> Result<IgnoredAny, V::Error>
-                where V: SeqVisitor,
+                where V: SeqVisitor
             {
                 while let Some(_) = try!(visitor.visit::<IgnoredAny>()) {
                     // Gobble
                 }
                 Ok(IgnoredAny)
             }
 
             #[inline]
             fn visit_map<V>(self, mut visitor: V) -> Result<IgnoredAny, V::Error>
-                where V: MapVisitor,
+                where V: MapVisitor
             {
                 while let Some((_, _)) = try!(visitor.visit::<IgnoredAny, IgnoredAny>()) {
                     // Gobble
                 }
                 Ok(IgnoredAny)
             }
 
             #[inline]
             fn visit_bytes<E>(self, _: &[u8]) -> Result<IgnoredAny, E>
-                where E: Error,
+                where E: Error
             {
                 Ok(IgnoredAny)
             }
         }
 
         // TODO maybe not necessary with impl specialization
         deserializer.deserialize_ignored_any(IgnoredAnyVisitor)
     }
--- a/third_party/rust/serde/src/de/mod.rs
+++ b/third_party/rust/serde/src/de/mod.rs
@@ -176,17 +176,20 @@ pub trait Error: Sized + error::Error {
             unexp: Unexpected<'a>,
             exp: &'a Expected,
         }
         impl<'a> Display for InvalidType<'a> {
             fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                 write!(formatter, "invalid type: {}, expected {}", self.unexp, self.exp)
             }
         }
-        Error::custom(InvalidType { unexp: unexp, exp: exp })
+        Error::custom(InvalidType {
+            unexp: unexp,
+            exp: exp,
+        })
     }
 
     /// Raised when a `Deserialize` receives a value of the right type but that
     /// is wrong for some other reason.
     ///
     /// The `unexp` argument provides information about what value was received.
     /// This is the value that was present in the input file or other source
     /// data of the Deserializer.
@@ -202,17 +205,20 @@ pub trait Error: Sized + error::Error {
             unexp: Unexpected<'a>,
             exp: &'a Expected,
         }
         impl<'a> Display for InvalidValue<'a> {
             fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                 write!(formatter, "invalid value: {}, expected {}", self.unexp, self.exp)
             }
         }
-        Error::custom(InvalidValue { unexp: unexp, exp: exp })
+        Error::custom(InvalidValue {
+            unexp: unexp,
+            exp: exp,
+        })
     }
 
     /// Raised when deserializing a sequence or map and the input data contains
     /// too many or too few elements.
     ///
     /// The `len` argument is the number of elements encountered. The sequence
     /// or map may have expected more arguments or fewer arguments.
     ///
@@ -224,17 +230,20 @@ pub trait Error: Sized + error::Error {
             len: usize,
             exp: &'a Expected,
         }
         impl<'a> Display for InvalidLength<'a> {
             fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                 write!(formatter, "invalid length {}, expected {}", self.len, self.exp)
             }
         }
-        Error::custom(InvalidLength { len: len, exp: exp })
+        Error::custom(InvalidLength {
+            len: len,
+            exp: exp,
+        })
     }
 
     /// Raised when a `Deserialize` enum type received a variant with an
     /// unrecognized name.
     fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self {
         struct UnknownVariant<'a> {
             variant: &'a str,
             expected: &'static [&'static str],
@@ -248,17 +257,20 @@ pub trait Error: Sized + error::Error {
                 } else {
                     write!(formatter,
                            "unknown variant `{}`, expected {}",
                            self.variant,
                            OneOf { names: self.expected })
                 }
             }
         }
-        Error::custom(UnknownVariant { variant: variant, expected: expected })
+        Error::custom(UnknownVariant {
+            variant: variant,
+            expected: expected,
+        })
     }
 
     /// Raised when a `Deserialize` struct type received a field with an
     /// unrecognized name.
     fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self {
         struct UnknownField<'a> {
             field: &'a str,
             expected: &'static [&'static str],
@@ -272,17 +284,20 @@ pub trait Error: Sized + error::Error {
                 } else {
                     write!(formatter,
                            "unknown field `{}`, expected {}",
                            self.field,
                            OneOf { names: self.expected })
                 }
             }
         }
-        Error::custom(UnknownField { field: field, expected: expected })
+        Error::custom(UnknownField {
+            field: field,
+            expected: expected,
+        })
     }
 
     /// Raised when a `Deserialize` struct type expected to receive a required
     /// field with a particular name but that field was not present in the
     /// input.
     fn missing_field(field: &'static str) -> Self {
         struct MissingField {
             field: &'static str,
@@ -465,17 +480,19 @@ impl<'a> fmt::Display for Unexpected<'a>
 /// # }
 /// ```
 pub trait Expected {
     /// Format an explanation of what data was being expected. Same signature as
     /// the `Display` and `Debug` traits.
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result;
 }
 
-impl<T> Expected for T where T: Visitor {
+impl<T> Expected for T
+    where T: Visitor
+{
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         self.expecting(formatter)
     }
 }
 
 impl<'a> Expected for &'a str {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         formatter.write_str(self)
@@ -516,18 +533,17 @@ impl<'a> Display for Expected + 'a {
 /// [impl-deserialize]: https://serde.rs/impl-deserialize.html
 pub trait Deserialize: Sized {
     /// Deserialize this value from the given Serde deserializer.
     ///
     /// See the [Implementing `Deserialize`][impl-deserialize] section of the
     /// manual for more information about how to implement this method.
     ///
     /// [impl-deserialize]: https://serde.rs/impl-deserialize.html
-    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-        where D: Deserializer;
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer;
 }
 
 /// `DeserializeSeed` is the stateful form of the `Deserialize` trait. If you
 /// ever find yourself looking for a way to pass data into a `Deserialize` impl,
 /// this trait is the way to do it.
 ///
 /// As one example of stateful deserialization consider deserializing a JSON
 /// array into an existing buffer. Using the `Deserialize` trait we could
@@ -665,18 +681,17 @@ pub trait Deserialize: Sized {
 /// # Ok(()) }
 /// ```
 pub trait DeserializeSeed: Sized {
     /// The type produced by using this seed.
     type Value;
 
     /// Equivalent to the more common `Deserialize::deserialize` method, except
     /// with some initial piece of data (the seed) passed in.
-    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
-        where D: Deserializer;
+    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> where D: Deserializer;
 }
 
 impl<T> DeserializeSeed for PhantomData<T>
     where T: Deserialize
 {
     type Value = T;
 
     #[inline]
@@ -779,180 +794,165 @@ pub trait Deserializer: Sized {
     /// on what data type is in the input.
     ///
     /// When implementing `Deserialize`, you should avoid relying on
     /// `Deserializer::deserialize` unless you need to be told by the
     /// Deserializer what type is in the input. Know that relying on
     /// `Deserializer::deserialize` means your data type will be able to
     /// deserialize from self-describing formats only, ruling out Bincode and
     /// many others.
-    fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
-        where V: Visitor;
+    fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting a `bool` value.
-    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
-        where V: Visitor;
+    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting a `u8` value.
-    fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
-        where V: Visitor;
+    fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting a `u16` value.
-    fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
-        where V: Visitor;
+    fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting a `u32` value.
-    fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
-        where V: Visitor;
+    fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting a `u64` value.
-    fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
-        where V: Visitor;
+    fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting an `i8` value.
-    fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
-        where V: Visitor;
+    fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting an `i16` value.
-    fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
-        where V: Visitor;
+    fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting an `i32` value.
-    fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
-        where V: Visitor;
+    fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting an `i64` value.
-    fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
-        where V: Visitor;
+    fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting a `f32` value.
-    fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
-        where V: Visitor;
+    fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting a `f64` value.
-    fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
-        where V: Visitor;
+    fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting a `char` value.
-    fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
-        where V: Visitor;
+    fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting a string value and does
     /// not benefit from taking ownership of buffered data owned by the
     /// `Deserializer`.
     ///
     /// If the `Visitor` would benefit from taking ownership of `String` data,
     /// indiciate this to the `Deserializer` by using `deserialize_string`
     /// instead.
-    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
-        where V: Visitor;
+    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting a string value and would
     /// benefit from taking ownership of buffered data owned by the
     /// `Deserializer`.
     ///
     /// If the `Visitor` would not benefit from taking ownership of `String`
     /// data, indicate that to the `Deserializer` by using `deserialize_str`
     /// instead.
-    fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
-        where V: Visitor;
+    fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting a byte array and does not
     /// benefit from taking ownership of buffered data owned by the
     /// `Deserializer`.
     ///
     /// If the `Visitor` would benefit from taking ownership of `Vec<u8>` data,
     /// indicate this to the `Deserializer` by using `deserialize_byte_buf`
     /// instead.
-    fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
-        where V: Visitor;
+    fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting a byte array and would
     /// benefit from taking ownership of buffered data owned by the
     /// `Deserializer`.
     ///
     /// If the `Visitor` would not benefit from taking ownership of `Vec<u8>`
     /// data, indicate that to the `Deserializer` by using `deserialize_bytes`
     /// instead.
-    fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
-        where V: Visitor;
+    fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting an optional value.
     ///
     /// This allows deserializers that encode an optional value as a nullable
     /// value to convert the null value into `None` and a regular value into
     /// `Some(value)`.
-    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
-        where V: Visitor;
+    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting a unit value.
-    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
-        where V: Visitor;
+    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting a unit struct with a
     /// particular name.
     fn deserialize_unit_struct<V>(self,
                                   name: &'static str,
-                                  visitor: V) -> Result<V::Value, Self::Error>
+                                  visitor: V)
+                                  -> Result<V::Value, Self::Error>
         where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting a newtype struct with a
     /// particular name.
     fn deserialize_newtype_struct<V>(self,
                                      name: &'static str,
-                                     visitor: V) -> Result<V::Value, Self::Error>
+                                     visitor: V)
+                                     -> Result<V::Value, Self::Error>
         where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting a sequence of values.
-    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
-        where V: Visitor;
+    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting a sequence of values and
     /// knows how many values there are without looking at the serialized data.
     fn deserialize_seq_fixed_size<V>(self,
                                      len: usize,
-                                     visitor: V) -> Result<V::Value, Self::Error>
+                                     visitor: V)
+                                     -> Result<V::Value, Self::Error>
         where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting a tuple value with a
     /// particular number of elements.
     fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
         where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting a tuple struct with a
     /// particular name and number of fields.
     fn deserialize_tuple_struct<V>(self,
                                    name: &'static str,
                                    len: usize,
-                                   visitor: V) -> Result<V::Value, Self::Error>
+                                   visitor: V)
+                                   -> Result<V::Value, Self::Error>
         where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting a map of key-value pairs.
-    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
-        where V: Visitor;
+    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting a struct with a particular
     /// name and fields.
     fn deserialize_struct<V>(self,
                              name: &'static str,
                              fields: &'static [&'static str],
-                             visitor: V) -> Result<V::Value, Self::Error>
+                             visitor: V)
+                             -> Result<V::Value, Self::Error>
         where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting the name of a struct
     /// field.
     fn deserialize_struct_field<V>(self, visitor: V) -> Result<V::Value, Self::Error>
         where V: Visitor;
 
     /// Hint that the `Deserialize` type is expecting an enum value with a
     /// particular name and possible variants.
     fn deserialize_enum<V>(self,
                            name: &'static str,
                            variants: &'static [&'static str],
-                           visitor: V) -> Result<V::Value, Self::Error>
+                           visitor: V)
+                           -> Result<V::Value, Self::Error>
         where V: Visitor;
 
     /// Hint that the `Deserialize` type needs to deserialize a value whose type
     /// doesn't matter because it is ignored.
     ///
     /// Deserializers for non-self-describing formats may not support this mode.
     fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
         where V: Visitor;
@@ -1011,111 +1011,111 @@ pub trait Visitor: Sized {
     ///     write!(formatter, "an integer between 0 and {}", self.max)
     /// }
     /// # }
     /// ```
     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result;
 
     /// Deserialize a `bool` into a `Value`.
     fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
-        where E: Error,
+        where E: Error
     {
         Err(Error::invalid_type(Unexpected::Bool(v), &self))
     }
 
     /// Deserialize an `i8` into a `Value`.
     fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>
-        where E: Error,
+        where E: Error
     {
         self.visit_i64(v as i64)
     }
 
     /// Deserialize an `i16` into a `Value`.
     fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E>
-        where E: Error,
+        where E: Error
     {
         self.visit_i64(v as i64)
     }
 
     /// Deserialize an `i32` into a `Value`.
     fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
-        where E: Error,
+        where E: Error
     {
         self.visit_i64(v as i64)
     }
 
     /// Deserialize an `i64` into a `Value`.
     fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
-        where E: Error,
+        where E: Error
     {
         Err(Error::invalid_type(Unexpected::Signed(v), &self))
     }
 
     /// Deserialize a `u8` into a `Value`.
     fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
-        where E: Error,
+        where E: Error
     {
         self.visit_u64(v as u64)
     }
 
     /// Deserialize a `u16` into a `Value`.
     fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
-        where E: Error,
+        where E: Error
     {
         self.visit_u64(v as u64)
     }
 
     /// Deserialize a `u32` into a `Value`.
     fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
-        where E: Error,
+        where E: Error
     {
         self.visit_u64(v as u64)
     }
 
     /// Deserialize a `u64` into a `Value`.
     fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
-        where E: Error,
+        where E: Error
     {
         Err(Error::invalid_type(Unexpected::Unsigned(v), &self))
     }
 
     /// Deserialize a `f32` into a `Value`.
     fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>
-        where E: Error,
+        where E: Error
     {
         self.visit_f64(v as f64)
     }
 
     /// Deserialize a `f64` into a `Value`.
     fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
-        where E: Error,
+        where E: Error
     {
         Err(Error::invalid_type(Unexpected::Float(v), &self))
     }
 
     /// Deserialize a `char` into a `Value`.
     #[inline]
     fn visit_char<E>(self, v: char) -> Result<Self::Value, E>
-        where E: Error,
+        where E: Error
     {
         self.visit_str(::utils::encode_utf8(v).as_str())
     }
 
     /// Deserialize a `&str` into a `Value`.
     ///
     /// This method allows the `Deserializer` to avoid a copy by retaining
     /// ownership of any buffered data. `Deserialize` implementations that do
     /// not benefit from taking ownership of `String` data should indicate that
     /// to the deserializer by using `Deserializer::deserialize_str` rather than
     /// `Deserializer::deserialize_string`.
     ///
     /// It is never correct to implement `visit_string` without implementing
     /// `visit_str`. Implement neither, both, or just `visit_str`.
     fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
-        where E: Error,
+        where E: Error
     {
         Err(Error::invalid_type(Unexpected::Str(v), &self))
     }
 
     /// Deserialize a `String` into a `Value`.
     ///
     /// This method allows the `Visitor` to avoid a copy by taking ownership of
     /// a string created by the `Deserializer`. `Deserialize` implementations
@@ -1127,87 +1127,87 @@ pub trait Visitor: Sized {
     /// It is never correct to implement `visit_string` without implementing
     /// `visit_str`. Implement neither, both, or just `visit_str`.
     ///
     /// The default implementation forwards to `visit_str` and then drops the
     /// `String`.
     #[inline]
     #[cfg(any(feature = "std", feature = "collections"))]
     fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
-        where E: Error,
+        where E: Error
     {
         self.visit_str(&v)
     }
 
     /// Deserialize a `()` into a `Value`.
     fn visit_unit<E>(self) -> Result<Self::Value, E>
-        where E: Error,
+        where E: Error
     {
         Err(Error::invalid_type(Unexpected::Unit, &self))
     }
 
     /// Deserialize an absent optional `Value`.
     fn visit_none<E>(self) -> Result<Self::Value, E>
-        where E: Error,
+        where E: Error
     {
         Err(Error::invalid_type(Unexpected::Option, &self))
     }
 
     /// Deserialize a present optional `Value`.
     fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
-        where D: Deserializer,
+        where D: Deserializer
     {
         let _ = deserializer;
         Err(Error::invalid_type(Unexpected::Option, &self))
     }
 
     /// Deserialize `Value` as a newtype struct.
     fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
-        where D: Deserializer,
+        where D: Deserializer
     {
         let _ = deserializer;
         Err(Error::invalid_type(Unexpected::NewtypeStruct, &self))
     }
 
     /// Deserialize `Value` as a sequence of elements.
     fn visit_seq<V>(self, visitor: V) -> Result<Self::Value, V::Error>
-        where V: SeqVisitor,
+        where V: SeqVisitor
     {
         let _ = visitor;
         Err(Error::invalid_type(Unexpected::Seq, &self))
     }
 
     /// Deserialize `Value` as a key-value map.
     fn visit_map<V>(self, visitor: V) -> Result<Self::Value, V::Error>
-        where V: MapVisitor,
+        where V: MapVisitor
     {
         let _ = visitor;
         Err(Error::invalid_type(Unexpected::Map, &self))
     }
 
     /// Deserialize `Value` as an enum.
     fn visit_enum<V>(self, visitor: V) -> Result<Self::Value, V::Error>
-        where V: EnumVisitor,
+        where V: EnumVisitor
     {
         let _ = visitor;
         Err(Error::invalid_type(Unexpected::Enum, &self))
     }
 
     /// Deserialize a `&[u8]` into a `Value`.
     ///
     /// This method allows the `Deserializer` to avoid a copy by retaining
     /// ownership of any buffered data. `Deserialize` implementations that do
     /// not benefit from taking ownership of `Vec<u8>` data should indicate that
     /// to the deserializer by using `Deserializer::deserialize_bytes` rather
     /// than `Deserializer::deserialize_byte_buf`.
     ///
     /// It is never correct to implement `visit_byte_buf` without implementing
     /// `visit_bytes`. Implement neither, both, or just `visit_bytes`.
     fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
-        where E: Error,
+        where E: Error
     {
         let _ = v;
         Err(Error::invalid_type(Unexpected::Bytes(v), &self))
     }
 
     /// Deserialize a `Vec<u8>` into a `Value`.
     ///
     /// This method allows the `Visitor` to avoid a copy by taking ownership of
@@ -1220,17 +1220,17 @@ pub trait Visitor: Sized {
     ///
     /// It is never correct to implement `visit_byte_buf` without implementing
     /// `visit_bytes`. Implement neither, both, or just `visit_bytes`.
     ///
     /// The default implementation forwards to `visit_bytes` and then drops the
     /// `Vec<u8>`.
     #[cfg(any(feature = "std", feature = "collections"))]
     fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
-        where E: Error,
+        where E: Error
     {
         self.visit_bytes(&v)
     }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 /// `SeqVisitor` visits each item in a sequence.
@@ -1264,17 +1264,19 @@ pub trait SeqVisitor {
 
     /// Return the lower and upper bound of items remaining in the sequence.
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
         (0, None)
     }
 }
 
-impl<'a, V> SeqVisitor for &'a mut V where V: SeqVisitor {
+impl<'a, V> SeqVisitor for &'a mut V
+    where V: SeqVisitor
+{
     type Error = V::Error;
 
     #[inline]
     fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, V::Error>
         where T: DeserializeSeed
     {
         (**self).visit_seed(seed)
     }
@@ -1321,26 +1323,29 @@ pub trait MapVisitor {
     /// the map, or `Ok(None)` if there are no more remaining items.
     ///
     /// `MapVisitor` implementations should override the default behavior if a
     /// more efficient implementation is possible.
     ///
     /// `Deserialize` implementations should typically use `MapVisitor::visit`
     /// instead.
     #[inline]
-    fn visit_seed<K, V>(&mut self, kseed: K, vseed: V) -> Result<Option<(K::Value, V::Value)>, Self::Error>
+    fn visit_seed<K, V>(&mut self,
+                        kseed: K,
+                        vseed: V)
+                        -> Result<Option<(K::Value, V::Value)>, Self::Error>
         where K: DeserializeSeed,
               V: DeserializeSeed
     {
         match try!(self.visit_key_seed(kseed)) {
             Some(key) => {
                 let value = try!(self.visit_value_seed(vseed));
                 Ok(Some((key, value)))
             }
-            None => Ok(None)
+            None => Ok(None),
         }
     }
 
     /// This returns `Ok(Some(key))` for the next key in the map, or `Ok(None)`
     /// if there are no more remaining entries.
     ///
     /// This method exists as a convenience for `Deserialize` implementations.
     /// `MapVisitor` implementations should not override the default behavior.
@@ -1365,29 +1370,31 @@ pub trait MapVisitor {
     /// This returns `Ok(Some((key, value)))` for the next (key-value) pair in
     /// the map, or `Ok(None)` if there are no more remaining items.
     ///
     /// This method exists as a convenience for `Deserialize` implementations.
     /// `MapVisitor` implementations should not override the default behavior.
     #[inline]
     fn visit<K, V>(&mut self) -> Result<Option<(K, V)>, Self::Error>
         where K: Deserialize,
-              V: Deserialize,
+              V: Deserialize
     {
         self.visit_seed(PhantomData, PhantomData)
     }
 
     /// Return the lower and upper bound of items remaining in the sequence.
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
         (0, None)
     }
 }
 
-impl<'a, V_> MapVisitor for &'a mut V_ where V_: MapVisitor {
+impl<'a, V_> MapVisitor for &'a mut V_
+    where V_: MapVisitor
+{
     type Error = V_::Error;
 
     #[inline]
     fn visit_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
         where K: DeserializeSeed
     {
         (**self).visit_key_seed(seed)
     }
@@ -1395,27 +1402,30 @@ impl<'a, V_> MapVisitor for &'a mut V_ w
     #[inline]
     fn visit_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
         where V: DeserializeSeed
     {
         (**self).visit_value_seed(seed)
     }
 
     #[inline]
-    fn visit_seed<K, V>(&mut self, kseed: K, vseed: V) -> Result<Option<(K::Value, V::Value)>, Self::Error>
+    fn visit_seed<K, V>(&mut self,
+                        kseed: K,
+                        vseed: V)
+                        -> Result<Option<(K::Value, V::Value)>, Self::Error>
         where K: DeserializeSeed,
               V: DeserializeSeed
     {
         (**self).visit_seed(kseed, vseed)
     }
 
     #[inline]
     fn visit<K, V>(&mut self) -> Result<Option<(K, V)>, V_::Error>
         where K: Deserialize,
-              V: Deserialize,
+              V: Deserialize
     {
         (**self).visit()
     }
 
     #[inline]
     fn visit_key<K>(&mut self) -> Result<Option<K>, V_::Error>
         where K: Deserialize
     {
@@ -1441,17 +1451,17 @@ impl<'a, V_> MapVisitor for &'a mut V_ w
 /// to the `Deserialize` in order to identify which variant of an enum to
 /// deserialize.
 pub trait EnumVisitor: Sized {
     /// The error type that can be returned if some error occurs during
     /// deserialization.
     type Error: Error;
     /// The `Visitor` that will be used to deserialize the content of the enum
     /// variant.
-    type Variant: VariantVisitor<Error=Self::Error>;
+    type Variant: VariantVisitor<Error = Self::Error>;
 
     /// `visit_variant` is called to identify which variant to deserialize.
     ///
     /// `Deserialize` implementations should typically use
     /// `EnumVisitor::visit_variant` instead.
     fn visit_variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
         where V: DeserializeSeed;
 
@@ -1534,19 +1544,17 @@ pub trait VariantVisitor: Sized {
     ///                   _visitor: V) -> Result<V::Value, Self::Error>
     ///     where V: Visitor
     /// {
     ///     // What the data actually contained; suppose it is a unit variant.
     ///     let unexp = Unexpected::UnitVariant;
     ///     Err(Error::invalid_type(unexp, &"tuple variant"))
     /// }
     /// ```
-    fn visit_tuple<V>(self,
-                      len: usize,
-                      visitor: V) -> Result<V::Value, Self::Error>
+    fn visit_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
         where V: Visitor;
 
     /// Called when deserializing a struct-like variant.
     ///
     /// The `fields` are the names of the fields of the struct variant.
     ///
     /// If the data contains a different type of variant, the following
     /// `invalid_type` error should be constructed:
@@ -1559,17 +1567,18 @@ pub trait VariantVisitor: Sized {
     /// {
     ///     // What the data actually contained; suppose it is a unit variant.
     ///     let unexp = Unexpected::UnitVariant;
     ///     Err(Error::invalid_type(unexp, &"struct variant"))
     /// }
     /// ```
     fn visit_struct<V>(self,
                        fields: &'static [&'static str],
-                       visitor: V) -> Result<V::Value, Self::Error>
+                       visitor: V)
+                       -> Result<V::Value, Self::Error>
         where V: Visitor;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 /// Used in error messages.
 ///
 /// - expected `a`
--- a/third_party/rust/serde/src/de/private.rs
+++ b/third_party/rust/serde/src/de/private.rs
@@ -1,21 +1,16 @@
 use core::marker::PhantomData;
 
 use de::{Deserialize, Deserializer, Error, Visitor};
 
 #[cfg(any(feature = "std", feature = "collections"))]
-pub use de::content::{
-    Content,
-    ContentRefDeserializer,
-    ContentDeserializer,
-    TaggedContentVisitor,
-    InternallyTaggedUnitVisitor,
-    UntaggedUnitVisitor,
-};
+pub use de::content::{Content, ContentRefDeserializer, ContentDeserializer, TaggedContentVisitor,
+                      TagOrContentField, TagOrContentFieldVisitor, InternallyTaggedUnitVisitor,
+                      UntaggedUnitVisitor};
 
 /// If the missing field is of type `Option<T>` then treat is as `None`,
 /// otherwise it is an error.
 pub fn missing_field<V, E>(field: &'static str) -> Result<V, E>
     where V: Deserialize,
           E: Error
 {
     struct MissingFieldDeserializer<E>(&'static str, PhantomData<E>);
--- a/third_party/rust/serde/src/de/value.rs
+++ b/third_party/rust/serde/src/de/value.rs
@@ -1,52 +1,36 @@
 //! This module supports deserializing from primitives with the `ValueDeserializer` trait.
 
 #[cfg(feature = "std")]
-use std::collections::{
-    BTreeMap,
-    BTreeSet,
-    HashMap,
-    HashSet,
-    btree_map,
-    btree_set,
-    hash_map,
-    hash_set,
-};
+use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map, btree_set, hash_map,
+                       hash_set};
 #[cfg(feature = "std")]
 use std::borrow::Cow;
 #[cfg(feature = "std")]
 use std::vec;
 
 #[cfg(all(feature = "collections", not(feature = "std")))]
-use collections::{
-    BTreeMap,
-    BTreeSet,
-    Vec,
-    String,
-    btree_map,
-    btree_set,
-    vec,
-};
+use collections::{BTreeMap, BTreeSet, Vec, String, btree_map, btree_set, vec};
 #[cfg(all(feature = "collections", not(feature = "std")))]
 use collections::borrow::Cow;
 #[cfg(all(feature = "collections", not(feature = "std")))]
 use collections::boxed::Box;
 #[cfg(all(feature = "collections", not(feature = "std")))]
 use collections::string::ToString;
 
 #[cfg(feature = "std")]
 use core::hash::Hash;
 #[cfg(feature = "std")]
 use std::error;
 #[cfg(not(feature = "std"))]
 use error;
 
 use core::fmt::{self, Display};
-use core::iter::{self,  Iterator};
+use core::iter::{self, Iterator};
 use core::marker::PhantomData;
 
 use de::{self, Expected, SeqVisitor};
 use bytes;
 
 ///////////////////////////////////////////////////////////////////////////////
 
 /// This represents all the possible errors that can occur using the `ValueDeserializer`.
@@ -58,26 +42,22 @@ pub struct Error {
 #[cfg(any(feature = "std", feature = "collections"))]
 type ErrorImpl = Box<str>;
 #[cfg(not(any(feature = "std", feature = "collections")))]
 type ErrorImpl = ();
 
 impl de::Error for Error {
     #[cfg(any(feature = "std", feature = "collections"))]
     fn custom<T: Display>(msg: T) -> Self {
-        Error {
-            err: msg.to_string().into_boxed_str(),
-        }
+        Error { err: msg.to_string().into_boxed_str() }
     }
 
     #[cfg(not(any(feature = "std", feature = "collections")))]
     fn custom<T: Display>(_msg: T) -> Self {
-        Error {
-            err: (),
-        }
+        Error { err: () }
     }
 }
 
 impl Display for Error {
     #[cfg(any(feature = "std", feature = "collections"))]
     fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
         formatter.write_str(&self.err)
     }
@@ -100,33 +80,31 @@ impl error::Error for Error {
     }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 /// This trait converts primitive types into a deserializer.
 pub trait ValueDeserializer<E: de::Error = Error> {
     /// The actual deserializer type.
-    type Deserializer: de::Deserializer<Error=E>;
+    type Deserializer: de::Deserializer<Error = E>;
 
     /// Convert this value into a deserializer.
     fn into_deserializer(self) -> Self::Deserializer;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 impl<E> ValueDeserializer<E> for ()
-    where E: de::Error,
+    where E: de::Error
 {
     type Deserializer = UnitDeserializer<E>;
 
     fn into_deserializer(self) -> UnitDeserializer<E> {
-        UnitDeserializer {
-            marker: PhantomData,
-        }
+        UnitDeserializer { marker: PhantomData }
     }
 }
 
 /// A helper deserializer that deserializes a `()`.
 pub struct UnitDeserializer<E> {
     marker: PhantomData<E>,
 }
 
@@ -137,23 +115,23 @@ impl<E> de::Deserializer for UnitDeseria
 
     forward_to_deserialize! {
         bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq
         seq_fixed_size bytes map unit_struct newtype_struct tuple_struct struct
         struct_field tuple enum ignored_any byte_buf
     }
 
     fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
-        where V: de::Visitor,
+        where V: de::Visitor
     {
         visitor.visit_unit()
     }
 
     fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
-        where V: de::Visitor,
+        where V: de::Visitor
     {
         visitor.visit_none()
     }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 macro_rules! primitive_deserializer {
@@ -216,213 +194,216 @@ primitive_deserializer!(char, CharDeseri
 
 /// A helper deserializer that deserializes a `&str`.
 pub struct StrDeserializer<'a, E> {
     value: &'a str,
     marker: PhantomData<E>,
 }
 
 impl<'a, E> ValueDeserializer<E> for &'a str
-    where E: de::Error,
+    where E: de::Error
 {
     type Deserializer = StrDeserializer<'a, E>;
 
     fn into_deserializer(self) -> StrDeserializer<'a, E> {
         StrDeserializer {
             value: self,
             marker: PhantomData,
         }
     }
 }
 
 impl<'a, E> de::Deserializer for StrDeserializer<'a, E>
-    where E: de::Error,
+    where E: de::Error
 {
     type Error = E;
 
     fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
-        where V: de::Visitor,
+        where V: de::Visitor
     {
         visitor.visit_str(self.value)
     }
 
     fn deserialize_enum<V>(self,
-                     _name: &str,
-                     _variants: &'static [&'static str],
-                     visitor: V) -> Result<V::Value, Self::Error>
-        where V: de::Visitor,
+                           _name: &str,
+                           _variants: &'static [&'static str],
+                           visitor: V)
+                           -> Result<V::Value, Self::Error>
+        where V: de::Visitor
     {
         visitor.visit_enum(self)
     }
 
     forward_to_deserialize! {
         bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
         seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct
         struct struct_field tuple ignored_any byte_buf
     }
 }
 
 impl<'a, E> de::EnumVisitor for StrDeserializer<'a, E>
-    where E: de::Error,
+    where E: de::Error
 {
     type Error = E;
     type Variant = private::UnitOnly<E>;
 
     fn visit_variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
-        where T: de::DeserializeSeed,
+        where T: de::DeserializeSeed
     {
         seed.deserialize(self).map(private::unit_only)
     }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 /// A helper deserializer that deserializes a `String`.
 #[cfg(any(feature = "std", feature = "collections"))]
 pub struct StringDeserializer<E> {
     value: String,
     marker: PhantomData<E>,
 }
 
 #[cfg(any(feature = "std", feature = "collections"))]
 impl<E> ValueDeserializer<E> for String
-    where E: de::Error,
+    where E: de::Error
 {
     type D