Bug 1341102: Revendor rust dependencies; r=bustage
authorManish Goregaokar <manishearth@gmail.com>
Tue, 28 Feb 2017 09:22:51 -0800
changeset 374206 17b6cdda4c106fba27557407fe598b08d5ffbf65
parent 374205 7d83ebea9020daa786f4368adc906f4d5c697d74
child 374207 ce4d5be6f3fb01e6f896d7be1ee5a027289b28a4
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbustage
bugs1341102
milestone54.0a1
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 Deserializer = StringDeserializer<E>;
 
     fn into_deserializer(self) -> StringDeserializer<E> {
         StringDeserializer {
             value: self,
             marker: PhantomData,
         }
     }
 }
 
 #[cfg(any(feature = "std", feature = "collections"))]
 impl<E> de::Deserializer for StringDeserializer<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_string(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
     }
 }
 
 #[cfg(any(feature = "std", feature = "collections"))]
 impl<'a, E> de::EnumVisitor for StringDeserializer<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)
     }
 }
 
 ////////////////////////////////////////////////////////////////////