Bug 1424280 - Update cargo lockfiles and re-vendor rust dependencies. r?jrmuizel draft
authorKartikaya Gupta <kgupta@mozilla.com>
Sun, 10 Dec 2017 13:49:02 -0500
changeset 710495 9efa856c8366ecbb726540e82bc991d229447a05
parent 710494 4d3325f124c3ea932642fe8835a2909050e9bf48
child 743591 335bfc798209365b2cea15afbee4a9058cebd722
push id92835
push userkgupta@mozilla.com
push dateSun, 10 Dec 2017 18:58:58 +0000
reviewersjrmuizel
bugs1424280
milestone59.0a1
Bug 1424280 - Update cargo lockfiles and re-vendor rust dependencies. r?jrmuizel MozReview-Commit-ID: 1G7oWr52koH
third_party/rust/app_units-0.5.6/.cargo-checksum.json
third_party/rust/app_units-0.5.6/.travis.yml
third_party/rust/app_units-0.5.6/Cargo.toml
third_party/rust/app_units-0.5.6/README.md
third_party/rust/app_units-0.5.6/src/app_unit.rs
third_party/rust/app_units-0.5.6/src/lib.rs
third_party/rust/euclid-0.15.5/.cargo-checksum.json
third_party/rust/euclid-0.15.5/.travis.yml
third_party/rust/euclid-0.15.5/COPYRIGHT
third_party/rust/euclid-0.15.5/Cargo.toml
third_party/rust/euclid-0.15.5/LICENSE-APACHE
third_party/rust/euclid-0.15.5/LICENSE-MIT
third_party/rust/euclid-0.15.5/README.md
third_party/rust/euclid-0.15.5/src/approxeq.rs
third_party/rust/euclid-0.15.5/src/length.rs
third_party/rust/euclid-0.15.5/src/lib.rs
third_party/rust/euclid-0.15.5/src/macros.rs
third_party/rust/euclid-0.15.5/src/num.rs
third_party/rust/euclid-0.15.5/src/point.rs
third_party/rust/euclid-0.15.5/src/rect.rs
third_party/rust/euclid-0.15.5/src/rotation.rs
third_party/rust/euclid-0.15.5/src/scale_factor.rs
third_party/rust/euclid-0.15.5/src/side_offsets.rs
third_party/rust/euclid-0.15.5/src/size.rs
third_party/rust/euclid-0.15.5/src/transform2d.rs
third_party/rust/euclid-0.15.5/src/transform3d.rs
third_party/rust/euclid-0.15.5/src/trig.rs
third_party/rust/euclid-0.15.5/src/vector.rs
third_party/rust/plane-split/.cargo-checksum.json
third_party/rust/plane-split/Cargo.toml
third_party/rust/plane-split/tests/main.rs
third_party/rust/plane-split/tests/split.rs
third_party/rust/serde/.cargo-checksum.json
third_party/rust/serde/Cargo.toml
third_party/rust/serde/README.md
third_party/rust/serde/src/de/impls.rs
third_party/rust/serde/src/de/mod.rs
third_party/rust/serde/src/de/value.rs
third_party/rust/serde/src/export.rs
third_party/rust/serde/src/lib.rs
third_party/rust/serde/src/private/de.rs
third_party/rust/serde/src/private/ser.rs
third_party/rust/serde/src/ser/impls.rs
third_party/rust/serde/src/ser/mod.rs
third_party/rust/serde_derive/.cargo-checksum.json
third_party/rust/serde_derive/Cargo.toml
third_party/rust/serde_derive/README.md
third_party/rust/serde_derive/src/bound.rs
third_party/rust/serde_derive/src/de.rs
third_party/rust/serde_derive/src/lib.rs
third_party/rust/serde_derive/src/ser.rs
third_party/rust/serde_derive_internals/.cargo-checksum.json
third_party/rust/serde_derive_internals/Cargo.toml
third_party/rust/serde_derive_internals/README.md
third_party/rust/serde_derive_internals/src/ast.rs
third_party/rust/serde_derive_internals/src/attr.rs
third_party/rust/serde_derive_internals/src/case.rs
third_party/rust/serde_derive_internals/src/check.rs
third_party/rust/serde_derive_internals/src/lib.rs
third_party/rust/smallvec-0.5.0/.cargo-checksum.json
third_party/rust/smallvec-0.5.0/.travis.yml
third_party/rust/smallvec-0.5.0/Cargo.toml
third_party/rust/smallvec-0.5.0/README.md
third_party/rust/smallvec-0.5.0/benches/bench.rs
third_party/rust/smallvec-0.5.0/lib.rs
toolkit/library/gtest/rust/Cargo.lock
toolkit/library/rust/Cargo.lock
deleted file mode 100644
--- a/third_party/rust/app_units-0.5.6/.cargo-checksum.json
+++ /dev/null
@@ -1,1 +0,0 @@
-{"files":{".travis.yml":"6b96b2c6bfd7e1acef4b825a2813fc4277859eb9400a16800db8835c25e4087d","Cargo.toml":"41d47153a6043d3e4599f827888e1ac43c204e52ed5f6998b1e275fcae21a3cc","README.md":"9f048d969f9f8333cdcdb892744cd0816e4f2922c8817fa5e9e07f9472fe1050","src/app_unit.rs":"0f4fde2c0481b6dd021f48c8ef548090e7c577c02c429c41626c2b5e7a006949","src/lib.rs":"2df7d863c47d8b22f9af66caeafa87e6a206ee713a8aeaa55c5a80a42a92513b"},"package":"ed0a4de09a3b8449515e649f3bb84f72ea15fc2d10639beb0776a09b7d308074"}
\ No newline at end of file
deleted file mode 100644
--- a/third_party/rust/app_units-0.5.6/.travis.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-language: rust
-notifications:
-  webhooks: http://build.servo.org:54856/travis
-
-rust:
-  - stable
-  - beta
-  - nightly
deleted file mode 100644
--- a/third_party/rust/app_units-0.5.6/Cargo.toml
+++ /dev/null
@@ -1,31 +0,0 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g. crates.io) dependencies
-#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
-[package]
-name = "app_units"
-version = "0.5.6"
-authors = ["The Servo Project Developers"]
-description = "Servo app units type (Au)"
-documentation = "http://doc.servo.org/app_units/"
-license = "MPL-2.0"
-repository = "https://github.com/servo/app_units"
-[dependencies.rustc-serialize]
-version = "0.3"
-
-[dependencies.num-traits]
-version = "0.1.32"
-
-[dependencies.heapsize]
-version = ">=0.3, < 0.5"
-
-[dependencies.serde]
-version = "1.0"
deleted file mode 100644
--- a/third_party/rust/app_units-0.5.6/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# app-units
-
-[Documentation](http://doc.servo.org/app_units/index.html)
deleted file mode 100644
--- a/third_party/rust/app_units-0.5.6/src/app_unit.rs
+++ /dev/null
@@ -1,388 +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/. */
-
-use heapsize::HeapSizeOf;
-use num_traits::Zero;
-use rustc_serialize::{Encodable, Encoder};
-use serde::de::{Deserialize, Deserializer};
-use serde::ser::{Serialize, Serializer};
-use std::default::Default;
-use std::fmt;
-use std::i32;
-use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, Sub, SubAssign};
-
-/// The number of app units in a pixel.
-pub const AU_PER_PX: i32 = 60;
-
-#[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Eq, Ord)]
-/// An App Unit, the fundamental unit of length in Servo. Usually
-/// 1/60th of a pixel (see AU_PER_PX)
-///
-/// Please ensure that the values are between MIN_AU and MAX_AU.
-/// It is safe to construct invalid Au values, but it may lead to
-/// panics and overflows.
-pub struct Au(pub i32);
-
-impl HeapSizeOf for Au {
-    fn heap_size_of_children(&self) -> usize { 0 }
-}
-
-impl<'de> Deserialize<'de> for Au {
-    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Au, D::Error> {
-        Ok(Au(try!(i32::deserialize(deserializer))).clamp())
-    }
-}
-
-impl Serialize for Au {
-    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
-        self.0.serialize(serializer)
-    }
-}
-
-impl Default for Au {
-    #[inline]
-    fn default() -> Au {
-        Au(0)
-    }
-}
-
-impl Zero for Au {
-    #[inline]
-    fn zero() -> Au {
-        Au(0)
-    }
-
-    #[inline]
-    fn is_zero(&self) -> bool {
-        self.0 == 0
-    }
-}
-
-// (1 << 30) - 1 lets us add/subtract two Au and check for overflow
-// after the operation. Gecko uses the same min/max values
-pub const MAX_AU: Au = Au((1 << 30) - 1);
-pub const MIN_AU: Au = Au(- ((1 << 30) - 1));
-
-impl Encodable for Au {
-    fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
-        e.emit_f64(self.to_f64_px())
-    }
-}
-
-impl fmt::Debug for Au {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{}px", self.to_f64_px())
-    }
-}
-
-impl Add for Au {
-    type Output = Au;
-
-    #[inline]
-    fn add(self, other: Au) -> Au {
-        Au(self.0 + other.0).clamp()
-    }
-}
-
-impl Sub for Au {
-    type Output = Au;
-
-    #[inline]
-    fn sub(self, other: Au) -> Au {
-        Au(self.0 - other.0).clamp()
-    }
-
-}
-
-impl Mul<i32> for Au {
-    type Output = Au;
-
-    #[inline]
-    fn mul(self, other: i32) -> Au {
-        if let Some(new) = self.0.checked_mul(other) {
-            Au(new).clamp()
-        } else if (self.0 > 0) ^ (other > 0) {
-            MIN_AU
-        } else {
-            MAX_AU
-        }
-    }
-}
-
-impl Div<i32> for Au {
-    type Output = Au;
-
-    #[inline]
-    fn div(self, other: i32) -> Au {
-        Au(self.0 / other)
-    }
-}
-
-impl Rem<i32> for Au {
-    type Output = Au;
-
-    #[inline]
-    fn rem(self, other: i32) -> Au {
-        Au(self.0 % other)
-    }
-}
-
-impl Neg for Au {
-    type Output = Au;
-
-    #[inline]
-    fn neg(self) -> Au {
-        Au(-self.0)
-    }
-}
-
-impl AddAssign for Au {
-    #[inline]
-    fn add_assign(&mut self, other: Au) {
-        *self = *self + other;
-        self.clamp_self();
-    }
-}
-
-impl SubAssign for Au {
-    #[inline]
-    fn sub_assign(&mut self, other: Au) {
-        *self = *self - other;
-        self.clamp_self();
-    }
-}
-
-impl MulAssign<i32> for Au {
-    #[inline]
-    fn mul_assign(&mut self, other: i32) {
-        *self = *self * other;
-        self.clamp_self();
-    }
-}
-
-impl DivAssign<i32> for Au {
-    #[inline]
-    fn div_assign(&mut self, other: i32) {
-        *self = *self / other;
-        self.clamp_self();
-    }
-}
-
-impl Au {
-    /// FIXME(pcwalton): Workaround for lack of cross crate inlining of newtype structs!
-    #[inline]
-    pub fn new(value: i32) -> Au {
-        Au(value).clamp()
-    }
-
-    #[inline]
-    fn clamp(self) -> Self {
-        if self.0 > MAX_AU.0 {
-            MAX_AU
-        } else if self.0 < MIN_AU.0 {
-            MIN_AU
-        } else {
-            self
-        }
-    }
-
-    #[inline]
-    fn clamp_self(&mut self) {
-        *self = Au::clamp(*self)
-    }
-
-    #[inline]
-    pub fn scale_by(self, factor: f32) -> Au {
-        let new_float = ((self.0 as f64) * factor as f64).round();
-        Au::from_f64_au(new_float)
-    }
-
-    #[inline]
-    /// Scale, but truncate (useful for viewport-relative units)
-    pub fn scale_by_trunc(self, factor: f32) -> Au {
-        let new_float = ((self.0 as f64) * factor as f64).trunc();
-        Au::from_f64_au(new_float)
-    }
-
-    #[inline]
-    pub fn from_f64_au(float: f64) -> Self {
-        // We *must* operate in f64. f32 isn't precise enough
-        // to handle MAX_AU
-        Au(float.min(MAX_AU.0 as f64)
-                .max(MIN_AU.0 as f64)
-            as i32)
-    }
-
-    #[inline]
-    pub fn from_px(px: i32) -> Au {
-        Au(px) * AU_PER_PX
-    }
-
-    /// Rounds this app unit down to the pixel towards zero and returns it.
-    #[inline]
-    pub fn to_px(self) -> i32 {
-        self.0 / AU_PER_PX
-    }
-
-    /// Ceil this app unit to the appropriate pixel boundary and return it.
-    #[inline]
-    pub fn ceil_to_px(self) -> i32 {
-        ((self.0 as f64) / (AU_PER_PX as f64)).ceil() as i32
-    }
-
-    #[inline]
-    pub fn to_nearest_px(self) -> i32 {
-        ((self.0 as f64) / (AU_PER_PX as f64)).round() as i32
-    }
-
-    #[inline]
-    pub fn to_nearest_pixel(self, pixels_per_px: f32) -> f32 {
-        ((self.0 as f32) / (AU_PER_PX as f32) * pixels_per_px).round() / pixels_per_px
-    }
-
-    #[inline]
-    pub fn to_f32_px(self) -> f32 {
-        (self.0 as f32) / (AU_PER_PX as f32)
-    }
-
-    #[inline]
-    pub fn to_f64_px(self) -> f64 {
-        (self.0 as f64) / (AU_PER_PX as f64)
-    }
-
-    #[inline]
-    pub fn from_f32_px(px: f32) -> Au {
-        let float = (px * AU_PER_PX as f32).round();
-        Au::from_f64_au(float as f64)
-    }
-
-    #[inline]
-    pub fn from_f64_px(px: f64) -> Au {
-        let float = (px * AU_PER_PX as f64).round();
-        Au::from_f64_au(float)
-    }
-
-    #[inline]
-    pub fn abs(self) -> Self {
-        Au(self.0.abs())
-    }
-}
-
-#[test]
-fn create() {
-    assert_eq!(Au::zero(), Au(0));
-    assert_eq!(Au::default(), Au(0));
-    assert_eq!(Au::new(7), Au(7));
-}
-
-#[test]
-fn operations() {
-    assert_eq!(Au(7) + Au(5), Au(12));
-    assert_eq!(MAX_AU + Au(1), MAX_AU);
-
-    assert_eq!(Au(7) - Au(5), Au(2));
-    assert_eq!(MIN_AU - Au(1), MIN_AU);
-
-    assert_eq!(Au(7) * 5, Au(35));
-    assert_eq!(MAX_AU * -1, MIN_AU);
-    assert_eq!(MIN_AU * -1, MAX_AU);
-
-    assert_eq!(Au(35) / 5, Au(7));
-    assert_eq!(Au(35) % 6, Au(5));
-
-    assert_eq!(-Au(7), Au(-7));
-}
-
-#[test]
-fn saturate() {
-    let half = MAX_AU / 2;
-    assert_eq!(half + half + half + half + half, MAX_AU);
-    assert_eq!(-half - half - half - half - half, MIN_AU);
-    assert_eq!(half * -10, MIN_AU);
-    assert_eq!(-half * 10, MIN_AU);
-    assert_eq!(half * 10, MAX_AU);
-    assert_eq!(-half * -10, MAX_AU);
-}
-
-#[test]
-fn scale() {
-    assert_eq!(Au(12).scale_by(1.5), Au(18));
-    assert_eq!(Au(12).scale_by(1.7), Au(20));
-    assert_eq!(Au(12).scale_by(1.8), Au(22));
-    assert_eq!(Au(12).scale_by_trunc(1.8), Au(21));
-}
-
-#[test]
-fn abs() {
-    assert_eq!(Au(-10).abs(), Au(10));
-}
-
-#[test]
-fn convert() {
-    assert_eq!(Au::from_px(5), Au(300));
-
-    assert_eq!(Au(300).to_px(), 5);
-    assert_eq!(Au(330).to_px(), 5);
-    assert_eq!(Au(350).to_px(), 5);
-    assert_eq!(Au(360).to_px(), 6);
-
-    assert_eq!(Au(300).ceil_to_px(), 5);
-    assert_eq!(Au(310).ceil_to_px(), 6);
-    assert_eq!(Au(330).ceil_to_px(), 6);
-    assert_eq!(Au(350).ceil_to_px(), 6);
-    assert_eq!(Au(360).ceil_to_px(), 6);
-
-    assert_eq!(Au(300).to_nearest_px(), 5);
-    assert_eq!(Au(310).to_nearest_px(), 5);
-    assert_eq!(Au(330).to_nearest_px(), 6);
-    assert_eq!(Au(350).to_nearest_px(), 6);
-    assert_eq!(Au(360).to_nearest_px(), 6);
-
-    assert_eq!(Au(60).to_nearest_pixel(2.), 1.);
-    assert_eq!(Au(70).to_nearest_pixel(2.), 1.);
-    assert_eq!(Au(80).to_nearest_pixel(2.), 1.5);
-    assert_eq!(Au(90).to_nearest_pixel(2.), 1.5);
-    assert_eq!(Au(100).to_nearest_pixel(2.), 1.5);
-    assert_eq!(Au(110).to_nearest_pixel(2.), 2.);
-    assert_eq!(Au(120).to_nearest_pixel(2.), 2.);
-
-    assert_eq!(Au(300).to_f32_px(), 5.);
-    assert_eq!(Au(312).to_f32_px(), 5.2);
-    assert_eq!(Au(330).to_f32_px(), 5.5);
-    assert_eq!(Au(348).to_f32_px(), 5.8);
-    assert_eq!(Au(360).to_f32_px(), 6.);
-    assert_eq!((Au(367).to_f32_px() * 1000.).round(), 6_117.);
-    assert_eq!((Au(368).to_f32_px() * 1000.).round(), 6_133.);
-
-    assert_eq!(Au(300).to_f64_px(), 5.);
-    assert_eq!(Au(312).to_f64_px(), 5.2);
-    assert_eq!(Au(330).to_f64_px(), 5.5);
-    assert_eq!(Au(348).to_f64_px(), 5.8);
-    assert_eq!(Au(360).to_f64_px(), 6.);
-    assert_eq!((Au(367).to_f64_px() * 1000.).round(), 6_117.);
-    assert_eq!((Au(368).to_f64_px() * 1000.).round(), 6_133.);
-
-    assert_eq!(Au::from_f32_px(5.), Au(300));
-    assert_eq!(Au::from_f32_px(5.2), Au(312));
-    assert_eq!(Au::from_f32_px(5.5), Au(330));
-    assert_eq!(Au::from_f32_px(5.8), Au(348));
-    assert_eq!(Au::from_f32_px(6.), Au(360));
-    assert_eq!(Au::from_f32_px(6.12), Au(367));
-    assert_eq!(Au::from_f32_px(6.13), Au(368));
-
-    assert_eq!(Au::from_f64_px(5.), Au(300));
-    assert_eq!(Au::from_f64_px(5.2), Au(312));
-    assert_eq!(Au::from_f64_px(5.5), Au(330));
-    assert_eq!(Au::from_f64_px(5.8), Au(348));
-    assert_eq!(Au::from_f64_px(6.), Au(360));
-    assert_eq!(Au::from_f64_px(6.12), Au(367));
-    assert_eq!(Au::from_f64_px(6.13), Au(368));
-}
-
-#[test]
-fn heapsize() {
-    use heapsize::HeapSizeOf;
-    fn f<T: HeapSizeOf>(_: T) {}
-    f(Au::new(0));
-}
deleted file mode 100644
--- a/third_party/rust/app_units-0.5.6/src/lib.rs
+++ /dev/null
@@ -1,16 +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/. */
-
-//! An Au is an "App Unit" and represents 1/60th of a CSS pixel. It was
-//! originally proposed in 2002 as a standard unit of measure in Gecko.
-//! See https://bugzilla.mozilla.org/show_bug.cgi?id=177805 for more info.
-
-extern crate heapsize;
-extern crate num_traits;
-extern crate rustc_serialize;
-extern crate serde;
-
-mod app_unit;
-
-pub use app_unit::{Au, MIN_AU, MAX_AU, AU_PER_PX};
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/.cargo-checksum.json
+++ /dev/null
@@ -1,1 +0,0 @@
-{"files":{".travis.yml":"13574ca06216b94913348afb2beae9db9929f8964fbc45b3c00344ee281e1f52","COPYRIGHT":"ec82b96487e9e778ee610c7ab245162464782cfa1f555c2299333f8dbe5c036a","Cargo.toml":"1951103509b9ee4036df52e5f11c9d1e2ba18c09eab673de25c37ad1f6dabab4","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"62065228e42caebca7e7d7db1204cbb867033de5982ca4009928915e4095f3a3","README.md":"625bec69c76ce5423fdd05cfe46922b2680ec517f97c5854ce34798d1d8a9541","src/approxeq.rs":"6cf810ad389c73a27141a7a67454ed12d4b01c3c16605b9a7414b389bc0615dd","src/length.rs":"73b0aed12a0c9acfd77a6b9ac0cd3a7ec522c41ffafad4448753cb6bba47b6a4","src/lib.rs":"43b594eebf1cd2c8fb7a7f4616d872d9e09f5e0c7c0172a16d4e5841ab552328","src/macros.rs":"a3f4deaa4323da6398546720548dda20b0b39427603ccc35ab49d220a83467a8","src/num.rs":"749b201289fc6663199160a2f9204e17925fd3053f8ab7779e7bfb377ad06227","src/point.rs":"859e3da88bf45123b10d90642b807b9ef35751699594d85012cb32b45e9e970b","src/rect.rs":"761b3e1c841c03ec87e99ed9dd9c37d669bec6967c2dac2b6be2f056e9c8b7e0","src/rotation.rs":"0b0a299268a76fbc15c58aec788ad0bfc27f7f68bcfeade3dce71cd2585166f2","src/scale_factor.rs":"b093243256df3f2b8a2e2bf98236e6ec1032c3d358596f384313614dbefaca49","src/side_offsets.rs":"fd95ffc9a74e9e84314875c388e763d0780486eb7f9034423e3a22048361e379","src/size.rs":"5ecb66be6c42f07770662c925017a7ef6e1d0e332b3576e1884c488fbf9d4b59","src/transform2d.rs":"82b5a41881fc4ab947df0b337ad2ac2e1dce7d532df1a225eb5abf2d32776007","src/transform3d.rs":"3b944cae37968b3c4e98a25323ac57ba331d97638b0a747fff28f139fcb6043c","src/trig.rs":"ef290927af252ca90a29ba9f17158b591ed591604e66cb9df045dd47b9cfdca5","src/vector.rs":"7f076e77a9a6fbecf44c1802233e9c2d59015a94cccf94fd9d8832cfb037bdb8"},"package":"f5ed7d77e46f6600f490463ad7b6349c3ebb2d2319af56e679e279e4c66495d9"}
\ No newline at end of file
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/.travis.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-language: rust
-rust:
-  - 1.17.0
-  - stable
-  - beta
-  - nightly
-
-notifications:
-  webhooks: http://build.servo.org:54856/travis
-
-matrix:
-  include:
-    - rust: stable
-      env: FEATURES=""
-    - rust: beta
-      env: FEATURES=""
-    - rust: nightly
-      env: FEATURES=""
-    - rust: nightly
-      env: FEATURES="unstable"
-
-script:
-  - cargo build --verbose --features "$FEATURES"
-  - cargo test --verbose --features "$FEATURES"
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/COPYRIGHT
+++ /dev/null
@@ -1,5 +0,0 @@
-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. All files in the project carrying such notice may not be
-copied, modified, or distributed except according to those terms.
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/Cargo.toml
+++ /dev/null
@@ -1,42 +0,0 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g. crates.io) dependencies
-#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
-[package]
-name = "euclid"
-version = "0.15.5"
-authors = ["The Servo Project Developers"]
-description = "Geometry primitives"
-documentation = "https://docs.rs/euclid/"
-keywords = ["matrix", "vector", "linear-algebra", "geometry"]
-categories = ["science"]
-license = "MIT / Apache-2.0"
-repository = "https://github.com/servo/euclid"
-[dependencies.heapsize]
-version = "0.4"
-
-[dependencies.num-traits]
-version = "0.1.32"
-default-features = false
-
-[dependencies.log]
-version = "0.3.1"
-
-[dependencies.serde]
-version = "1.0"
-[dev-dependencies.serde_test]
-version = "1.0"
-
-[dev-dependencies.rand]
-version = "0.3.7"
-
-[features]
-unstable = []
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/LICENSE-APACHE
+++ /dev/null
@@ -1,201 +0,0 @@
-                              Apache License
-                        Version 2.0, January 2004
-                     http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
-   "License" shall mean the terms and conditions for use, reproduction,
-   and distribution as defined by Sections 1 through 9 of this document.
-
-   "Licensor" shall mean the copyright owner or entity authorized by
-   the copyright owner that is granting the License.
-
-   "Legal Entity" shall mean the union of the acting entity and all
-   other entities that control, are controlled by, or are under common
-   control with that entity. For the purposes of this definition,
-   "control" means (i) the power, direct or indirect, to cause the
-   direction or management of such entity, whether by contract or
-   otherwise, or (ii) ownership of fifty percent (50%) or more of the
-   outstanding shares, or (iii) beneficial ownership of such entity.
-
-   "You" (or "Your") shall mean an individual or Legal Entity
-   exercising permissions granted by this License.
-
-   "Source" form shall mean the preferred form for making modifications,
-   including but not limited to software source code, documentation
-   source, and configuration files.
-
-   "Object" form shall mean any form resulting from mechanical
-   transformation or translation of a Source form, including but
-   not limited to compiled object code, generated documentation,
-   and conversions to other media types.
-
-   "Work" shall mean the work of authorship, whether in Source or
-   Object form, made available under the License, as indicated by a
-   copyright notice that is included in or attached to the work
-   (an example is provided in the Appendix below).
-
-   "Derivative Works" shall mean any work, whether in Source or Object
-   form, that is based on (or derived from) the Work and for which the
-   editorial revisions, annotations, elaborations, or other modifications
-   represent, as a whole, an original work of authorship. For the purposes
-   of this License, Derivative Works shall not include works that remain
-   separable from, or merely link (or bind by name) to the interfaces of,
-   the Work and Derivative Works thereof.
-
-   "Contribution" shall mean any work of authorship, including
-   the original version of the Work and any modifications or additions
-   to that Work or Derivative Works thereof, that is intentionally
-   submitted to Licensor for inclusion in the Work by the copyright owner
-   or by an individual or Legal Entity authorized to submit on behalf of
-   the copyright owner. For the purposes of this definition, "submitted"
-   means any form of electronic, verbal, or written communication sent
-   to the Licensor or its representatives, including but not limited to
-   communication on electronic mailing lists, source code control systems,
-   and issue tracking systems that are managed by, or on behalf of, the
-   Licensor for the purpose of discussing and improving the Work, but
-   excluding communication that is conspicuously marked or otherwise
-   designated in writing by the copyright owner as "Not a Contribution."
-
-   "Contributor" shall mean Licensor and any individual or Legal Entity
-   on behalf of whom a Contribution has been received by Licensor and
-   subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of
-   this License, each Contributor hereby grants to You a perpetual,
-   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-   copyright license to reproduce, prepare Derivative Works of,
-   publicly display, publicly perform, sublicense, and distribute the
-   Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of
-   this License, each Contributor hereby grants to You a perpetual,
-   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-   (except as stated in this section) patent license to make, have made,
-   use, offer to sell, sell, import, and otherwise transfer the Work,
-   where such license applies only to those patent claims licensable
-   by such Contributor that are necessarily infringed by their
-   Contribution(s) alone or by combination of their Contribution(s)
-   with the Work to which such Contribution(s) was submitted. If You
-   institute patent litigation against any entity (including a
-   cross-claim or counterclaim in a lawsuit) alleging that the Work
-   or a Contribution incorporated within the Work constitutes direct
-   or contributory patent infringement, then any patent licenses
-   granted to You under this License for that Work shall terminate
-   as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the
-   Work or Derivative Works thereof in any medium, with or without
-   modifications, and in Source or Object form, provided that You
-   meet the following conditions:
-
-   (a) You must give any other recipients of the Work or
-       Derivative Works a copy of this License; and
-
-   (b) You must cause any modified files to carry prominent notices
-       stating that You changed the files; and
-
-   (c) You must retain, in the Source form of any Derivative Works
-       that You distribute, all copyright, patent, trademark, and
-       attribution notices from the Source form of the Work,
-       excluding those notices that do not pertain to any part of
-       the Derivative Works; and
-
-   (d) If the Work includes a "NOTICE" text file as part of its
-       distribution, then any Derivative Works that You distribute must
-       include a readable copy of the attribution notices contained
-       within such NOTICE file, excluding those notices that do not
-       pertain to any part of the Derivative Works, in at least one
-       of the following places: within a NOTICE text file distributed
-       as part of the Derivative Works; within the Source form or
-       documentation, if provided along with the Derivative Works; or,
-       within a display generated by the Derivative Works, if and
-       wherever such third-party notices normally appear. The contents
-       of the NOTICE file are for informational purposes only and
-       do not modify the License. You may add Your own attribution
-       notices within Derivative Works that You distribute, alongside
-       or as an addendum to the NOTICE text from the Work, provided
-       that such additional attribution notices cannot be construed
-       as modifying the License.
-
-   You may add Your own copyright statement to Your modifications and
-   may provide additional or different license terms and conditions
-   for use, reproduction, or distribution of Your modifications, or
-   for any such Derivative Works as a whole, provided Your use,
-   reproduction, and distribution of the Work otherwise complies with
-   the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise,
-   any Contribution intentionally submitted for inclusion in the Work
-   by You to the Licensor shall be under the terms and conditions of
-   this License, without any additional terms or conditions.
-   Notwithstanding the above, nothing herein shall supersede or modify
-   the terms of any separate license agreement you may have executed
-   with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade
-   names, trademarks, service marks, or product names of the Licensor,
-   except as required for reasonable and customary use in describing the
-   origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or
-   agreed to in writing, Licensor provides the Work (and each
-   Contributor provides its Contributions) on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-   implied, including, without limitation, any warranties or conditions
-   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-   PARTICULAR PURPOSE. You are solely responsible for determining the
-   appropriateness of using or redistributing the Work and assume any
-   risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory,
-   whether in tort (including negligence), contract, or otherwise,
-   unless required by applicable law (such as deliberate and grossly
-   negligent acts) or agreed to in writing, shall any Contributor be
-   liable to You for damages, including any direct, indirect, special,
-   incidental, or consequential damages of any character arising as a
-   result of this License or out of the use or inability to use the
-   Work (including but not limited to damages for loss of goodwill,
-   work stoppage, computer failure or malfunction, or any and all
-   other commercial damages or losses), even if such Contributor
-   has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing
-   the Work or Derivative Works thereof, You may choose to offer,
-   and charge a fee for, acceptance of support, warranty, indemnity,
-   or other liability obligations and/or rights consistent with this
-   License. However, in accepting such obligations, You may act only
-   on Your own behalf and on Your sole responsibility, not on behalf
-   of any other Contributor, and only if You agree to indemnify,
-   defend, and hold each Contributor harmless for any liability
-   incurred by, or claims asserted against, such Contributor by reason
-   of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
-   To apply the Apache License to your work, attach the following
-   boilerplate notice, with the fields enclosed by brackets "[]"
-   replaced with your own identifying information. (Don't include
-   the brackets!)  The text should be enclosed in the appropriate
-   comment syntax for the file format. We also recommend that a
-   file or class name and description of purpose be included on the
-   same "printed page" as the copyright notice for easier
-   identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-	http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/LICENSE-MIT
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2012-2013 Mozilla Foundation
-
-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.
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# euclid
-
-This is a small library for geometric types with a focus on 2d graphics and
-layout.
-
-* [Documentation](https://docs.rs/euclid/)
-* [Release notes](https://github.com/servo/euclid/releases)
-* [crates.io](https://crates.io/crates/euclid)
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/approxeq.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution.
-//
-// 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.
-
-
-/// Trait for testing approximate equality
-pub trait ApproxEq<Eps> {
-    fn approx_epsilon() -> Eps;
-    fn approx_eq(&self, other: &Self) -> bool;
-    fn approx_eq_eps(&self, other: &Self, approx_epsilon: &Eps) -> bool;
-}
-
-macro_rules! approx_eq {
-    ($ty:ty, $eps:expr) => (
-        impl ApproxEq<$ty> for $ty {
-            #[inline]
-            fn approx_epsilon() -> $ty { $eps }
-            #[inline]
-            fn approx_eq(&self, other: &$ty) -> bool {
-                self.approx_eq_eps(other, &$eps)
-            }
-            #[inline]
-            fn approx_eq_eps(&self, other: &$ty, approx_epsilon: &$ty) -> bool {
-                (*self - *other).abs() < *approx_epsilon
-            }
-        }
-    )
-}
-
-approx_eq!(f32, 1.0e-6);
-approx_eq!(f64, 1.0e-6);
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/length.rs
+++ /dev/null
@@ -1,461 +0,0 @@
-// Copyright 2014 The Servo Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution.
-//
-// 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.
-//! A one-dimensional length, tagged with its units.
-
-use scale_factor::ScaleFactor;
-use num::Zero;
-
-use heapsize::HeapSizeOf;
-use num_traits::{NumCast, Saturating};
-use num::One;
-use serde::{Deserialize, Deserializer, Serialize, Serializer};
-use std::cmp::Ordering;
-use std::ops::{Add, Sub, Mul, Div, Neg};
-use std::ops::{AddAssign, SubAssign};
-use std::marker::PhantomData;
-use std::fmt;
-
-/// A one-dimensional distance, with value represented by `T` and unit of measurement `Unit`.
-///
-/// `T` can be any numeric type, for example a primitive type like `u64` or `f32`.
-///
-/// `Unit` is not used in the representation of a `Length` value. It is used only at compile time
-/// to ensure that a `Length` stored with one unit is converted explicitly before being used in an
-/// expression that requires a different unit.  It may be a type without values, such as an empty
-/// enum.
-///
-/// You can multiply a `Length` by a `scale_factor::ScaleFactor` to convert it from one unit to
-/// another. See the `ScaleFactor` docs for an example.
-// Uncomment the derive, and remove the macro call, once heapsize gets
-// PhantomData<T> support.
-#[repr(C)]
-pub struct Length<T, Unit>(pub T, PhantomData<Unit>);
-
-impl<T: Clone, Unit> Clone for Length<T, Unit> {
-    fn clone(&self) -> Self {
-        Length(self.0.clone(), PhantomData)
-    }
-}
-
-impl<T: Copy, Unit> Copy for Length<T, Unit> {}
-
-impl<Unit, T: HeapSizeOf> HeapSizeOf for Length<T, Unit> {
-    fn heap_size_of_children(&self) -> usize {
-        self.0.heap_size_of_children()
-    }
-}
-
-impl<'de, Unit, T> Deserialize<'de> for Length<T, Unit> where T: Deserialize<'de> {
-    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-                      where D: Deserializer<'de> {
-        Ok(Length(try!(Deserialize::deserialize(deserializer)), PhantomData))
-    }
-}
-
-impl<T, Unit> Serialize for Length<T, Unit> where T: Serialize {
-    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
-        self.0.serialize(serializer)
-    }
-}
-
-impl<T, Unit> Length<T, Unit> {
-    pub fn new(x: T) -> Self {
-        Length(x, PhantomData)
-    }
-}
-
-impl<Unit, T: Clone> Length<T, Unit> {
-    pub fn get(&self) -> T {
-        self.0.clone()
-    }
-}
-
-impl<T: fmt::Debug + Clone, U> fmt::Debug for Length<T, U> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.get().fmt(f)
-    }
-}
-
-impl<T: fmt::Display + Clone, U> fmt::Display for Length<T, U> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.get().fmt(f)
-    }
-}
-
-// length + length
-impl<U, T: Clone + Add<T, Output=T>> Add for Length<T, U> {
-    type Output = Length<T, U>;
-    fn add(self, other: Length<T, U>) -> Length<T, U> {
-        Length::new(self.get() + other.get())
-    }
-}
-
-// length += length
-impl<U, T: Clone + AddAssign<T>> AddAssign for Length<T, U> {
-    fn add_assign(&mut self, other: Length<T, U>) {
-        self.0 += other.get();
-    }
-}
-
-// length - length
-impl<U, T: Clone + Sub<T, Output=T>> Sub<Length<T, U>> for Length<T, U> {
-    type Output = Length<T, U>;
-    fn sub(self, other: Length<T, U>) -> <Self as Sub>::Output {
-        Length::new(self.get() - other.get())
-    }
-}
-
-// length -= length
-impl<U, T: Clone + SubAssign<T>> SubAssign for Length<T, U> {
-    fn sub_assign(&mut self, other: Length<T, U>) {
-        self.0 -= other.get();
-    }
-}
-
-// Saturating length + length and length - length.
-impl<U, T: Clone + Saturating> Saturating for Length<T, U> {
-    fn saturating_add(self, other: Length<T, U>) -> Length<T, U> {
-        Length::new(self.get().saturating_add(other.get()))
-    }
-
-    fn saturating_sub(self, other: Length<T, U>) -> Length<T, U> {
-        Length::new(self.get().saturating_sub(other.get()))
-    }
-}
-
-// length / length
-impl<Src, Dst, T: Clone + Div<T, Output=T>> Div<Length<T, Src>> for Length<T, Dst> {
-    type Output = ScaleFactor<T, Src, Dst>;
-    #[inline]
-    fn div(self, other: Length<T, Src>) -> ScaleFactor<T, Src, Dst> {
-        ScaleFactor::new(self.get() / other.get())
-    }
-}
-
-// length * scaleFactor
-impl<Src, Dst, T: Clone + Mul<T, Output=T>> Mul<ScaleFactor<T, Src, Dst>> for Length<T, Src> {
-    type Output = Length<T, Dst>;
-    #[inline]
-    fn mul(self, scale: ScaleFactor<T, Src, Dst>) -> Length<T, Dst> {
-        Length::new(self.get() * scale.get())
-    }
-}
-
-// length / scaleFactor
-impl<Src, Dst, T: Clone + Div<T, Output=T>> Div<ScaleFactor<T, Src, Dst>> for Length<T, Dst> {
-    type Output = Length<T, Src>;
-    #[inline]
-    fn div(self, scale: ScaleFactor<T, Src, Dst>) -> Length<T, Src> {
-        Length::new(self.get() / scale.get())
-    }
-}
-
-// -length
-impl <U, T:Clone + Neg<Output=T>> Neg for Length<T, U> {
-    type Output = Length<T, U>;
-    #[inline]
-    fn neg(self) -> Length<T, U> {
-        Length::new(-self.get())
-    }
-}
-
-impl<Unit, T0: NumCast + Clone> Length<T0, Unit> {
-    /// Cast from one numeric representation to another, preserving the units.
-    pub fn cast<T1: NumCast + Clone>(&self) -> Option<Length<T1, Unit>> {
-        NumCast::from(self.get()).map(Length::new)
-    }
-}
-
-impl<Unit, T: Clone + PartialEq> PartialEq for Length<T, Unit> {
-    fn eq(&self, other: &Self) -> bool { self.get().eq(&other.get()) }
-}
-
-impl<Unit, T: Clone + PartialOrd> PartialOrd for Length<T, Unit> {
-    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
-        self.get().partial_cmp(&other.get())
-    }
-}
-
-impl<Unit, T: Clone + Eq> Eq for Length<T, Unit> {}
-
-impl<Unit, T: Clone + Ord> Ord for Length<T, Unit> {
-    fn cmp(&self, other: &Self) -> Ordering { self.get().cmp(&other.get()) }
-}
-
-impl<Unit, T: Zero> Zero for Length<T, Unit> {
-    fn zero() -> Self {
-        Length::new(Zero::zero())
-    }
-}
-
-impl<T, U> Length<T, U>
-where T: Copy + One + Add<Output=T> + Sub<Output=T> + Mul<Output=T> {
-    /// Linearly interpolate between this length and another length.
-    ///
-    /// `t` is expected to be between zero and one.
-    #[inline]
-    pub fn lerp(&self, other: Self, t: T) -> Self {
-        let one_t = T::one() - t;
-        Length::new(one_t * self.get() + t * other.get())
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::Length;
-    use num::Zero;
-
-    use heapsize::HeapSizeOf;
-    use num_traits::Saturating;
-    use scale_factor::ScaleFactor;
-    use std::f32::INFINITY;
-
-    extern crate serde_test;
-    use self::serde_test::Token;
-    use self::serde_test::assert_tokens;
-
-    enum Inch {}
-    enum Mm {}
-    enum Cm {}
-    enum Second {}
-
-    #[test]
-    fn test_clone() {
-        // A cloned Length is a separate length with the state matching the
-        // original Length at the point it was cloned.
-        let mut variable_length: Length<f32, Inch> = Length::new(12.0);
-
-        let one_foot = variable_length.clone();
-        variable_length.0 = 24.0;
-
-        assert_eq!(one_foot.get(), 12.0);
-        assert_eq!(variable_length.get(), 24.0);
-    }
-
-    #[test]
-    fn test_heapsizeof_builtins() {
-        // Heap size of built-ins is zero by default.
-        let one_foot: Length<f32, Inch> = Length::new(12.0);
-
-        let heap_size_length_f32 = one_foot.heap_size_of_children();
-
-        assert_eq!(heap_size_length_f32, 0);
-    }
-
-    #[test]
-    fn test_heapsizeof_length_vector() {
-        // Heap size of any Length is just the heap size of the length value.
-        for n in 0..5 {
-            let length: Length<Vec<f32>, Inch> = Length::new(Vec::with_capacity(n));
-
-            assert_eq!(length.heap_size_of_children(), length.0.heap_size_of_children());
-        }
-    }
-
-    #[test]
-    fn test_length_serde() {
-        let one_cm: Length<f32, Mm> = Length::new(10.0);
-
-        assert_tokens(&one_cm, &[Token::F32(10.0)]);
-    }
-
-    #[test]
-    fn test_get_clones_length_value() {
-        // Calling get returns a clone of the Length's value.
-        // To test this, we need something clone-able - hence a vector.
-        let mut length: Length<Vec<i32>, Inch> = Length::new(vec![1, 2, 3]);
-
-        let value = length.get();
-        length.0.push(4);
-
-        assert_eq!(value, vec![1, 2, 3]);
-        assert_eq!(length.get(), vec![1, 2, 3, 4]);
-    }
-
-    #[test]
-    fn test_fmt_debug() {
-        // Debug and display format the value only.
-        let one_cm: Length<f32, Mm> = Length::new(10.0);
-
-        let result = format!("{:?}", one_cm);
-
-        assert_eq!(result, "10");
-    }
-
-    #[test]
-    fn test_fmt_display() {
-        // Debug and display format the value only.
-        let one_cm: Length<f32, Mm> = Length::new(10.0);
-
-        let result = format!("{}", one_cm);
-
-        assert_eq!(result, "10");
-    }
-
-    #[test]
-    fn test_add() {
-        let length1: Length<u8, Mm> = Length::new(250);
-        let length2: Length<u8, Mm> = Length::new(5);
-
-        let result = length1 + length2;
-
-        assert_eq!(result.get(), 255);
-    }
-
-    #[test]
-    fn test_addassign() {
-        let one_cm: Length<f32, Mm> = Length::new(10.0);
-        let mut measurement: Length<f32, Mm> = Length::new(5.0);
-
-        measurement += one_cm;
-
-        assert_eq!(measurement.get(), 15.0);
-    }
-
-    #[test]
-    fn test_sub() {
-        let length1: Length<u8, Mm> = Length::new(250);
-        let length2: Length<u8, Mm> = Length::new(5);
-
-        let result = length1 - length2;
-
-        assert_eq!(result.get(), 245);
-    }
-
-    #[test]
-    fn test_subassign() {
-        let one_cm: Length<f32, Mm> = Length::new(10.0);
-        let mut measurement: Length<f32, Mm> = Length::new(5.0);
-
-        measurement -= one_cm;
-
-        assert_eq!(measurement.get(), -5.0);
-    }
-
-    #[test]
-    fn test_saturating_add() {
-        let length1: Length<u8, Mm> = Length::new(250);
-        let length2: Length<u8, Mm> = Length::new(6);
-
-        let result = length1.saturating_add(length2);
-
-        assert_eq!(result.get(), 255);
-    }
-
-    #[test]
-    fn test_saturating_sub() {
-        let length1: Length<u8, Mm> = Length::new(5);
-        let length2: Length<u8, Mm> = Length::new(10);
-
-        let result = length1.saturating_sub(length2);
-
-        assert_eq!(result.get(), 0);
-    }
-
-    #[test]
-    fn test_division_by_length() {
-        // Division results in a ScaleFactor from denominator units
-        // to numerator units.
-        let length: Length<f32, Cm> = Length::new(5.0);
-        let duration: Length<f32, Second> = Length::new(10.0);
-
-        let result = length / duration;
-
-        let expected: ScaleFactor<f32, Second, Cm> = ScaleFactor::new(0.5);
-        assert_eq!(result, expected);
-    }
-
-    #[test]
-    fn test_multiplication() {
-        let length_mm: Length<f32, Mm> = Length::new(10.0);
-        let cm_per_mm: ScaleFactor<f32, Mm, Cm> = ScaleFactor::new(0.1);
-
-        let result = length_mm * cm_per_mm;
-
-        let expected: Length<f32, Cm> = Length::new(1.0);
-        assert_eq!(result, expected);
-    }
-
-    #[test]
-    fn test_division_by_scalefactor() {
-        let length: Length<f32, Cm> = Length::new(5.0);
-        let cm_per_second: ScaleFactor<f32, Second, Cm> = ScaleFactor::new(10.0);
-
-        let result = length / cm_per_second;
-
-        let expected: Length<f32, Second> = Length::new(0.5);
-        assert_eq!(result, expected);
-    }
-
-    #[test]
-    fn test_negation() {
-        let length: Length<f32, Cm> = Length::new(5.0);
-
-        let result = -length;
-
-        let expected: Length<f32, Cm> = Length::new(-5.0);
-        assert_eq!(result, expected);
-    }
-
-    #[test]
-    fn test_cast() {
-        let length_as_i32: Length<i32, Cm> = Length::new(5);
-
-        let result: Length<f32, Cm> = length_as_i32.cast().unwrap();
-
-        let length_as_f32: Length<f32, Cm> = Length::new(5.0);
-        assert_eq!(result, length_as_f32);
-    }
-
-    #[test]
-    fn test_equality() {
-        let length_5_point_0: Length<f32, Cm> = Length::new(5.0);
-        let length_5_point_1: Length<f32, Cm> = Length::new(5.1);
-        let length_0_point_1: Length<f32, Cm> = Length::new(0.1);
-
-        assert!(length_5_point_0 == length_5_point_1 - length_0_point_1);
-        assert!(length_5_point_0 != length_5_point_1);
-    }
-
-    #[test]
-    fn test_order() {
-        let length_5_point_0: Length<f32, Cm> = Length::new(5.0);
-        let length_5_point_1: Length<f32, Cm> = Length::new(5.1);
-        let length_0_point_1: Length<f32, Cm> = Length::new(0.1);
-
-        assert!(length_5_point_0 < length_5_point_1);
-        assert!(length_5_point_0 <= length_5_point_1);
-        assert!(length_5_point_0 <= length_5_point_1 - length_0_point_1);
-        assert!(length_5_point_1 > length_5_point_0);
-        assert!(length_5_point_1 >= length_5_point_0);
-        assert!(length_5_point_0 >= length_5_point_1 - length_0_point_1);
-    }
-
-    #[test]
-    fn test_zero_add() {
-        type LengthCm = Length<f32, Cm>;
-        let length: LengthCm = Length::new(5.0);
-
-        let result = length - LengthCm::zero();
-
-        assert_eq!(result, length);
-    }
-
-    #[test]
-    fn test_zero_division() {
-        type LengthCm = Length<f32, Cm>;
-        let length: LengthCm = Length::new(5.0);
-        let length_zero: LengthCm = Length::zero();
-
-        let result = length / length_zero;
-
-        let expected: ScaleFactor<f32, Cm, Cm> = ScaleFactor::new(INFINITY);
-        assert_eq!(result, expected);
-    }
-}
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/lib.rs
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution.
-//
-// 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.
-
-#![cfg_attr(feature = "unstable", feature(asm, repr_simd, test, fn_must_use))]
-
-//! A collection of strongly typed math tools for computer graphics with an inclination
-//! towards 2d graphics and layout.
-//!
-//! All types are generic over the scalar type of their component (`f32`, `i32`, etc.),
-//! and tagged with a generic Unit parameter which is useful to prevent mixing
-//! values from different spaces. For example it should not be legal to translate
-//! a screen-space position by a world-space vector and this can be expressed using
-//! the generic Unit parameter.
-//!
-//! This unit system is not mandatory and all Typed* structures have an alias
-//! with the default unit: `UnknownUnit`.
-//! for example ```Point2D<T>``` is equivalent to ```TypedPoint2D<T, UnknownUnit>```.
-//! Client code typically creates a set of aliases for each type and doesn't need
-//! to deal with the specifics of typed units further. For example:
-//!
-//! ```rust
-//! use euclid::*;
-//! pub struct ScreenSpace;
-//! pub type ScreenPoint = TypedPoint2D<f32, ScreenSpace>;
-//! pub type ScreenSize = TypedSize2D<f32, ScreenSpace>;
-//! pub struct WorldSpace;
-//! pub type WorldPoint = TypedPoint3D<f32, WorldSpace>;
-//! pub type ProjectionMatrix = TypedTransform3D<f32, WorldSpace, ScreenSpace>;
-//! // etc...
-//! ```
-//!
-//! All euclid types are marked `#[repr(C)]` in order to facilitate exposing them to
-//! foreign function interfaces (provided the underlying scalar type is also `repr(C)`).
-//!
-//! Components are accessed in their scalar form by default for convenience, and most
-//! types additionally implement strongly typed accessors which return typed ```Length``` wrappers.
-//! For example:
-//!
-//! ```rust
-//! # use euclid::*;
-//! # pub struct WorldSpace;
-//! # pub type WorldPoint = TypedPoint3D<f32, WorldSpace>;
-//! let p = WorldPoint::new(0.0, 1.0, 1.0);
-//! // p.x is an f32.
-//! println!("p.x = {:?} ", p.x);
-//! // p.x is a Length<f32, WorldSpace>.
-//! println!("p.x_typed() = {:?} ", p.x_typed());
-//! // Length::get returns the scalar value (f32).
-//! assert_eq!(p.x, p.x_typed().get());
-//! ```
-
-extern crate heapsize;
-
-#[cfg_attr(test, macro_use)]
-extern crate log;
-extern crate serde;
-
-#[cfg(test)]
-extern crate rand;
-#[cfg(feature = "unstable")]
-extern crate test;
-extern crate num_traits;
-
-pub use length::Length;
-pub use scale_factor::ScaleFactor;
-pub use transform2d::{Transform2D, TypedTransform2D};
-pub use transform3d::{Transform3D, TypedTransform3D};
-pub use point::{
-    Point2D, TypedPoint2D, point2,
-    Point3D, TypedPoint3D, point3,
-};
-pub use vector::{
-    Vector2D, TypedVector2D, vec2,
-    Vector3D, TypedVector3D, vec3,
-};
-
-pub use rect::{Rect, TypedRect, rect};
-pub use rotation::{TypedRotation2D, Rotation2D, TypedRotation3D, Rotation3D};
-pub use side_offsets::{SideOffsets2D, TypedSideOffsets2D};
-#[cfg(feature = "unstable")] pub use side_offsets::SideOffsets2DSimdI32;
-pub use size::{Size2D, TypedSize2D, size2};
-pub use trig::Trig;
-
-pub mod approxeq;
-pub mod num;
-mod length;
-#[macro_use]
-mod macros;
-mod transform2d;
-mod transform3d;
-mod point;
-mod rect;
-mod rotation;
-mod scale_factor;
-mod side_offsets;
-mod size;
-mod trig;
-mod vector;
-
-/// The default unit.
-#[derive(Clone, Copy)]
-pub struct UnknownUnit;
-
-/// Unit for angles in radians.
-pub struct Rad;
-
-/// Unit for angles in degrees.
-pub struct Deg;
-
-/// A value in radians.
-pub type Radians<T> = Length<T, Rad>;
-
-/// A value in Degrees.
-pub type Degrees<T> = Length<T, Deg>;
-
-/// Temporary alias to facilitate the transition to the new naming scheme
-#[deprecated]
-pub type Matrix2D<T> = Transform2D<T>;
-
-/// Temporary alias to facilitate the transition to the new naming scheme
-#[deprecated]
-pub type TypedMatrix2D<T, Src, Dst> = TypedTransform2D<T, Src, Dst>;
-
-/// Temporary alias to facilitate the transition to the new naming scheme
-#[deprecated]
-pub type Matrix4D<T> = Transform3D<T>;
-
-/// Temporary alias to facilitate the transition to the new naming scheme
-#[deprecated]
-pub type TypedMatrix4D<T, Src, Dst> = TypedTransform3D<T, Src, Dst>;
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/macros.rs
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution.
-//
-// 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.
-
-macro_rules! define_matrix {
-    (
-        $(#[$attr:meta])*
-        pub struct $name:ident<T, $($phantom:ident),+> {
-            $(pub $field:ident: T,)+
-        }
-    ) => (
-        #[repr(C)]
-        $(#[$attr])*
-        pub struct $name<T, $($phantom),+> {
-            $(pub $field: T,)+
-            _unit: PhantomData<($($phantom),+)>
-        }
-
-        impl<T: Clone, $($phantom),+> Clone for $name<T, $($phantom),+> {
-            fn clone(&self) -> Self {
-                $name {
-                    $($field: self.$field.clone(),)+
-                    _unit: PhantomData,
-                }
-            }
-        }
-
-        impl<T: Copy, $($phantom),+> Copy for $name<T, $($phantom),+> {}
-
-        impl<T, $($phantom),+> ::heapsize::HeapSizeOf for $name<T, $($phantom),+>
-            where T: ::heapsize::HeapSizeOf
-        {
-            fn heap_size_of_children(&self) -> usize {
-                $(self.$field.heap_size_of_children() +)+ 0
-            }
-        }
-
-        impl<'de, T, $($phantom),+> ::serde::Deserialize<'de> for $name<T, $($phantom),+>
-            where T: ::serde::Deserialize<'de>
-        {
-            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-                where D: ::serde::Deserializer<'de>
-            {
-                let ($($field,)+) =
-                    try!(::serde::Deserialize::deserialize(deserializer));
-                Ok($name {
-                    $($field: $field,)+
-                    _unit: PhantomData,
-                })
-            }
-        }
-
-        impl<T, $($phantom),+> ::serde::Serialize for $name<T, $($phantom),+>
-            where T: ::serde::Serialize
-        {
-            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-                where S: ::serde::Serializer
-            {
-                ($(&self.$field,)+).serialize(serializer)
-            }
-        }
-
-        impl<T, $($phantom),+> ::std::cmp::Eq for $name<T, $($phantom),+>
-            where T: ::std::cmp::Eq {}
-
-        impl<T, $($phantom),+> ::std::cmp::PartialEq for $name<T, $($phantom),+>
-            where T: ::std::cmp::PartialEq
-        {
-            fn eq(&self, other: &Self) -> bool {
-                true $(&& self.$field == other.$field)+
-            }
-        }
-
-        impl<T, $($phantom),+> ::std::hash::Hash for $name<T, $($phantom),+>
-            where T: ::std::hash::Hash
-        {
-            fn hash<H: ::std::hash::Hasher>(&self, h: &mut H) {
-                $(self.$field.hash(h);)+
-            }
-        }
-    )
-}
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/num.rs
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2014 The Servo Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution.
-//
-// 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.
-//! A one-dimensional length, tagged with its units.
-
-use num_traits;
-
-
-pub trait Zero {
-    fn zero() -> Self;
-}
-
-impl<T: num_traits::Zero> Zero for T {
-    fn zero() -> T { num_traits::Zero::zero() }
-}
-
-pub trait One {
-    fn one() -> Self;
-}
-
-impl<T: num_traits::One> One for T {
-    fn one() -> T { num_traits::One::one() }
-}
-
-
-pub trait Round : Copy { fn round(self) -> Self; }
-pub trait Floor : Copy { fn floor(self) -> Self; }
-pub trait Ceil : Copy { fn ceil(self) -> Self; }
-
-macro_rules! num_int {
-    ($ty:ty) => (
-        impl Round for $ty {
-            #[inline]
-            fn round(self) -> $ty { self }
-        }
-        impl Floor for $ty {
-            #[inline]
-            fn floor(self) -> $ty { self }
-        }
-        impl Ceil for $ty {
-            #[inline]
-            fn ceil(self) -> $ty { self }
-        }
-    )
-}
-macro_rules! num_float {
-    ($ty:ty) => (
-        impl Round for $ty {
-            #[inline]
-            fn round(self) -> $ty { self.round() }
-        }
-        impl Floor for $ty {
-            #[inline]
-            fn floor(self) -> $ty { self.floor() }
-        }
-        impl Ceil for $ty {
-            #[inline]
-            fn ceil(self) -> $ty { self.ceil() }
-        }
-    )
-}
-
-num_int!(i16);
-num_int!(u16);
-num_int!(i32);
-num_int!(u32);
-num_int!(i64);
-num_int!(u64);
-num_int!(isize);
-num_int!(usize);
-num_float!(f32);
-num_float!(f64);
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/point.rs
+++ /dev/null
@@ -1,834 +0,0 @@
-// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use super::UnknownUnit;
-use approxeq::ApproxEq;
-use length::Length;
-use scale_factor::ScaleFactor;
-use size::TypedSize2D;
-use num::*;
-use num_traits::{Float, NumCast};
-use vector::{TypedVector2D, TypedVector3D, vec2, vec3};
-use std::fmt;
-use std::ops::{Add, Mul, Sub, Div, AddAssign, SubAssign, MulAssign, DivAssign};
-use std::marker::PhantomData;
-
-define_matrix! {
-    /// A 2d Point tagged with a unit.
-    pub struct TypedPoint2D<T, U> {
-        pub x: T,
-        pub y: T,
-    }
-}
-
-/// Default 2d point type with no unit.
-///
-/// `Point2D` provides the same methods as `TypedPoint2D`.
-pub type Point2D<T> = TypedPoint2D<T, UnknownUnit>;
-
-impl<T: Copy + Zero, U> TypedPoint2D<T, U> {
-    /// Constructor, setting all components to zero.
-    #[inline]
-    pub fn origin() -> Self {
-        point2(Zero::zero(), Zero::zero())
-    }
-
-    #[inline]
-    pub fn zero() -> Self {
-        Self::origin()
-    }
-
-    /// Convert into a 3d point.
-    #[inline]
-    pub fn to_3d(&self) -> TypedPoint3D<T, U> {
-        point3(self.x, self.y, Zero::zero())
-    }
-}
-
-impl<T: fmt::Debug, U> fmt::Debug for TypedPoint2D<T, U> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "({:?},{:?})", self.x, self.y)
-    }
-}
-
-impl<T: fmt::Display, U> fmt::Display for TypedPoint2D<T, U> {
-    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
-        write!(formatter, "({},{})", self.x, self.y)
-    }
-}
-
-impl<T: Copy, U> TypedPoint2D<T, U> {
-    /// Constructor taking scalar values directly.
-    #[inline]
-    pub fn new(x: T, y: T) -> Self {
-        TypedPoint2D { x: x, y: y, _unit: PhantomData }
-    }
-
-    /// Constructor taking properly typed Lengths instead of scalar values.
-    #[inline]
-    pub fn from_lengths(x: Length<T, U>, y: Length<T, U>) -> Self {
-        point2(x.0, y.0)
-    }
-
-    /// Create a 3d point from this one, using the specified z value.
-    #[inline]
-    pub fn extend(&self, z: T) -> TypedPoint3D<T, U> {
-        point3(self.x, self.y, z)
-    }
-
-    /// Cast this point into a vector.
-    ///
-    /// Equivalent to subtracting the origin from this point.
-    #[inline]
-    pub fn to_vector(&self) -> TypedVector2D<T, U> {
-        vec2(self.x, self.y)
-    }
-
-    /// Swap x and y.
-    #[inline]
-    pub fn yx(&self) -> Self {
-        point2(self.y, self.x)
-    }
-
-    /// Returns self.x as a Length carrying the unit.
-    #[inline]
-    pub fn x_typed(&self) -> Length<T, U> { Length::new(self.x) }
-
-    /// Returns self.y as a Length carrying the unit.
-    #[inline]
-    pub fn y_typed(&self) -> Length<T, U> { Length::new(self.y) }
-
-    /// Drop the units, preserving only the numeric value.
-    #[inline]
-    pub fn to_untyped(&self) -> Point2D<T> {
-        point2(self.x, self.y)
-    }
-
-    /// Tag a unitless value with units.
-    #[inline]
-    pub fn from_untyped(p: &Point2D<T>) -> Self {
-        point2(p.x, p.y)
-    }
-
-    #[inline]
-    pub fn to_array(&self) -> [T; 2] {
-        [self.x, self.y]
-    }
-}
-
-impl<T: Copy + Add<T, Output=T>, U> TypedPoint2D<T, U> {
-    #[inline]
-    pub fn add_size(&self, other: &TypedSize2D<T, U>) -> Self {
-        point2(self.x + other.width, self.y + other.height)
-    }
-}
-
-impl<T: Copy + Add<T, Output=T>, U> Add<TypedSize2D<T, U>> for TypedPoint2D<T, U> {
-    type Output = Self;
-    #[inline]
-    fn add(self, other: TypedSize2D<T, U>) -> Self {
-        point2(self.x + other.width, self.y + other.height)
-    }
-}
-
-impl<T: Copy + Add<T, Output=T>, U> AddAssign<TypedVector2D<T, U>> for TypedPoint2D<T, U> {
-    #[inline]
-    fn add_assign(&mut self, other: TypedVector2D<T, U>) {
-        *self = *self + other
-    }
-}
-
-impl<T: Copy + Sub<T, Output=T>, U> SubAssign<TypedVector2D<T, U>> for TypedPoint2D<T, U> {
-    #[inline]
-    fn sub_assign(&mut self, other: TypedVector2D<T, U>) {
-        *self = *self - other
-    }
-}
-
-impl<T: Copy + Add<T, Output=T>, U> Add<TypedVector2D<T, U>> for TypedPoint2D<T, U> {
-    type Output = Self;
-    #[inline]
-    fn add(self, other: TypedVector2D<T, U>) -> Self {
-        point2(self.x + other.x, self.y + other.y)
-    }
-}
-
-impl<T: Copy + Sub<T, Output=T>, U> Sub for TypedPoint2D<T, U> {
-    type Output = TypedVector2D<T, U>;
-    #[inline]
-    fn sub(self, other: Self) -> TypedVector2D<T, U> {
-        vec2(self.x - other.x, self.y - other.y)
-    }
-}
-
-impl<T: Copy + Sub<T, Output=T>, U> Sub<TypedVector2D<T, U>> for TypedPoint2D<T, U> {
-    type Output = Self;
-    #[inline]
-    fn sub(self, other: TypedVector2D<T, U>) -> Self {
-        point2(self.x - other.x, self.y - other.y)
-    }
-}
-
-impl<T: Float, U> TypedPoint2D<T, U> {
-    #[inline]
-    pub fn min(self, other: Self) -> Self {
-         point2(self.x.min(other.x), self.y.min(other.y))
-    }
-
-    #[inline]
-    pub fn max(self, other: Self) -> Self {
-        point2(self.x.max(other.x), self.y.max(other.y))
-    }
-}
-
-impl<T: Copy + Mul<T, Output=T>, U> Mul<T> for TypedPoint2D<T, U> {
-    type Output = Self;
-    #[inline]
-    fn mul(self, scale: T) -> Self {
-        point2(self.x * scale, self.y * scale)
-    }
-}
-
-impl<T: Copy + Mul<T, Output=T>, U> MulAssign<T> for TypedPoint2D<T, U> {
-    #[inline]
-    fn mul_assign(&mut self, scale: T) {
-        *self = *self * scale
-    }
-}
-
-impl<T: Copy + Div<T, Output=T>, U> Div<T> for TypedPoint2D<T, U> {
-    type Output = Self;
-    #[inline]
-    fn div(self, scale: T) -> Self {
-        point2(self.x / scale, self.y / scale)
-    }
-}
-
-impl<T: Copy + Div<T, Output=T>, U> DivAssign<T> for TypedPoint2D<T, U> {
-    #[inline]
-    fn div_assign(&mut self, scale: T) {
-        *self = *self / scale
-    }
-}
-
-impl<T: Copy + Mul<T, Output=T>, U1, U2> Mul<ScaleFactor<T, U1, U2>> for TypedPoint2D<T, U1> {
-    type Output = TypedPoint2D<T, U2>;
-    #[inline]
-    fn mul(self, scale: ScaleFactor<T, U1, U2>) -> TypedPoint2D<T, U2> {
-        point2(self.x * scale.get(), self.y * scale.get())
-    }
-}
-
-impl<T: Copy + Div<T, Output=T>, U1, U2> Div<ScaleFactor<T, U1, U2>> for TypedPoint2D<T, U2> {
-    type Output = TypedPoint2D<T, U1>;
-    #[inline]
-    fn div(self, scale: ScaleFactor<T, U1, U2>) -> TypedPoint2D<T, U1> {
-        point2(self.x / scale.get(), self.y / scale.get())
-    }
-}
-
-impl<T: Round, U> TypedPoint2D<T, U> {
-    /// Rounds each component to the nearest integer value.
-    ///
-    /// This behavior is preserved for negative values (unlike the basic cast).
-    /// For example `{ -0.1, -0.8 }.round() == { 0.0, -1.0 }`.
-    #[inline]
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn round(&self) -> Self {
-        point2(self.x.round(), self.y.round())
-    }
-}
-
-impl<T: Ceil, U> TypedPoint2D<T, U> {
-    /// Rounds each component to the smallest integer equal or greater than the original value.
-    ///
-    /// This behavior is preserved for negative values (unlike the basic cast).
-    /// For example `{ -0.1, -0.8 }.ceil() == { 0.0, 0.0 }`.
-    #[inline]
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn ceil(&self) -> Self {
-        point2(self.x.ceil(), self.y.ceil())
-    }
-}
-
-impl<T: Floor, U> TypedPoint2D<T, U> {
-    /// Rounds each component to the biggest integer equal or lower than the original value.
-    ///
-    /// This behavior is preserved for negative values (unlike the basic cast).
-    /// For example `{ -0.1, -0.8 }.floor() == { -1.0, -1.0 }`.
-    #[inline]
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn floor(&self) -> Self {
-        point2(self.x.floor(), self.y.floor())
-    }
-}
-
-impl<T: NumCast + Copy, U> TypedPoint2D<T, U> {
-    /// Cast from one numeric representation to another, preserving the units.
-    ///
-    /// When casting from floating point to integer coordinates, the decimals are truncated
-    /// as one would expect from a simple cast, but this behavior does not always make sense
-    /// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting.
-    #[inline]
-    pub fn cast<NewT: NumCast + Copy>(&self) -> Option<TypedPoint2D<NewT, U>> {
-        match (NumCast::from(self.x), NumCast::from(self.y)) {
-            (Some(x), Some(y)) => Some(point2(x, y)),
-            _ => None
-        }
-    }
-
-    // Convenience functions for common casts
-
-    /// Cast into an `f32` point.
-    #[inline]
-    pub fn to_f32(&self) -> TypedPoint2D<f32, U> {
-        self.cast().unwrap()
-    }
-
-    /// Cast into an `usize` point, truncating decimals if any.
-    ///
-    /// When casting from floating point points, it is worth considering whether
-    /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
-    /// the desired conversion behavior.
-    #[inline]
-    pub fn to_usize(&self) -> TypedPoint2D<usize, U> {
-        self.cast().unwrap()
-    }
-
-    /// Cast into an i32 point, truncating decimals if any.
-    ///
-    /// When casting from floating point points, it is worth considering whether
-    /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
-    /// the desired conversion behavior.
-    #[inline]
-    pub fn to_i32(&self) -> TypedPoint2D<i32, U> {
-        self.cast().unwrap()
-    }
-
-    /// Cast into an i64 point, truncating decimals if any.
-    ///
-    /// When casting from floating point points, it is worth considering whether
-    /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
-    /// the desired conversion behavior.
-    #[inline]
-    pub fn to_i64(&self) -> TypedPoint2D<i64, U> {
-        self.cast().unwrap()
-    }
-}
-
-impl<T, U> TypedPoint2D<T, U>
-where T: Copy + One + Add<Output=T> + Sub<Output=T> + Mul<Output=T> {
-    /// Linearly interpolate between this point and another point.
-    ///
-    /// `t` is expected to be between zero and one.
-    #[inline]
-    pub fn lerp(&self, other: Self, t: T) -> Self {
-        let one_t = T::one() - t;
-        point2(
-            one_t * self.x + t * other.x,
-            one_t * self.y + t * other.y,
-        )
-    }
-}
-
-impl<T: Copy+ApproxEq<T>, U> ApproxEq<TypedPoint2D<T, U>> for TypedPoint2D<T, U> {
-    #[inline]
-    fn approx_epsilon() -> Self {
-        point2(T::approx_epsilon(), T::approx_epsilon())
-    }
-
-    #[inline]
-    fn approx_eq(&self, other: &Self) -> bool {
-        self.x.approx_eq(&other.x) && self.y.approx_eq(&other.y)
-    }
-
-    #[inline]
-    fn approx_eq_eps(&self, other: &Self, eps: &Self) -> bool {
-        self.x.approx_eq_eps(&other.x, &eps.x) && self.y.approx_eq_eps(&other.y, &eps.y)
-    }
-}
-
-impl<T: Copy, U> Into<[T; 2]> for TypedPoint2D<T, U> {
-    fn into(self) -> [T; 2] {
-        self.to_array()
-    }
-}
-
-impl<T: Copy, U> From<[T; 2]> for TypedPoint2D<T, U> {
-    fn from(array: [T; 2]) -> Self {
-        point2(array[0], array[1])
-    }
-}
-
-
-define_matrix! {
-    /// A 3d Point tagged with a unit.
-    pub struct TypedPoint3D<T, U> {
-        pub x: T,
-        pub y: T,
-        pub z: T,
-    }
-}
-
-/// Default 3d point type with no unit.
-///
-/// `Point3D` provides the same methods as `TypedPoint3D`.
-pub type Point3D<T> = TypedPoint3D<T, UnknownUnit>;
-
-impl<T: Copy + Zero, U> TypedPoint3D<T, U> {
-    /// Constructor, setting all copmonents to zero.
-    #[inline]
-    pub fn origin() -> Self {
-        point3(Zero::zero(), Zero::zero(), Zero::zero())
-    }
-}
-
-impl<T: Copy + One, U> TypedPoint3D<T, U> {
-    #[inline]
-    pub fn to_array_4d(&self) -> [T; 4] {
-        [self.x, self.y, self.z, One::one()]
-    }
-}
-
-impl<T, U> TypedPoint3D<T, U>
-where T: Copy + One + Add<Output=T> + Sub<Output=T> + Mul<Output=T> {
-    /// Linearly interpolate between this point and another point.
-    ///
-    /// `t` is expected to be between zero and one.
-    #[inline]
-    pub fn lerp(&self, other: Self, t: T) -> Self {
-        let one_t = T::one() - t;
-        point3(
-            one_t * self.x + t * other.x,
-            one_t * self.y + t * other.y,
-            one_t * self.z + t * other.z,
-        )
-    }
-}
-
-impl<T: fmt::Debug, U> fmt::Debug for TypedPoint3D<T, U> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "({:?},{:?},{:?})", self.x, self.y, self.z)
-    }
-}
-
-impl<T: fmt::Display, U> fmt::Display for TypedPoint3D<T, U> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "({},{},{})", self.x, self.y, self.z)
-    }
-}
-
-impl<T: Copy, U> TypedPoint3D<T, U> {
-    /// Constructor taking scalar values directly.
-    #[inline]
-    pub fn new(x: T, y: T, z: T) -> Self {
-        TypedPoint3D { x: x, y: y, z: z, _unit: PhantomData }
-    }
-
-    /// Constructor taking properly typed Lengths instead of scalar values.
-    #[inline]
-    pub fn from_lengths(x: Length<T, U>, y: Length<T, U>, z: Length<T, U>) -> Self {
-        point3(x.0, y.0, z.0)
-    }
-
-    /// Cast this point into a vector.
-    ///
-    /// Equivalent to substracting the origin to this point.
-    #[inline]
-    pub fn to_vector(&self) -> TypedVector3D<T, U> {
-        vec3(self.x, self.y, self.z)
-    }
-
-    /// Returns a 2d point using this point's x and y coordinates
-    #[inline]
-    pub fn xy(&self) -> TypedPoint2D<T, U> {
-        point2(self.x, self.y)
-    }
-
-    /// Returns a 2d point using this point's x and z coordinates
-    #[inline]
-    pub fn xz(&self) -> TypedPoint2D<T, U> {
-        point2(self.x, self.z)
-    }
-
-    /// Returns a 2d point using this point's x and z coordinates
-    #[inline]
-    pub fn yz(&self) -> TypedPoint2D<T, U> {
-        point2(self.y, self.z)
-    }
-
-    /// Returns self.x as a Length carrying the unit.
-    #[inline]
-    pub fn x_typed(&self) -> Length<T, U> { Length::new(self.x) }
-
-    /// Returns self.y as a Length carrying the unit.
-    #[inline]
-    pub fn y_typed(&self) -> Length<T, U> { Length::new(self.y) }
-
-    /// Returns self.z as a Length carrying the unit.
-    #[inline]
-    pub fn z_typed(&self) -> Length<T, U> { Length::new(self.z) }
-
-    #[inline]
-    pub fn to_array(&self) -> [T; 3] { [self.x, self.y, self.z] }
-
-    /// Drop the units, preserving only the numeric value.
-    #[inline]
-    pub fn to_untyped(&self) -> Point3D<T> {
-        point3(self.x, self.y, self.z)
-    }
-
-    /// Tag a unitless value with units.
-    #[inline]
-    pub fn from_untyped(p: &Point3D<T>) -> Self {
-        point3(p.x, p.y, p.z)
-    }
-
-    /// Convert into a 2d point.
-    #[inline]
-    pub fn to_2d(&self) -> TypedPoint2D<T, U> {
-        self.xy()
-    }
-}
-
-impl<T: Copy + Add<T, Output=T>, U> AddAssign<TypedVector3D<T, U>> for TypedPoint3D<T, U> {
-    #[inline]
-    fn add_assign(&mut self, other: TypedVector3D<T, U>) {
-        *self = *self + other
-    }
-}
-
-impl<T: Copy + Sub<T, Output=T>, U> SubAssign<TypedVector3D<T, U>> for TypedPoint3D<T, U> {
-    #[inline]
-    fn sub_assign(&mut self, other: TypedVector3D<T, U>) {
-        *self = *self - other
-    }
-}
-
-impl<T: Copy + Add<T, Output=T>, U> Add<TypedVector3D<T, U>> for TypedPoint3D<T, U> {
-    type Output = Self;
-    #[inline]
-    fn add(self, other: TypedVector3D<T, U>) -> Self {
-        point3(self.x + other.x, self.y + other.y, self.z + other.z)
-    }
-}
-
-impl<T: Copy + Sub<T, Output=T>, U> Sub for TypedPoint3D<T, U> {
-    type Output = TypedVector3D<T, U>;
-    #[inline]
-    fn sub(self, other: Self) -> TypedVector3D<T, U> {
-        vec3(self.x - other.x, self.y - other.y, self.z - other.z)
-    }
-}
-
-impl<T: Copy + Sub<T, Output=T>, U> Sub<TypedVector3D<T, U>> for TypedPoint3D<T, U> {
-    type Output = Self;
-    #[inline]
-    fn sub(self, other: TypedVector3D<T, U>) -> Self {
-        point3(self.x - other.x, self.y - other.y, self.z - other.z)
-    }
-}
-
-impl<T: Copy + Mul<T, Output=T>, U> Mul<T> for TypedPoint3D<T, U> {
-    type Output = Self;
-    #[inline]
-    fn mul(self, scale: T) -> Self {
-        point3(self.x * scale, self.y * scale, self.z * scale)
-    }
-}
-
-impl<T: Copy + Div<T, Output=T>, U> Div<T> for TypedPoint3D<T, U> {
-    type Output = Self;
-    #[inline]
-    fn div(self, scale: T) -> Self {
-        point3(self.x / scale, self.y / scale, self.z / scale)
-    }
-}
-
-impl<T: Float, U> TypedPoint3D<T, U> {
-    #[inline]
-    pub fn min(self, other: Self) -> Self {
-         point3(self.x.min(other.x), self.y.min(other.y), self.z.min(other.z))
-    }
-
-    #[inline]
-    pub fn max(self, other: Self) -> Self {
-        point3(self.x.max(other.x), self.y.max(other.y), self.z.max(other.z))
-    }
-}
-
-impl<T: Round, U> TypedPoint3D<T, U> {
-    /// Rounds each component to the nearest integer value.
-    ///
-    /// This behavior is preserved for negative values (unlike the basic cast).
-    #[inline]
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn round(&self) -> Self {
-        point3(self.x.round(), self.y.round(), self.z.round())
-    }
-}
-
-impl<T: Ceil, U> TypedPoint3D<T, U> {
-    /// Rounds each component to the smallest integer equal or greater than the original value.
-    ///
-    /// This behavior is preserved for negative values (unlike the basic cast).
-    #[inline]
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn ceil(&self) -> Self {
-        point3(self.x.ceil(), self.y.ceil(), self.z.ceil())
-    }
-}
-
-impl<T: Floor, U> TypedPoint3D<T, U> {
-    /// Rounds each component to the biggest integer equal or lower than the original value.
-    ///
-    /// This behavior is preserved for negative values (unlike the basic cast).
-    #[inline]
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn floor(&self) -> Self {
-        point3(self.x.floor(), self.y.floor(), self.z.floor())
-    }
-}
-
-impl<T: NumCast + Copy, U> TypedPoint3D<T, U> {
-    /// Cast from one numeric representation to another, preserving the units.
-    ///
-    /// When casting from floating point to integer coordinates, the decimals are truncated
-    /// as one would expect from a simple cast, but this behavior does not always make sense
-    /// geometrically. Consider using round(), ceil or floor() before casting.
-    #[inline]
-    pub fn cast<NewT: NumCast + Copy>(&self) -> Option<TypedPoint3D<NewT, U>> {
-        match (NumCast::from(self.x),
-               NumCast::from(self.y),
-               NumCast::from(self.z)) {
-            (Some(x), Some(y), Some(z)) => Some(point3(x, y, z)),
-            _ => None
-        }
-    }
-
-    // Convenience functions for common casts
-
-    /// Cast into an `f32` point.
-    #[inline]
-    pub fn to_f32(&self) -> TypedPoint3D<f32, U> {
-        self.cast().unwrap()
-    }
-
-    /// Cast into an `usize` point, truncating decimals if any.
-    ///
-    /// When casting from floating point points, it is worth considering whether
-    /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
-    /// the desired conversion behavior.
-    #[inline]
-    pub fn to_usize(&self) -> TypedPoint3D<usize, U> {
-        self.cast().unwrap()
-    }
-
-    /// Cast into an `i32` point, truncating decimals if any.
-    ///
-    /// When casting from floating point points, it is worth considering whether
-    /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
-    /// the desired conversion behavior.
-    #[inline]
-    pub fn to_i32(&self) -> TypedPoint3D<i32, U> {
-        self.cast().unwrap()
-    }
-
-    /// Cast into an `i64` point, truncating decimals if any.
-    ///
-    /// When casting from floating point points, it is worth considering whether
-    /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
-    /// the desired conversion behavior.
-    #[inline]
-    pub fn to_i64(&self) -> TypedPoint3D<i64, U> {
-        self.cast().unwrap()
-    }
-}
-
-impl<T: Copy+ApproxEq<T>, U> ApproxEq<TypedPoint3D<T, U>> for TypedPoint3D<T, U> {
-    #[inline]
-    fn approx_epsilon() -> Self {
-        point3(T::approx_epsilon(), T::approx_epsilon(), T::approx_epsilon())
-    }
-
-    #[inline]
-    fn approx_eq(&self, other: &Self) -> bool {
-        self.x.approx_eq(&other.x)
-            && self.y.approx_eq(&other.y)
-            && self.z.approx_eq(&other.z)
-    }
-
-    #[inline]
-    fn approx_eq_eps(&self, other: &Self, eps: &Self) -> bool {
-        self.x.approx_eq_eps(&other.x, &eps.x)
-            && self.y.approx_eq_eps(&other.y, &eps.y)
-            && self.z.approx_eq_eps(&other.z, &eps.z)
-    }
-}
-
-impl<T: Copy, U> Into<[T; 3]> for TypedPoint3D<T, U> {
-    fn into(self) -> [T; 3] {
-        self.to_array()
-    }
-}
-
-impl<T: Copy, U> From<[T; 3]> for TypedPoint3D<T, U> {
-    fn from(array: [T; 3]) -> Self {
-        point3(array[0], array[1], array[2])
-    }
-}
-
-
-pub fn point2<T: Copy, U>(x: T, y: T) -> TypedPoint2D<T, U> {
-    TypedPoint2D::new(x, y)
-}
-
-pub fn point3<T: Copy, U>(x: T, y: T, z: T) -> TypedPoint3D<T, U> {
-    TypedPoint3D::new(x, y, z)
-}
-
-#[cfg(test)]
-mod point2d {
-    use super::Point2D;
-
-    #[test]
-    pub fn test_scalar_mul() {
-        let p1: Point2D<f32> = Point2D::new(3.0, 5.0);
-
-        let result = p1 * 5.0;
-
-        assert_eq!(result, Point2D::new(15.0, 25.0));
-    }
-
-    #[test]
-    pub fn test_min() {
-        let p1 = Point2D::new(1.0, 3.0);
-        let p2 = Point2D::new(2.0, 2.0);
-
-        let result = p1.min(p2);
-
-        assert_eq!(result, Point2D::new(1.0, 2.0));
-    }
-
-    #[test]
-    pub fn test_max() {
-        let p1 = Point2D::new(1.0, 3.0);
-        let p2 = Point2D::new(2.0, 2.0);
-
-        let result = p1.max(p2);
-
-        assert_eq!(result, Point2D::new(2.0, 3.0));
-    }
-}
-
-#[cfg(test)]
-mod typedpoint2d {
-    use super::{TypedPoint2D, Point2D, point2};
-    use scale_factor::ScaleFactor;
-    use vector::vec2;
-
-    pub enum Mm {}
-    pub enum Cm {}
-
-    pub type Point2DMm<T> = TypedPoint2D<T, Mm>;
-    pub type Point2DCm<T> = TypedPoint2D<T, Cm>;
-
-    #[test]
-    pub fn test_add() {
-        let p1 = Point2DMm::new(1.0, 2.0);
-        let p2 = vec2(3.0, 4.0);
-
-        let result = p1 + p2;
-
-        assert_eq!(result, Point2DMm::new(4.0, 6.0));
-    }
-
-    #[test]
-    pub fn test_add_assign() {
-        let mut p1 = Point2DMm::new(1.0, 2.0);
-        p1 += vec2(3.0, 4.0);
-
-        assert_eq!(p1, Point2DMm::new(4.0, 6.0));
-    }
-
-    #[test]
-    pub fn test_scalar_mul() {
-        let p1 = Point2DMm::new(1.0, 2.0);
-        let cm_per_mm: ScaleFactor<f32, Mm, Cm> = ScaleFactor::new(0.1);
-
-        let result = p1 * cm_per_mm;
-
-        assert_eq!(result, Point2DCm::new(0.1, 0.2));
-    }
-
-    #[test]
-    pub fn test_conv_vector() {
-        use {Point2D, point2};
-
-        for i in 0..100 {
-            // We don't care about these values as long as they are not the same.
-            let x = i as f32 *0.012345;
-            let y = i as f32 *0.987654;
-            let p: Point2D<f32> = point2(x, y);
-            assert_eq!(p.to_vector().to_point(), p);
-        }
-    }
-
-    #[test]
-    pub fn test_swizzling() {
-        let p: Point2D<i32> = point2(1, 2);
-        assert_eq!(p.yx(), point2(2, 1));
-    }
-}
-
-#[cfg(test)]
-mod point3d {
-    use super::{Point3D, point2, point3};
-
-    #[test]
-    pub fn test_min() {
-        let p1 = Point3D::new(1.0, 3.0, 5.0);
-        let p2 = Point3D::new(2.0, 2.0, -1.0);
-
-        let result = p1.min(p2);
-
-        assert_eq!(result, Point3D::new(1.0, 2.0, -1.0));
-    }
-
-    #[test]
-    pub fn test_max() {
-        let p1 = Point3D::new(1.0, 3.0, 5.0);
-        let p2 = Point3D::new(2.0, 2.0, -1.0);
-
-        let result = p1.max(p2);
-
-        assert_eq!(result, Point3D::new(2.0, 3.0, 5.0));
-    }
-
-    #[test]
-    pub fn test_conv_vector() {
-        use point3;
-        for i in 0..100 {
-            // We don't care about these values as long as they are not the same.
-            let x = i as f32 *0.012345;
-            let y = i as f32 *0.987654;
-            let z = x * y;
-            let p: Point3D<f32> = point3(x, y, z);
-            assert_eq!(p.to_vector().to_point(), p);
-        }
-    }
-
-    #[test]
-    pub fn test_swizzling() {
-        let p: Point3D<i32> = point3(1, 2, 3);
-        assert_eq!(p.xy(), point2(1, 2));
-        assert_eq!(p.xz(), point2(1, 3));
-        assert_eq!(p.yz(), point2(2, 3));
-    }
-}
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/rect.rs
+++ /dev/null
@@ -1,700 +0,0 @@
-// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use super::UnknownUnit;
-use length::Length;
-use scale_factor::ScaleFactor;
-use num::*;
-use point::TypedPoint2D;
-use vector::TypedVector2D;
-use size::TypedSize2D;
-
-use heapsize::HeapSizeOf;
-use num_traits::NumCast;
-use serde::{Deserialize, Deserializer, Serialize, Serializer};
-use std::cmp::PartialOrd;
-use std::fmt;
-use std::hash::{Hash, Hasher};
-use std::ops::{Add, Sub, Mul, Div};
-
-/// A 2d Rectangle optionally tagged with a unit.
-#[repr(C)]
-pub struct TypedRect<T, U = UnknownUnit> {
-    pub origin: TypedPoint2D<T, U>,
-    pub size: TypedSize2D<T, U>,
-}
-
-/// The default rectangle type with no unit.
-pub type Rect<T> = TypedRect<T, UnknownUnit>;
-
-impl<T: HeapSizeOf, U> HeapSizeOf for TypedRect<T, U> {
-    fn heap_size_of_children(&self) -> usize {
-        self.origin.heap_size_of_children() + self.size.heap_size_of_children()
-    }
-}
-
-impl<'de, T: Copy + Deserialize<'de>, U> Deserialize<'de> for TypedRect<T, U> {
-    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-        where D: Deserializer<'de>
-    {
-        let (origin, size) = try!(Deserialize::deserialize(deserializer));
-        Ok(TypedRect::new(origin, size))
-    }
-}
-
-impl<T: Serialize, U> Serialize for TypedRect<T, U> {
-    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-        where S: Serializer
-    {
-        (&self.origin, &self.size).serialize(serializer)
-    }
-}
-
-impl<T: Hash, U> Hash for TypedRect<T, U>
-{
-    fn hash<H: Hasher>(&self, h: &mut H) {
-        self.origin.hash(h);
-        self.size.hash(h);
-    }
-}
-
-impl<T: Copy, U> Copy for TypedRect<T, U> {}
-
-impl<T: Copy, U> Clone for TypedRect<T, U> {
-    fn clone(&self) -> Self { *self }
-}
-
-impl<T: PartialEq, U> PartialEq<TypedRect<T, U>> for TypedRect<T, U> {
-    fn eq(&self, other: &Self) -> bool {
-        self.origin.eq(&other.origin) && self.size.eq(&other.size)
-    }
-}
-
-impl<T: Eq, U> Eq for TypedRect<T, U> {}
-
-impl<T: fmt::Debug, U> fmt::Debug for TypedRect<T, U> {
-   fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "TypedRect({:?} at {:?})", self.size, self.origin)
-    }
-}
-
-impl<T: fmt::Display, U> fmt::Display for TypedRect<T, U> {
-    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
-        write!(formatter, "Rect({} at {})", self.size, self.origin)
-    }
-}
-
-impl<T, U> TypedRect<T, U> {
-    /// Constructor.
-    pub fn new(origin: TypedPoint2D<T, U>, size: TypedSize2D<T, U>) -> Self {
-        TypedRect {
-            origin: origin,
-            size: size,
-        }
-    }
-}
-
-impl<T, U> TypedRect<T, U>
-where T: Copy + Clone + Zero + PartialOrd + PartialEq + Add<T, Output=T> + Sub<T, Output=T> {
-    #[inline]
-    pub fn intersects(&self, other: &Self) -> bool {
-        self.origin.x < other.origin.x + other.size.width &&
-       other.origin.x <  self.origin.x + self.size.width &&
-        self.origin.y < other.origin.y + other.size.height &&
-       other.origin.y <  self.origin.y + self.size.height
-    }
-
-    #[inline]
-    pub fn max_x(&self) -> T {
-        self.origin.x + self.size.width
-    }
-
-    #[inline]
-    pub fn min_x(&self) -> T {
-        self.origin.x
-    }
-
-    #[inline]
-    pub fn max_y(&self) -> T {
-        self.origin.y + self.size.height
-    }
-
-    #[inline]
-    pub fn min_y(&self) -> T {
-        self.origin.y
-    }
-
-    #[inline]
-    pub fn max_x_typed(&self) -> Length<T, U> {
-        Length::new(self.max_x())
-    }
-
-    #[inline]
-    pub fn min_x_typed(&self) -> Length<T, U> {
-        Length::new(self.min_x())
-    }
-
-    #[inline]
-    pub fn max_y_typed(&self) -> Length<T, U> {
-        Length::new(self.max_y())
-    }
-
-    #[inline]
-    pub fn min_y_typed(&self) -> Length<T, U> {
-        Length::new(self.min_y())
-    }
-
-    #[inline]
-    pub fn intersection(&self, other: &Self) -> Option<Self> {
-        if !self.intersects(other) {
-            return None;
-        }
-
-        let upper_left = TypedPoint2D::new(max(self.min_x(), other.min_x()),
-                                      max(self.min_y(), other.min_y()));
-        let lower_right_x = min(self.max_x(), other.max_x());
-        let lower_right_y = min(self.max_y(), other.max_y());
-
-        Some(TypedRect::new(upper_left, TypedSize2D::new(lower_right_x - upper_left.x,
-                                                    lower_right_y - upper_left.y)))
-    }
-
-    /// Returns the same rectangle, translated by a vector.
-    #[inline]
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn translate(&self, by: &TypedVector2D<T, U>) -> Self {
-        Self::new(self.origin + *by, self.size)
-    }
-
-    /// Returns true if this rectangle contains the point. Points are considered
-    /// in the rectangle if they are on the left or top edge, but outside if they
-    /// are on the right or bottom edge.
-    #[inline]
-    pub fn contains(&self, other: &TypedPoint2D<T, U>) -> bool {
-        self.origin.x <= other.x && other.x < self.origin.x + self.size.width &&
-        self.origin.y <= other.y && other.y < self.origin.y + self.size.height
-    }
-
-    /// Returns true if this rectangle contains the interior of rect. Always
-    /// returns true if rect is empty, and always returns false if rect is
-    /// nonempty but this rectangle is empty.
-    #[inline]
-    pub fn contains_rect(&self, rect: &Self) -> bool {
-        rect.is_empty() ||
-            (self.min_x() <= rect.min_x() && rect.max_x() <= self.max_x() &&
-             self.min_y() <= rect.min_y() && rect.max_y() <= self.max_y())
-    }
-
-    #[inline]
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn inflate(&self, width: T, height: T) -> Self {
-        TypedRect::new(
-            TypedPoint2D::new(self.origin.x - width, self.origin.y - height),
-            TypedSize2D::new(self.size.width + width + width, self.size.height + height + height),
-        )
-    }
-
-    #[inline]
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn inflate_typed(&self, width: Length<T, U>, height: Length<T, U>) -> Self {
-        self.inflate(width.get(), height.get())
-    }
-
-    #[inline]
-    pub fn top_right(&self) -> TypedPoint2D<T, U> {
-        TypedPoint2D::new(self.max_x(), self.origin.y)
-    }
-
-    #[inline]
-    pub fn bottom_left(&self) -> TypedPoint2D<T, U> {
-        TypedPoint2D::new(self.origin.x, self.max_y())
-    }
-
-    #[inline]
-    pub fn bottom_right(&self) -> TypedPoint2D<T, U> {
-        TypedPoint2D::new(self.max_x(), self.max_y())
-    }
-
-    #[inline]
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn translate_by_size(&self, size: &TypedSize2D<T, U>) -> Self {
-        self.translate(&size.to_vector())
-    }
-
-    /// Returns the smallest rectangle containing the four points.
-    pub fn from_points(points: &[TypedPoint2D<T, U>]) -> Self {
-        if points.len() == 0 {
-            return TypedRect::zero();
-        }
-        let (mut min_x, mut min_y) = (points[0].x, points[0].y);
-        let (mut max_x, mut max_y) = (min_x, min_y);
-        for point in &points[1..] {
-            if point.x < min_x {
-                min_x = point.x
-            }
-            if point.x > max_x {
-                max_x = point.x
-            }
-            if point.y < min_y {
-                min_y = point.y
-            }
-            if point.y > max_y {
-                max_y = point.y
-            }
-        }
-        TypedRect::new(TypedPoint2D::new(min_x, min_y),
-                       TypedSize2D::new(max_x - min_x, max_y - min_y))
-    }
-}
-
-impl<T, U> TypedRect<T, U>
-where T: Copy + One + Add<Output=T> + Sub<Output=T> + Mul<Output=T> {
-    /// Linearly interpolate between this rectangle and another rectange.
-    ///
-    /// `t` is expected to be between zero and one.
-    #[inline]
-    pub fn lerp(&self, other: Self, t: T) -> Self {
-        Self::new(
-            self.origin.lerp(other.origin, t),
-            self.size.lerp(other.size, t),
-        )
-    }
-}
-
-impl<T, U> TypedRect<T, U>
-where T: Copy + Clone + PartialOrd + Add<T, Output=T> + Sub<T, Output=T> + Zero {
-    #[inline]
-    pub fn union(&self, other: &Self) -> Self {
-        if self.size == Zero::zero() {
-            return *other;
-        }
-        if other.size == Zero::zero() {
-            return *self;
-        }
-
-        let upper_left = TypedPoint2D::new(min(self.min_x(), other.min_x()),
-                                      min(self.min_y(), other.min_y()));
-
-        let lower_right_x = max(self.max_x(), other.max_x());
-        let lower_right_y = max(self.max_y(), other.max_y());
-
-        TypedRect::new(
-            upper_left,
-            TypedSize2D::new(lower_right_x - upper_left.x, lower_right_y - upper_left.y)
-        )
-    }
-}
-
-impl<T, U> TypedRect<T, U> {
-    #[inline]
-    pub fn scale<Scale: Copy>(&self, x: Scale, y: Scale) -> Self
-        where T: Copy + Clone + Mul<Scale, Output=T> {
-        TypedRect::new(
-            TypedPoint2D::new(self.origin.x * x, self.origin.y * y),
-            TypedSize2D::new(self.size.width * x, self.size.height * y)
-        )
-    }
-}
-
-impl<T: Copy + PartialEq + Zero, U> TypedRect<T, U> {
-    /// Constructor, setting all sides to zero.
-    pub fn zero() -> Self {
-        TypedRect::new(
-            TypedPoint2D::origin(),
-            TypedSize2D::zero(),
-        )
-    }
-
-    /// Returns true if the size is zero, regardless of the origin's value.
-    pub fn is_empty(&self) -> bool {
-        self.size.width == Zero::zero() || self.size.height == Zero::zero()
-    }
-}
-
-
-pub fn min<T: Clone + PartialOrd>(x: T, y: T) -> T {
-    if x <= y { x } else { y }
-}
-
-pub fn max<T: Clone + PartialOrd>(x: T, y: T) -> T {
-    if x >= y { x } else { y }
-}
-
-impl<T: Copy + Mul<T, Output=T>, U> Mul<T> for TypedRect<T, U> {
-    type Output = Self;
-    #[inline]
-    fn mul(self, scale: T) -> Self {
-        TypedRect::new(self.origin * scale, self.size * scale)
-    }
-}
-
-impl<T: Copy + Div<T, Output=T>, U> Div<T> for TypedRect<T, U> {
-    type Output = Self;
-    #[inline]
-    fn div(self, scale: T) -> Self {
-        TypedRect::new(self.origin / scale, self.size / scale)
-    }
-}
-
-impl<T: Copy + Mul<T, Output=T>, U1, U2> Mul<ScaleFactor<T, U1, U2>> for TypedRect<T, U1> {
-    type Output = TypedRect<T, U2>;
-    #[inline]
-    fn mul(self, scale: ScaleFactor<T, U1, U2>) -> TypedRect<T, U2> {
-        TypedRect::new(self.origin * scale, self.size * scale)
-    }
-}
-
-impl<T: Copy + Div<T, Output=T>, U1, U2> Div<ScaleFactor<T, U1, U2>> for TypedRect<T, U2> {
-    type Output = TypedRect<T, U1>;
-    #[inline]
-    fn div(self, scale: ScaleFactor<T, U1, U2>) -> TypedRect<T, U1> {
-        TypedRect::new(self.origin / scale, self.size / scale)
-    }
-}
-
-impl<T: Copy, Unit> TypedRect<T, Unit> {
-    /// Drop the units, preserving only the numeric value.
-    pub fn to_untyped(&self) -> Rect<T> {
-        TypedRect::new(self.origin.to_untyped(), self.size.to_untyped())
-    }
-
-    /// Tag a unitless value with units.
-    pub fn from_untyped(r: &Rect<T>) -> TypedRect<T, Unit> {
-        TypedRect::new(TypedPoint2D::from_untyped(&r.origin), TypedSize2D::from_untyped(&r.size))
-    }
-}
-
-impl<T0: NumCast + Copy, Unit> TypedRect<T0, Unit> {
-    /// Cast from one numeric representation to another, preserving the units.
-    ///
-    /// When casting from floating point to integer coordinates, the decimals are truncated
-    /// as one would expect from a simple cast, but this behavior does not always make sense
-    /// geometrically. Consider using round(), round_in or round_out() before casting.
-    pub fn cast<T1: NumCast + Copy>(&self) -> Option<TypedRect<T1, Unit>> {
-        match (self.origin.cast(), self.size.cast()) {
-            (Some(origin), Some(size)) => Some(TypedRect::new(origin, size)),
-            _ => None
-        }
-    }
-}
-
-impl<T: Floor + Ceil + Round + Add<T, Output=T> + Sub<T, Output=T>, U> TypedRect<T, U> {
-    /// Return a rectangle with edges rounded to integer coordinates, such that
-    /// the returned rectangle has the same set of pixel centers as the original
-    /// one.
-    /// Edges at offset 0.5 round up.
-    /// Suitable for most places where integral device coordinates
-    /// are needed, but note that any translation should be applied first to
-    /// avoid pixel rounding errors.
-    /// Note that this is *not* rounding to nearest integer if the values are negative.
-    /// They are always rounding as floor(n + 0.5).
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn round(&self) -> Self {
-        let origin = self.origin.round();
-        let size = self.origin.add_size(&self.size).round() - origin;
-        TypedRect::new(origin, TypedSize2D::new(size.x, size.y))
-    }
-
-    /// Return a rectangle with edges rounded to integer coordinates, such that
-    /// the original rectangle contains the resulting rectangle.
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn round_in(&self) -> Self {
-        let origin = self.origin.ceil();
-        let size = self.origin.add_size(&self.size).floor() - origin;
-        TypedRect::new(origin, TypedSize2D::new(size.x, size.y))
-    }
-
-    /// Return a rectangle with edges rounded to integer coordinates, such that
-    /// the original rectangle is contained in the resulting rectangle.
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn round_out(&self) -> Self {
-        let origin = self.origin.floor();
-        let size = self.origin.add_size(&self.size).ceil() - origin;
-        TypedRect::new(origin, TypedSize2D::new(size.x, size.y))
-    }
-}
-
-// Convenience functions for common casts
-impl<T: NumCast + Copy, Unit> TypedRect<T, Unit> {
-    /// Cast into an `f32` rectangle.
-    pub fn to_f32(&self) -> TypedRect<f32, Unit> {
-        self.cast().unwrap()
-    }
-
-    /// Cast into an `usize` rectangle, truncating decimals if any.
-    ///
-    /// When casting from floating point rectangles, it is worth considering whether
-    /// to `round()`, `round_in()` or `round_out()` before the cast in order to
-    /// obtain the desired conversion behavior.
-    pub fn to_usize(&self) -> TypedRect<usize, Unit> {
-        self.cast().unwrap()
-    }
-
-    /// Cast into an `i32` rectangle, truncating decimals if any.
-    ///
-    /// When casting from floating point rectangles, it is worth considering whether
-    /// to `round()`, `round_in()` or `round_out()` before the cast in order to
-    /// obtain the desired conversion behavior.
-    pub fn to_i32(&self) -> TypedRect<i32, Unit> {
-        self.cast().unwrap()
-    }
-
-    /// Cast into an `i64` rectangle, truncating decimals if any.
-    ///
-    /// When casting from floating point rectangles, it is worth considering whether
-    /// to `round()`, `round_in()` or `round_out()` before the cast in order to
-    /// obtain the desired conversion behavior.
-    pub fn to_i64(&self) -> TypedRect<i64, Unit> {
-        self.cast().unwrap()
-    }
-}
-
-/// Shorthand for `TypedRect::new(TypedPoint2D::new(x, y), TypedSize2D::new(w, h))`.
-pub fn rect<T: Copy, U>(x: T, y: T, w: T, h: T) -> TypedRect<T, U> {
-    TypedRect::new(TypedPoint2D::new(x, y), TypedSize2D::new(w, h))
-}
-
-#[cfg(test)]
-mod tests {
-    use point::Point2D;
-    use vector::vec2;
-    use size::Size2D;
-    use super::*;
-
-    #[test]
-    fn test_min_max() {
-        assert!(min(0u32, 1u32) == 0u32);
-        assert!(min(-1.0f32, 0.0f32) == -1.0f32);
-
-        assert!(max(0u32, 1u32) == 1u32);
-        assert!(max(-1.0f32, 0.0f32) == 0.0f32);
-    }
-
-    #[test]
-    fn test_translate() {
-        let p = Rect::new(Point2D::new(0u32, 0u32), Size2D::new(50u32, 40u32));
-        let pp = p.translate(&vec2(10,15));
-
-        assert!(pp.size.width == 50);
-        assert!(pp.size.height == 40);
-        assert!(pp.origin.x == 10);
-        assert!(pp.origin.y == 15);
-
-
-        let r = Rect::new(Point2D::new(-10, -5), Size2D::new(50, 40));
-        let rr = r.translate(&vec2(0,-10));
-
-        assert!(rr.size.width == 50);
-        assert!(rr.size.height == 40);
-        assert!(rr.origin.x == -10);
-        assert!(rr.origin.y == -15);
-    }
-
-    #[test]
-    fn test_translate_by_size() {
-        let p = Rect::new(Point2D::new(0u32, 0u32), Size2D::new(50u32, 40u32));
-        let pp = p.translate_by_size(&Size2D::new(10,15));
-
-        assert!(pp.size.width == 50);
-        assert!(pp.size.height == 40);
-        assert!(pp.origin.x == 10);
-        assert!(pp.origin.y == 15);
-
-
-        let r = Rect::new(Point2D::new(-10, -5), Size2D::new(50, 40));
-        let rr = r.translate_by_size(&Size2D::new(0,-10));
-
-        assert!(rr.size.width == 50);
-        assert!(rr.size.height == 40);
-        assert!(rr.origin.x == -10);
-        assert!(rr.origin.y == -15);
-    }
-
-    #[test]
-    fn test_union() {
-        let p = Rect::new(Point2D::new(0, 0), Size2D::new(50, 40));
-        let q = Rect::new(Point2D::new(20,20), Size2D::new(5, 5));
-        let r = Rect::new(Point2D::new(-15, -30), Size2D::new(200, 15));
-        let s = Rect::new(Point2D::new(20, -15), Size2D::new(250, 200));
-
-        let pq = p.union(&q);
-        assert!(pq.origin == Point2D::new(0, 0));
-        assert!(pq.size == Size2D::new(50, 40));
-
-        let pr = p.union(&r);
-        assert!(pr.origin == Point2D::new(-15, -30));
-        assert!(pr.size == Size2D::new(200, 70));
-
-        let ps = p.union(&s);
-        assert!(ps.origin == Point2D::new(0, -15));
-        assert!(ps.size == Size2D::new(270, 200));
-
-    }
-
-    #[test]
-    fn test_intersection() {
-        let p = Rect::new(Point2D::new(0, 0), Size2D::new(10, 20));
-        let q = Rect::new(Point2D::new(5, 15), Size2D::new(10, 10));
-        let r = Rect::new(Point2D::new(-5, -5), Size2D::new(8, 8));
-
-        let pq = p.intersection(&q);
-        assert!(pq.is_some());
-        let pq = pq.unwrap();
-        assert!(pq.origin == Point2D::new(5, 15));
-        assert!(pq.size == Size2D::new(5, 5));
-
-        let pr = p.intersection(&r);
-        assert!(pr.is_some());
-        let pr = pr.unwrap();
-        assert!(pr.origin == Point2D::new(0, 0));
-        assert!(pr.size == Size2D::new(3, 3));
-
-        let qr = q.intersection(&r);
-        assert!(qr.is_none());
-    }
-
-    #[test]
-    fn test_contains() {
-        let r = Rect::new(Point2D::new(-20, 15), Size2D::new(100, 200));
-
-        assert!(r.contains(&Point2D::new(0, 50)));
-        assert!(r.contains(&Point2D::new(-10, 200)));
-
-        // The `contains` method is inclusive of the top/left edges, but not the
-        // bottom/right edges.
-        assert!(r.contains(&Point2D::new(-20, 15)));
-        assert!(!r.contains(&Point2D::new(80, 15)));
-        assert!(!r.contains(&Point2D::new(80, 215)));
-        assert!(!r.contains(&Point2D::new(-20, 215)));
-
-        // Points beyond the top-left corner.
-        assert!(!r.contains(&Point2D::new(-25, 15)));
-        assert!(!r.contains(&Point2D::new(-15, 10)));
-
-        // Points beyond the top-right corner.
-        assert!(!r.contains(&Point2D::new(85, 20)));
-        assert!(!r.contains(&Point2D::new(75, 10)));
-
-        // Points beyond the bottom-right corner.
-        assert!(!r.contains(&Point2D::new(85, 210)));
-        assert!(!r.contains(&Point2D::new(75, 220)));
-
-        // Points beyond the bottom-left corner.
-        assert!(!r.contains(&Point2D::new(-25, 210)));
-        assert!(!r.contains(&Point2D::new(-15, 220)));
-
-        let r = Rect::new(Point2D::new(-20.0, 15.0), Size2D::new(100.0, 200.0));
-        assert!(r.contains_rect(&r));
-        assert!(!r.contains_rect(&r.translate(&vec2( 0.1,  0.0))));
-        assert!(!r.contains_rect(&r.translate(&vec2(-0.1,  0.0))));
-        assert!(!r.contains_rect(&r.translate(&vec2( 0.0,  0.1))));
-        assert!(!r.contains_rect(&r.translate(&vec2( 0.0, -0.1))));
-        // Empty rectangles are always considered as contained in other rectangles,
-        // even if their origin is not.
-        let p = Point2D::new(1.0, 1.0);
-        assert!(!r.contains(&p));
-        assert!(r.contains_rect(&Rect::new(p, Size2D::zero())));
-    }
-
-    #[test]
-    fn test_scale() {
-        let p = Rect::new(Point2D::new(0u32, 0u32), Size2D::new(50u32, 40u32));
-        let pp = p.scale(10, 15);
-
-        assert!(pp.size.width == 500);
-        assert!(pp.size.height == 600);
-        assert!(pp.origin.x == 0);
-        assert!(pp.origin.y == 0);
-
-        let r = Rect::new(Point2D::new(-10, -5), Size2D::new(50, 40));
-        let rr = r.scale(1, 20);
-
-        assert!(rr.size.width == 50);
-        assert!(rr.size.height == 800);
-        assert!(rr.origin.x == -10);
-        assert!(rr.origin.y == -100);
-    }
-
-    #[test]
-    fn test_inflate() {
-        let p = Rect::new(Point2D::new(0, 0), Size2D::new(10, 10));
-        let pp = p.inflate(10, 20);
-
-        assert!(pp.size.width == 30);
-        assert!(pp.size.height == 50);
-        assert!(pp.origin.x == -10);
-        assert!(pp.origin.y == -20);
-
-        let r = Rect::new(Point2D::new(0, 0), Size2D::new(10, 20));
-        let rr = r.inflate(-2, -5);
-
-        assert!(rr.size.width == 6);
-        assert!(rr.size.height == 10);
-        assert!(rr.origin.x == 2);
-        assert!(rr.origin.y == 5);
-    }
-
-    #[test]
-    fn test_min_max_x_y() {
-        let p = Rect::new(Point2D::new(0u32, 0u32), Size2D::new(50u32, 40u32));
-        assert!(p.max_y() == 40);
-        assert!(p.min_y() == 0);
-        assert!(p.max_x() == 50);
-        assert!(p.min_x() == 0);
-
-        let r = Rect::new(Point2D::new(-10, -5), Size2D::new(50, 40));
-        assert!(r.max_y() == 35);
-        assert!(r.min_y() == -5);
-        assert!(r.max_x() == 40);
-        assert!(r.min_x() == -10);
-    }
-
-    #[test]
-    fn test_is_empty() {
-        assert!(Rect::new(Point2D::new(0u32, 0u32), Size2D::new(0u32, 0u32)).is_empty());
-        assert!(Rect::new(Point2D::new(0u32, 0u32), Size2D::new(10u32, 0u32)).is_empty());
-        assert!(Rect::new(Point2D::new(0u32, 0u32), Size2D::new(0u32, 10u32)).is_empty());
-        assert!(!Rect::new(Point2D::new(0u32, 0u32), Size2D::new(1u32, 1u32)).is_empty());
-        assert!(Rect::new(Point2D::new(10u32, 10u32), Size2D::new(0u32, 0u32)).is_empty());
-        assert!(Rect::new(Point2D::new(10u32, 10u32), Size2D::new(10u32, 0u32)).is_empty());
-        assert!(Rect::new(Point2D::new(10u32, 10u32), Size2D::new(0u32, 10u32)).is_empty());
-        assert!(!Rect::new(Point2D::new(10u32, 10u32), Size2D::new(1u32, 1u32)).is_empty());
-    }
-
-    #[test]
-    fn test_round() {
-        let mut x = -2.0;
-        let mut y = -2.0;
-        let mut w = -2.0;
-        let mut h = -2.0;
-        while x < 2.0 {
-            while y < 2.0 {
-                while w < 2.0 {
-                    while h < 2.0 {
-                        let rect = Rect::new(Point2D::new(x, y), Size2D::new(w, h));
-
-                        assert!(rect.contains_rect(&rect.round_in()));
-                        assert!(rect.round_in().inflate(1.0, 1.0).contains_rect(&rect));
-
-                        assert!(rect.round_out().contains_rect(&rect));
-                        assert!(rect.inflate(1.0, 1.0).contains_rect(&rect.round_out()));
-
-                        assert!(rect.inflate(1.0, 1.0).contains_rect(&rect.round()));
-                        assert!(rect.round().inflate(1.0, 1.0).contains_rect(&rect));
-
-                        h += 0.1;
-                    }
-                    w += 0.1;
-                }
-                y += 0.1;
-            }
-            x += 0.1
-        }
-    }
-}
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/rotation.rs
+++ /dev/null
@@ -1,696 +0,0 @@
-// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use approxeq::ApproxEq;
-use num_traits::{Float, One, Zero};
-use std::fmt;
-use std::ops::{Add, Neg, Mul, Sub, Div};
-use std::marker::PhantomData;
-use trig::Trig;
-use {TypedPoint2D, TypedPoint3D, TypedVector2D, TypedVector3D, Vector3D, point2, point3, vec3};
-use {TypedTransform3D, TypedTransform2D, UnknownUnit, Radians};
-
-
-define_matrix! {
-    /// A transform that can represent rotations in 2d, represented as an angle in radians.
-    pub struct TypedRotation2D<T, Src, Dst> {
-        pub angle : T,
-    }
-}
-
-/// The default 2d rotation type with no units.
-pub type Rotation2D<T> = TypedRotation2D<T, UnknownUnit, UnknownUnit>;
-
-impl<T, Src, Dst> TypedRotation2D<T, Src, Dst> {
-    #[inline]
-    /// Creates a rotation from an angle in radians.
-    pub fn new(angle: Radians<T>) -> Self {
-        TypedRotation2D {
-            angle: angle.0,
-            _unit: PhantomData,
-        }
-    }
-
-    pub fn radians(angle: T) -> Self {
-        Self::new(Radians::new(angle))
-    }
-
-    /// Creates the identity rotation.
-    #[inline]
-    pub fn identity() -> Self where T: Zero {
-        Self::radians(T::zero())
-    }
-}
-
-impl<T, Src, Dst> TypedRotation2D<T, Src, Dst> where T: Clone
-{
-    /// Returns self.angle as a strongly typed `Radians<T>`.
-    pub fn get_angle(&self) -> Radians<T> {
-        Radians::new(self.angle.clone())
-    }
-}
-
-
-impl<T, Src, Dst> TypedRotation2D<T, Src, Dst>
-where T: Copy + Clone +
-         Add<T, Output=T> +
-         Sub<T, Output=T> +
-         Mul<T, Output=T> +
-         Div<T, Output=T> +
-         Neg<Output=T> +
-         ApproxEq<T> +
-         PartialOrd +
-         Float +
-         One + Zero
-{
-    /// Creates a 3d rotation (around the z axis) from this 2d rotation.
-    #[inline]
-    pub fn to_3d(&self) -> TypedRotation3D<T, Src, Dst> {
-        TypedRotation3D::around_z(self.get_angle())
-    }
-
-    /// Returns the inverse of this rotation.
-    #[inline]
-    pub fn inverse(&self) -> TypedRotation2D<T, Dst, Src> {
-        TypedRotation2D::radians(-self.angle)
-    }
-
-    /// Returns a rotation representing the other rotation followed by this rotation.
-    #[inline]
-    pub fn pre_rotate<NewSrc>(&self, other: &TypedRotation2D<T, NewSrc, Src>) -> TypedRotation2D<T, NewSrc, Dst> {
-        TypedRotation2D::radians(self.angle + other.angle)
-    }
-
-    /// Returns a rotation representing this rotation followed by the other rotation.
-    #[inline]
-    pub fn post_rotate<NewDst>(&self, other: &TypedRotation2D<T, Dst, NewDst>) -> TypedRotation2D<T, Src, NewDst> {
-        other.pre_rotate(self)
-    }
-
-    /// Returns the given 2d point transformed by this rotation.
-    ///
-    /// The input point must be use the unit Src, and the returned point has the unit Dst.
-    #[inline]
-    pub fn transform_point(&self, point: &TypedPoint2D<T, Src>) -> TypedPoint2D<T, Dst> {
-        let (sin, cos) = Float::sin_cos(self.angle);
-        point2(
-            point.x * cos - point.y * sin,
-            point.y * cos + point.x * sin,
-        )
-    }
-
-    /// Returns the given 2d vector transformed by this rotation.
-    ///
-    /// The input point must be use the unit Src, and the returned point has the unit Dst.
-    #[inline]
-    pub fn transform_vector(&self, vector: &TypedVector2D<T, Src>) -> TypedVector2D<T, Dst> {
-        self.transform_point(&vector.to_point()).to_vector()
-    }
-}
-
-impl<T, Src, Dst> TypedRotation2D<T, Src, Dst>
-where T: Copy + Clone +
-         Add<T, Output=T> +
-         Mul<T, Output=T> +
-         Div<T, Output=T> +
-         Sub<T, Output=T> +
-         Trig +
-         PartialOrd +
-         One + Zero
-{
-    /// Returns the matrix representation of this rotation.
-    #[inline]
-    pub fn to_transform(&self) -> TypedTransform2D<T, Src, Dst> {
-        TypedTransform2D::create_rotation(self.get_angle())
-    }
-}
-
-define_matrix! {
-    /// A transform that can represent rotations in 3d, represented as a quaternion.
-    ///
-    /// Most methods expect the quaternion to be normalized.
-    /// When in doubt, use `unit_quaternion` instead of `quaternion` to create
-    /// a rotation as the former will ensure that its result is normalized.
-    ///
-    /// Some people use the `x, y, z, w` (or `w, x, y, z`) notations. The equivalence is
-    /// as follows: `x -> i`, `y -> j`, `z -> k`, `w -> r`.
-    /// The memory layout of this type corresponds to the `x, y, z, w` notation
-    pub struct TypedRotation3D<T, Src, Dst> {
-        // Component multiplied by the imaginary number `i`.
-        pub i: T,
-        // Component multiplied by the imaginary number `j`.
-        pub j: T,
-        // Component multiplied by the imaginary number `k`.
-        pub k: T,
-        // The real part.
-        pub r: T,
-    }
-}
-
-/// The default 3d rotation type with no units.
-pub type Rotation3D<T> = TypedRotation3D<T, UnknownUnit, UnknownUnit>;
-
-impl<T, Src, Dst> TypedRotation3D<T, Src, Dst> {
-    /// Creates a rotation around from a quaternion representation.
-    ///
-    /// The parameters are a, b, c and r compose the quaternion `a*i + b*j + c*k + r`
-    /// where `a`, `b` and `c` describe the vector part and the last parameter `r` is
-    /// the real part.
-    ///
-    /// The resulting quaternion is not necessarily normalized. See `unit_quaternion`.
-    #[inline]
-    pub fn quaternion(a: T, b: T, c: T, r: T) -> Self {
-        TypedRotation3D { i: a, j: b, k: c, r, _unit: PhantomData }
-    }
-}
-
-
-impl<T, Src, Dst> TypedRotation3D<T, Src, Dst> where T: Copy {
-    /// Returns the vector part (i, j, k) of this quaternion.
-    #[inline]
-    pub fn vector_part(&self) -> Vector3D<T> { vec3(self.i, self.j, self.k) }
-}
-
-impl<T, Src, Dst> TypedRotation3D<T, Src, Dst>
-where T: Copy + Clone +
-         Add<T, Output=T> +
-         Sub<T, Output=T> +
-         Mul<T, Output=T> +
-         Div<T, Output=T> +
-         Neg<Output=T> +
-         ApproxEq<T> +
-         PartialOrd +
-         Float +
-         One + Zero
-{
-    /// Creates the identity rotation.
-    #[inline]
-    pub fn identity() -> Self {
-        let zero = T::zero();
-        let one = T::one();
-        Self::quaternion(zero, zero, zero, one)
-    }
-
-    /// Creates a rotation around from a quaternion representation and normalizes it.
-    ///
-    /// The parameters are a, b, c and r compose the quaternion `a*i + b*j + c*k + r`
-    /// before normalization, where `a`, `b` and `c` describe the vector part and the
-    /// last parameter `r` is the real part.
-    #[inline]
-    pub fn unit_quaternion(i: T, j: T, k: T, r: T) -> Self {
-        Self::quaternion(i, j, k, r).normalize()
-    }
-
-    /// Creates a rotation around a given axis.
-    pub fn around_axis(axis: TypedVector3D<T, Src>, angle: Radians<T>) -> Self {
-        let axis = axis.normalize();
-        let two = T::one() + T::one();
-        let (sin, cos) = Float::sin_cos(angle.get() / two);
-        Self::quaternion(axis.x * sin, axis.y * sin, axis.z * sin, cos)
-    }
-
-    /// Creates a rotation around the x axis.
-    pub fn around_x(angle: Radians<T>) -> Self {
-        let zero = Zero::zero();
-        let two = T::one() + T::one();
-        let (sin, cos) = Float::sin_cos(angle.get() / two);
-        Self::quaternion(sin, zero, zero, cos)
-    }
-
-    /// Creates a rotation around the y axis.
-    pub fn around_y(angle: Radians<T>) -> Self {
-        let zero = Zero::zero();
-        let two = T::one() + T::one();
-        let (sin, cos) = Float::sin_cos(angle.get() / two);
-        Self::quaternion(zero, sin, zero, cos)
-    }
-
-    /// Creates a rotation around the z axis.
-    pub fn around_z(angle: Radians<T>) -> Self {
-        let zero = Zero::zero();
-        let two = T::one() + T::one();
-        let (sin, cos) = Float::sin_cos(angle.get() / two);
-        Self::quaternion(zero, zero, sin, cos)
-    }
-
-    /// Creates a rotation from euler angles.
-    ///
-    /// The rotations are applied in roll then pitch then yaw order.
-    ///
-    ///  - Roll (also calld bank) is a rotation around the x axis.
-    ///  - Pitch (also calld bearing) is a rotation around the y axis.
-    ///  - Yaw (also calld heading) is a rotation around the z axis.
-    pub fn euler(roll: Radians<T>, pitch: Radians<T>, yaw: Radians<T>) -> Self {
-        let half = T::one() / (T::one() + T::one());
-
-	    let (sy, cy) = Float::sin_cos(half * yaw.get());
-	    let (sp, cp) = Float::sin_cos(half * pitch.get());
-	    let (sr, cr) = Float::sin_cos(half * roll.get());
-
-        Self::quaternion(
-            cy * sr * cp - sy * cr * sp,
-            cy * cr * sp + sy * sr * cp,
-            sy * cr * cp - cy * sr * sp,
-            cy * cr * cp + sy * sr * sp,
-        )
-    }
-
-    /// Returns the inverse of this rotation.
-    #[inline]
-    pub fn inverse(&self) -> TypedRotation3D<T, Dst, Src> {
-        TypedRotation3D::quaternion(-self.i, -self.j, -self.k, self.r)
-    }
-
-    /// Computes the norm of this quaternion
-    #[inline]
-    pub fn norm(&self) -> T {
-        self.square_norm().sqrt()
-    }
-
-    #[inline]
-    pub fn square_norm(&self) -> T {
-        (self.i * self.i + self.j * self.j + self.k * self.k + self.r *self.r)
-    }
-
-    /// Returns a unit quaternion from this one.
-    #[inline]
-    pub fn normalize(&self) -> Self {
-        self.mul(T::one() / self.norm())
-    }
-
-    #[inline]
-    pub fn is_normalized(&self) -> bool {
-        // TODO: we might need to relax the threshold here, because of floating point imprecision.
-        self.square_norm().approx_eq(&T::one())
-    }
-
-    /// Spherical linear interpolation between this rotation and another rotation.
-    ///
-    /// `t` is expected to be between zero and one.
-    pub fn slerp(&self, other: &Self, t: T) -> Self {
-        debug_assert!(self.is_normalized());
-        debug_assert!(other.is_normalized());
-
-        let r1 = *self;
-        let mut r2 = *other;
-
-        let mut dot = r1.i * r2.i + r1.j * r2.j + r1.k * r2.k + r1.r * r2.r;
-
-        let one = T::one();
-
-        if dot.approx_eq(&T::one()) {
-            // If the inputs are too close, linearly interpolate to avoid precision issues.
-            return r1.lerp(&r2, t);
-        }
-
-        // If the dot product is negative, the quaternions
-        // have opposite handed-ness and slerp won't take
-        // the shorter path. Fix by reversing one quaternion.
-        if dot < T::zero() {
-            r2 = r2.mul(-T::one());
-            dot = -dot;
-        }
-
-        // For robustness, stay within the domain of acos.
-        dot = Float::min(dot, one);
-
-        // Angle between r1 and the result.
-        let theta = Float::acos(dot) * t;
-
-        // r1 and r3 form an orthonormal basis.
-        let r3 = r2.sub(r1.mul(dot)).normalize();
-        let (sin, cos) = Float::sin_cos(theta);
-        r1.mul(cos).add(r3.mul(sin))
-    }
-
-    /// Basic Linear interpolation between this rotation and another rotation.
-    ///
-    /// `t` is expected to be between zero and one.
-    #[inline]
-    pub fn lerp(&self, other: &Self, t: T) -> Self {
-        let one_t = T::one() - t;
-        return self.mul(one_t).add(other.mul(t)).normalize();
-    }
-
-    /// Returns the given 3d point transformed by this rotation.
-    ///
-    /// The input point must be use the unit Src, and the returned point has the unit Dst.
-    pub fn rotate_point3d(&self, point: &TypedPoint3D<T, Src>) -> TypedPoint3D<T, Dst> {
-        debug_assert!(self.is_normalized());
-
-        let two = T::one() + T::one();
-        let cross = self.vector_part().cross(point.to_vector().to_untyped()) * two;
-
-        point3(
-            point.x + self.r * cross.x + self.j * cross.z - self.k * cross.y,
-            point.y + self.r * cross.y + self.k * cross.x - self.i * cross.z,
-            point.z + self.r * cross.z + self.i * cross.y - self.j * cross.x,
-        )
-    }
-
-    /// Returns the given 2d point transformed by this rotation then projected on the xy plane.
-    ///
-    /// The input point must be use the unit Src, and the returned point has the unit Dst.
-    #[inline]
-    pub fn rotate_point2d(&self, point: &TypedPoint2D<T, Src>) -> TypedPoint2D<T, Dst> {
-        self.rotate_point3d(&point.to_3d()).xy()
-    }
-
-    /// Returns the given 3d vector transformed by this rotation then projected on the xy plane.
-    ///
-    /// The input vector must be use the unit Src, and the returned point has the unit Dst.
-    #[inline]
-    pub fn rotate_vector3d(&self, vector: &TypedVector3D<T, Src>) -> TypedVector3D<T, Dst> {
-        self.rotate_point3d(&vector.to_point()).to_vector()
-    }
-
-    /// Returns the given 2d vector transformed by this rotation then projected on the xy plane.
-    ///
-    /// The input vector must be use the unit Src, and the returned point has the unit Dst.
-    #[inline]
-    pub fn rotate_vector2d(&self, vector: &TypedVector2D<T, Src>) -> TypedVector2D<T, Dst> {
-        self.rotate_vector3d(&vector.to_3d()).xy()
-    }
-
-    /// Returns the matrix representation of this rotation.
-    #[inline]
-    pub fn to_transform(&self) -> TypedTransform3D<T, Src, Dst> {
-        debug_assert!(self.is_normalized());
-
-        let i2 = self.i + self.i;
-        let j2 = self.j + self.j;
-        let k2 = self.k + self.k;
-        let ii = self.i * i2;
-        let ij = self.i * j2;
-        let ik = self.i * k2;
-        let jj = self.j * j2;
-        let jk = self.j * k2;
-        let kk = self.k * k2;
-        let ri = self.r * i2;
-        let rj = self.r * j2;
-        let rk = self.r * k2;
-
-        let one = T::one();
-        let zero = T::zero();
-
-        let m11 = one - (jj + kk);
-        let m12 = ij + rk;
-        let m13 = ik - rj;
-
-        let m21 = ij - rk;
-        let m22 = one - (ii + kk);
-        let m23 = jk + ri;
-
-        let m31 = ik + rj;
-        let m32 = jk - ri;
-        let m33 = one - (ii + jj);
-
-        TypedTransform3D::row_major(
-            m11,  m12,  m13, zero,
-            m21,  m22,  m23, zero,
-            m31,  m32,  m33, zero,
-            zero, zero, zero, one,
-        )
-    }
-
-    /// Returns a rotation representing the other rotation followed by this rotation.
-    pub fn pre_rotate<NewSrc>(&self, other: &TypedRotation3D<T, NewSrc, Src>) -> TypedRotation3D<T, NewSrc, Dst> {
-        debug_assert!(self.is_normalized());
-        TypedRotation3D::quaternion(
-            self.i * other.r + self.r * other.i + self.j * other.k - self.k * other.j,
-            self.j * other.r + self.r * other.j + self.k * other.i - self.i * other.k,
-            self.k * other.r + self.r * other.k + self.i * other.j - self.j * other.i,
-            self.r * other.r - self.i * other.i - self.j * other.j - self.k * other.k,
-        )
-    }
-
-    /// Returns a rotation representing this rotation followed by the other rotation.
-    #[inline]
-    pub fn post_rotate<NewDst>(&self, other: &TypedRotation3D<T, Dst, NewDst>) -> TypedRotation3D<T, Src, NewDst> {
-        other.pre_rotate(self)
-    }
-
-    // add, sub and mul are used internally for intermediate computation but aren't public
-    // because they don't carry real semantic meanings (I think?).
-
-    #[inline]
-    fn add(&self, other: Self) -> Self {
-        Self::quaternion(
-            self.i + other.i,
-            self.j + other.j,
-            self.k + other.k,
-            self.r + other.r,
-        )
-    }
-
-    #[inline]
-    fn sub(&self, other: Self) -> Self {
-        Self::quaternion(
-            self.i - other.i,
-            self.j - other.j,
-            self.k - other.k,
-            self.r - other.r,
-        )
-    }
-
-    #[inline]
-    fn mul(&self, factor: T) -> Self {
-        Self::quaternion(
-            self.i * factor,
-            self.j * factor,
-            self.k * factor,
-            self.r * factor,
-        )
-    }
-}
-
-impl<T: fmt::Debug, Src, Dst> fmt::Debug for TypedRotation3D<T, Src, Dst> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "Quat({:?}*i + {:?}*j + {:?}*k + {:?})", self.i, self.j, self.k, self.r)
-    }
-}
-
-impl<T: fmt::Display, Src, Dst> fmt::Display for TypedRotation3D<T, Src, Dst> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "Quat({}*i + {}*j + {}*k + {})", self.i, self.j, self.k, self.r)
-    }
-}
-
-impl<T, Src, Dst> ApproxEq<T> for TypedRotation3D<T, Src, Dst>
-where
-    T: Copy + Neg<Output=T> + ApproxEq<T>
-{
-    fn approx_epsilon() -> T {
-        T::approx_epsilon()
-    }
-
-    fn approx_eq(&self, other: &Self) -> bool {
-        self.approx_eq_eps(other, &Self::approx_epsilon())
-    }
-
-    fn approx_eq_eps(&self, other: &Self, eps: &T) -> bool {
-        (
-            self.i.approx_eq_eps(&other.i, eps)
-            && self.j.approx_eq_eps(&other.j, eps)
-            && self.k.approx_eq_eps(&other.k, eps)
-            && self.r.approx_eq_eps(&other.r, eps)
-        ) || (
-            self.i.approx_eq_eps(&-other.i, eps)
-            && self.j.approx_eq_eps(&-other.j, eps)
-            && self.k.approx_eq_eps(&-other.k, eps)
-            && self.r.approx_eq_eps(&-other.r, eps)
-        )
-    }
-}
-
-#[test]
-fn simple_rotation_2d() {
-    use std::f32::consts::{PI, FRAC_PI_2};
-    let ri = Rotation2D::identity();
-    let r90 = Rotation2D::radians(FRAC_PI_2);
-    let rm90 = Rotation2D::radians(-FRAC_PI_2);
-    let r180 = Rotation2D::radians(PI);
-
-    assert!(ri.transform_point(&point2(1.0, 2.0)).approx_eq(&point2(1.0, 2.0)));
-    assert!(r90.transform_point(&point2(1.0, 2.0)).approx_eq(&point2(-2.0, 1.0)));
-    assert!(rm90.transform_point(&point2(1.0, 2.0)).approx_eq(&point2(2.0, -1.0)));
-    assert!(r180.transform_point(&point2(1.0, 2.0)).approx_eq(&point2(-1.0, -2.0)));
-
-    assert!(
-        r90.inverse().inverse().transform_point(&point2(1.0, 2.0)).approx_eq(
-            &r90.transform_point(&point2(1.0, 2.0))
-        )
-    );
-}
-
-#[test]
-fn simple_rotation_3d_in_2d() {
-    use std::f32::consts::{PI, FRAC_PI_2};
-    let ri = Rotation3D::identity();
-    let r90 = Rotation3D::around_z(Radians::new(FRAC_PI_2));
-    let rm90 = Rotation3D::around_z(Radians::new(-FRAC_PI_2));
-    let r180 = Rotation3D::around_z(Radians::new(PI));
-
-    assert!(ri.rotate_point2d(&point2(1.0, 2.0)).approx_eq(&point2(1.0, 2.0)));
-    assert!(r90.rotate_point2d(&point2(1.0, 2.0)).approx_eq(&point2(-2.0, 1.0)));
-    assert!(rm90.rotate_point2d(&point2(1.0, 2.0)).approx_eq(&point2(2.0, -1.0)));
-    assert!(r180.rotate_point2d(&point2(1.0, 2.0)).approx_eq(&point2(-1.0, -2.0)));
-
-    assert!(
-        r90.inverse().inverse().rotate_point2d(&point2(1.0, 2.0)).approx_eq(
-            &r90.rotate_point2d(&point2(1.0, 2.0))
-        )
-    );
-}
-
-#[test]
-fn pre_post() {
-    use std::f32::consts::{FRAC_PI_2};
-    let r1 = Rotation3D::around_x(Radians::new(FRAC_PI_2));
-    let r2 = Rotation3D::around_y(Radians::new(FRAC_PI_2));
-    let r3 = Rotation3D::around_z(Radians::new(FRAC_PI_2));
-
-    let t1 = r1.to_transform();
-    let t2 = r2.to_transform();
-    let t3 = r3.to_transform();
-
-    let p = point3(1.0, 2.0, 3.0);
-
-    // Check that the order of transformations is correct (corresponds to what
-    // we do in Transfor3D).
-    let p1 = r1.post_rotate(&r2).post_rotate(&r3).rotate_point3d(&p);
-    let p2 = t1.post_mul(&t2).post_mul(&t3).transform_point3d(&p);
-
-    assert!(p1.approx_eq(&p2));
-
-    // Check that changing the order indeed matters.
-    let p3 = t3.post_mul(&t1).post_mul(&t2).transform_point3d(&p);
-    assert!(!p1.approx_eq(&p3));
-}
-
-#[test]
-fn to_transform3d() {
-    use std::f32::consts::{PI, FRAC_PI_2};
-    let rotations = [
-        Rotation3D::identity(),
-        Rotation3D::around_x(Radians::new(FRAC_PI_2)),
-        Rotation3D::around_x(Radians::new(-FRAC_PI_2)),
-        Rotation3D::around_x(Radians::new(PI)),
-        Rotation3D::around_y(Radians::new(FRAC_PI_2)),
-        Rotation3D::around_y(Radians::new(-FRAC_PI_2)),
-        Rotation3D::around_y(Radians::new(PI)),
-        Rotation3D::around_z(Radians::new(FRAC_PI_2)),
-        Rotation3D::around_z(Radians::new(-FRAC_PI_2)),
-        Rotation3D::around_z(Radians::new(PI)),
-    ];
-
-    let points = [
-        point3(0.0, 0.0, 0.0),
-        point3(1.0, 2.0, 3.0),
-        point3(-5.0, 3.0, -1.0),
-        point3(-0.5, -1.0, 1.5),
-    ];
-
-    for rotation in &rotations {
-        for point in &points {
-            let p1 = rotation.rotate_point3d(point);
-            let p2 = rotation.to_transform().transform_point3d(point);
-            assert!(p1.approx_eq(&p2));
-        }
-    }
-}
-
-#[test]
-fn slerp() {
-    let q1 = Rotation3D::quaternion(1.0, 0.0, 0.0, 0.0);
-    let q2 = Rotation3D::quaternion(0.0, 1.0, 0.0, 0.0);
-    let q3 = Rotation3D::quaternion(0.0, 0.0, -1.0, 0.0);
-
-    // The values below can be obtained with a python program:
-    // import numpy
-    // import quaternion
-    // q1 = numpy.quaternion(1, 0, 0, 0)
-    // q2 = numpy.quaternion(0, 1, 0, 0)
-    // quaternion.slerp_evaluate(q1, q2, 0.2)
-
-    assert!(q1.slerp(&q2, 0.0).approx_eq(&q1));
-    assert!(q1.slerp(&q2, 0.2).approx_eq(&Rotation3D::quaternion(0.951056516295154, 0.309016994374947, 0.0, 0.0)));
-    assert!(q1.slerp(&q2, 0.4).approx_eq(&Rotation3D::quaternion(0.809016994374947, 0.587785252292473, 0.0, 0.0)));
-    assert!(q1.slerp(&q2, 0.6).approx_eq(&Rotation3D::quaternion(0.587785252292473, 0.809016994374947, 0.0, 0.0)));
-    assert!(q1.slerp(&q2, 0.8).approx_eq(&Rotation3D::quaternion(0.309016994374947, 0.951056516295154, 0.0, 0.0)));
-    assert!(q1.slerp(&q2, 1.0).approx_eq(&q2));
-
-    assert!(q1.slerp(&q3, 0.0).approx_eq(&q1));
-    assert!(q1.slerp(&q3, 0.2).approx_eq(&Rotation3D::quaternion(0.951056516295154, 0.0, -0.309016994374947, 0.0)));
-    assert!(q1.slerp(&q3, 0.4).approx_eq(&Rotation3D::quaternion(0.809016994374947, 0.0, -0.587785252292473, 0.0)));
-    assert!(q1.slerp(&q3, 0.6).approx_eq(&Rotation3D::quaternion(0.587785252292473, 0.0, -0.809016994374947, 0.0)));
-    assert!(q1.slerp(&q3, 0.8).approx_eq(&Rotation3D::quaternion(0.309016994374947, 0.0, -0.951056516295154, 0.0)));
-    assert!(q1.slerp(&q3, 1.0).approx_eq(&q3));
-}
-
-#[test]
-fn around_axis() {
-    use std::f32::consts::{PI, FRAC_PI_2};
-
-    // Two sort of trivial cases:
-    let r1 = Rotation3D::around_axis(vec3(1.0, 1.0, 0.0), Radians::new(PI));
-    let r2 = Rotation3D::around_axis(vec3(1.0, 1.0, 0.0), Radians::new(FRAC_PI_2));
-    assert!(r1.rotate_point3d(&point3(1.0, 2.0, 0.0)).approx_eq(&point3(2.0, 1.0, 0.0)));
-    assert!(r2.rotate_point3d(&point3(1.0, 0.0, 0.0)).approx_eq(&point3(0.5, 0.5, -0.5.sqrt())));
-
-    // A more arbitray test (made up with numpy):
-    let r3 = Rotation3D::around_axis(vec3(0.5, 1.0, 2.0), Radians::new(2.291288));
-    assert!(r3.rotate_point3d(&point3(1.0, 0.0, 0.0)).approx_eq(&point3(-0.58071821,  0.81401868, -0.01182979)));
-}
-
-#[test]
-fn from_euler() {
-    use std::f32::consts::FRAC_PI_2;
-
-    // First test simple separate yaw pitch and roll rotations, because it is easy to come
-    // up with the corresponding quaternion.
-    // Since several quaternions can represent the same transformation we compare the result
-    // of transforming a point rather than the values of each qauetrnions.
-    let p = point3(1.0, 2.0, 3.0);
-
-    let angle = Radians::new(FRAC_PI_2);
-    let zero = Radians::new(0.0);
-
-    // roll
-    let roll_re = Rotation3D::euler(angle, zero, zero);
-    let roll_rq = Rotation3D::around_x(angle);
-    let roll_pe = roll_re.rotate_point3d(&p);
-    let roll_pq = roll_rq.rotate_point3d(&p);
-
-    // pitch
-    let pitch_re = Rotation3D::euler(zero, angle, zero);
-    let pitch_rq = Rotation3D::around_y(angle);
-    let pitch_pe = pitch_re.rotate_point3d(&p);
-    let pitch_pq = pitch_rq.rotate_point3d(&p);
-
-    // yaw
-    let yaw_re = Rotation3D::euler(zero, zero, angle);
-    let yaw_rq = Rotation3D::around_z(angle);
-    let yaw_pe = yaw_re.rotate_point3d(&p);
-    let yaw_pq = yaw_rq.rotate_point3d(&p);
-
-    assert!(roll_pe.approx_eq(&roll_pq));
-    assert!(pitch_pe.approx_eq(&pitch_pq));
-    assert!(yaw_pe.approx_eq(&yaw_pq));
-
-    // Now check that the yaw pitch and roll transformations when compined are applied in
-    // the proper order: roll -> pitch -> yaw.
-    let ypr_e = Rotation3D::euler(angle, angle, angle);
-    let ypr_q = roll_rq.post_rotate(&pitch_rq).post_rotate(&yaw_rq);
-    let ypr_pe = ypr_e.rotate_point3d(&p);
-    let ypr_pq = ypr_q.rotate_point3d(&p);
-
-    assert!(ypr_pe.approx_eq(&ypr_pq));
-}
-
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/scale_factor.rs
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright 2014 The Servo Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution.
-//
-// 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.
-//! A type-checked scaling factor between units.
-
-use num::One;
-
-use heapsize::HeapSizeOf;
-use num_traits::NumCast;
-use serde::{Deserialize, Deserializer, Serialize, Serializer};
-use std::fmt;
-use std::ops::{Add, Mul, Sub, Div};
-use std::marker::PhantomData;
-
-/// A scaling factor between two different units of measurement.
-///
-/// This is effectively a type-safe float, intended to be used in combination with other types like
-/// `length::Length` to enforce conversion between systems of measurement at compile time.
-///
-/// `Src` and `Dst` represent the units before and after multiplying a value by a `ScaleFactor`. They
-/// may be types without values, such as empty enums.  For example:
-///
-/// ```rust
-/// use euclid::ScaleFactor;
-/// use euclid::Length;
-/// enum Mm {};
-/// enum Inch {};
-///
-/// let mm_per_inch: ScaleFactor<f32, Inch, Mm> = ScaleFactor::new(25.4);
-///
-/// let one_foot: Length<f32, Inch> = Length::new(12.0);
-/// let one_foot_in_mm: Length<f32, Mm> = one_foot * mm_per_inch;
-/// ```
-#[repr(C)]
-pub struct ScaleFactor<T, Src, Dst>(pub T, PhantomData<(Src, Dst)>);
-
-impl<T: HeapSizeOf, Src, Dst> HeapSizeOf for ScaleFactor<T, Src, Dst> {
-    fn heap_size_of_children(&self) -> usize {
-        self.0.heap_size_of_children()
-    }
-}
-
-impl<'de, T, Src, Dst> Deserialize<'de> for ScaleFactor<T, Src, Dst> where T: Deserialize<'de> {
-    fn deserialize<D>(deserializer: D) -> Result<ScaleFactor<T, Src, Dst>, D::Error>
-                      where D: Deserializer<'de> {
-        Ok(ScaleFactor(try!(Deserialize::deserialize(deserializer)), PhantomData))
-    }
-}
-
-impl<T, Src, Dst> Serialize for ScaleFactor<T, Src, Dst> where T: Serialize {
-    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
-        self.0.serialize(serializer)
-    }
-}
-
-impl<T, Src, Dst> ScaleFactor<T, Src, Dst> {
-    pub fn new(x: T) -> ScaleFactor<T, Src, Dst> {
-        ScaleFactor(x, PhantomData)
-    }
-}
-
-impl<T: Clone, Src, Dst> ScaleFactor<T, Src, Dst> {
-    pub fn get(&self) -> T {
-        self.0.clone()
-    }
-}
-
-impl<T: Clone + One + Div<T, Output=T>, Src, Dst> ScaleFactor<T, Src, Dst> {
-    /// The inverse ScaleFactor (1.0 / self).
-    pub fn inv(&self) -> ScaleFactor<T, Dst, Src> {
-        let one: T = One::one();
-        ScaleFactor::new(one / self.get())
-    }
-}
-
-// scale0 * scale1
-impl<T: Clone + Mul<T, Output=T>, A, B, C>
-Mul<ScaleFactor<T, B, C>> for ScaleFactor<T, A, B> {
-    type Output = ScaleFactor<T, A, C>;
-    #[inline]
-    fn mul(self, other: ScaleFactor<T, B, C>) -> ScaleFactor<T, A, C> {
-        ScaleFactor::new(self.get() * other.get())
-    }
-}
-
-// scale0 + scale1
-impl<T: Clone + Add<T, Output=T>, Src, Dst> Add for ScaleFactor<T, Src, Dst> {
-    type Output = ScaleFactor<T, Src, Dst>;
-    #[inline]
-    fn add(self, other: ScaleFactor<T, Src, Dst>) -> ScaleFactor<T, Src, Dst> {
-        ScaleFactor::new(self.get() + other.get())
-    }
-}
-
-// scale0 - scale1
-impl<T: Clone + Sub<T, Output=T>, Src, Dst> Sub for ScaleFactor<T, Src, Dst> {
-    type Output = ScaleFactor<T, Src, Dst>;
-    #[inline]
-    fn sub(self, other: ScaleFactor<T, Src, Dst>) -> ScaleFactor<T, Src, Dst> {
-        ScaleFactor::new(self.get() - other.get())
-    }
-}
-
-impl<T: NumCast + Clone, Src, Dst0> ScaleFactor<T, Src, Dst0> {
-    /// Cast from one numeric representation to another, preserving the units.
-    pub fn cast<T1: NumCast + Clone>(&self) -> Option<ScaleFactor<T1, Src, Dst0>> {
-        NumCast::from(self.get()).map(ScaleFactor::new)
-    }
-}
-
-// FIXME: Switch to `derive(PartialEq, Clone)` after this Rust issue is fixed:
-// https://github.com/mozilla/rust/issues/7671
-
-impl<T: PartialEq, Src, Dst> PartialEq for ScaleFactor<T, Src, Dst> {
-    fn eq(&self, other: &ScaleFactor<T, Src, Dst>) -> bool {
-        self.0 == other.0
-    }
-}
-
-impl<T: Clone, Src, Dst> Clone for ScaleFactor<T, Src, Dst> {
-    fn clone(&self) -> ScaleFactor<T, Src, Dst> {
-        ScaleFactor::new(self.get())
-    }
-}
-
-impl<T: Copy, Src, Dst> Copy for ScaleFactor<T, Src, Dst> {}
-
-impl<T: fmt::Debug, Src, Dst> fmt::Debug for ScaleFactor<T, Src, Dst> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.0.fmt(f)
-    }
-}
-
-impl<T: fmt::Display, Src, Dst> fmt::Display for ScaleFactor<T, Src, Dst> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.0.fmt(f)
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::ScaleFactor;
-
-    enum Inch {}
-    enum Cm {}
-    enum Mm {}
-
-    #[test]
-    fn test_scale_factor() {
-        let mm_per_inch: ScaleFactor<f32, Inch, Mm> = ScaleFactor::new(25.4);
-        let cm_per_mm: ScaleFactor<f32, Mm, Cm> = ScaleFactor::new(0.1);
-
-        let mm_per_cm: ScaleFactor<f32, Cm, Mm> = cm_per_mm.inv();
-        assert_eq!(mm_per_cm.get(), 10.0);
-
-        let cm_per_inch: ScaleFactor<f32, Inch, Cm> = mm_per_inch * cm_per_mm;
-        assert_eq!(cm_per_inch, ScaleFactor::new(2.54));
-
-        let a: ScaleFactor<isize, Inch, Inch> = ScaleFactor::new(2);
-        let b: ScaleFactor<isize, Inch, Inch> = ScaleFactor::new(3);
-        assert!(a != b);
-        assert_eq!(a, a.clone());
-        assert_eq!(a.clone() + b.clone(), ScaleFactor::new(5));
-        assert_eq!(a - b, ScaleFactor::new(-1));
-    }
-}
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/side_offsets.rs
+++ /dev/null
@@ -1,283 +0,0 @@
-// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution.
-//
-// 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.
-
-//! A group of side offsets, which correspond to top/left/bottom/right for borders, padding,
-//! and margins in CSS.
-
-use super::UnknownUnit;
-use length::Length;
-use num::Zero;
-use std::fmt;
-use std::ops::Add;
-use std::marker::PhantomData;
-
-#[cfg(feature = "unstable")]
-use heapsize::HeapSizeOf;
-
-/// A group of side offsets, which correspond to top/left/bottom/right for borders, padding,
-/// and margins in CSS, optionally tagged with a unit.
-define_matrix! {
-    pub struct TypedSideOffsets2D<T, U> {
-        pub top: T,
-        pub right: T,
-        pub bottom: T,
-        pub left: T,
-    }
-}
-
-impl<T: fmt::Debug, U> fmt::Debug for TypedSideOffsets2D<T, U> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "({:?},{:?},{:?},{:?})",
-               self.top, self.right, self.bottom, self.left)
-    }
-}
-
-/// The default side offset type with no unit.
-pub type SideOffsets2D<T> = TypedSideOffsets2D<T, UnknownUnit>;
-
-impl<T: Copy, U> TypedSideOffsets2D<T, U> {
-    /// Constructor taking a scalar for each side.
-    pub fn new(top: T, right: T, bottom: T, left: T) -> Self {
-        TypedSideOffsets2D {
-            top: top,
-            right: right,
-            bottom: bottom,
-            left: left,
-            _unit: PhantomData,
-        }
-    }
-
-    /// Constructor taking a typed Length for each side.
-    pub fn from_lengths(top: Length<T, U>,
-                        right: Length<T, U>,
-                        bottom: Length<T, U>,
-                        left: Length<T, U>) -> Self {
-        TypedSideOffsets2D::new(top.0, right.0, bottom.0, left.0)
-    }
-
-    /// Access self.top as a typed Length instead of a scalar value.
-    pub fn top_typed(&self) -> Length<T, U> { Length::new(self.top) }
-
-    /// Access self.right as a typed Length instead of a scalar value.
-    pub fn right_typed(&self) -> Length<T, U> { Length::new(self.right) }
-
-    /// Access self.bottom as a typed Length instead of a scalar value.
-    pub fn bottom_typed(&self) -> Length<T, U> { Length::new(self.bottom) }
-
-    /// Access self.left as a typed Length instead of a scalar value.
-    pub fn left_typed(&self) -> Length<T, U> { Length::new(self.left) }
-
-    /// Constructor setting the same value to all sides, taking a scalar value directly.
-    pub fn new_all_same(all: T) -> Self {
-        TypedSideOffsets2D::new(all, all, all, all)
-    }
-
-    /// Constructor setting the same value to all sides, taking a typed Length.
-    pub fn from_length_all_same(all: Length<T, U>) -> Self {
-        TypedSideOffsets2D::new_all_same(all.0)
-    }
-}
-
-impl<T, U> TypedSideOffsets2D<T, U> where T: Add<T, Output=T> + Copy {
-    pub fn horizontal(&self) -> T {
-        self.left + self.right
-    }
-
-    pub fn vertical(&self) -> T {
-        self.top + self.bottom
-    }
-
-    pub fn horizontal_typed(&self) -> Length<T, U> {
-        Length::new(self.horizontal())
-    }
-
-    pub fn vertical_typed(&self) -> Length<T, U> {
-        Length::new(self.vertical())
-    }
-}
-
-impl<T, U> Add for TypedSideOffsets2D<T, U> where T : Copy + Add<T, Output=T> {
-    type Output = Self;
-    fn add(self, other: Self) -> Self {
-        TypedSideOffsets2D::new(
-            self.top + other.top,
-            self.right + other.right,
-            self.bottom + other.bottom,
-            self.left + other.left,
-        )
-    }
-}
-
-impl<T: Copy + Zero, U> TypedSideOffsets2D<T, U> {
-    /// Constructor, setting all sides to zero.
-    pub fn zero() -> Self {
-        TypedSideOffsets2D::new(
-            Zero::zero(),
-            Zero::zero(),
-            Zero::zero(),
-            Zero::zero(),
-        )
-    }
-}
-
-/// A SIMD enabled version of TypedSideOffsets2D specialized for i32.
-#[cfg(feature = "unstable")]
-#[derive(Clone, Copy, PartialEq)]
-#[repr(simd)]
-pub struct SideOffsets2DSimdI32 {
-    pub top: i32,
-    pub bottom: i32,
-    pub right: i32,
-    pub left: i32,
-}
-
-#[cfg(feature = "unstable")]
-impl HeapSizeOf for SideOffsets2DSimdI32 {
-    fn heap_size_of_children(&self) -> usize { 0 }
-}
-
-#[cfg(feature = "unstable")]
-impl SideOffsets2DSimdI32 {
-    #[inline]
-    pub fn new(top: i32, right: i32, bottom: i32, left: i32) -> SideOffsets2DSimdI32 {
-        SideOffsets2DSimdI32 {
-            top: top,
-            bottom: bottom,
-            right: right,
-            left: left,
-        }
-    }
-}
-
-#[cfg(feature = "unstable")]
-impl SideOffsets2DSimdI32 {
-    #[inline]
-    pub fn new_all_same(all: i32) -> SideOffsets2DSimdI32 {
-        SideOffsets2DSimdI32::new(all.clone(), all.clone(), all.clone(), all.clone())
-    }
-}
-
-#[cfg(feature = "unstable")]
-impl SideOffsets2DSimdI32 {
-    #[inline]
-    pub fn horizontal(&self) -> i32 {
-        self.left + self.right
-    }
-
-    #[inline]
-    pub fn vertical(&self) -> i32 {
-        self.top + self.bottom
-    }
-}
-
-/*impl Add for SideOffsets2DSimdI32 {
-    type Output = SideOffsets2DSimdI32;
-    #[inline]
-    fn add(self, other: SideOffsets2DSimdI32) -> SideOffsets2DSimdI32 {
-        self + other // Use SIMD addition
-    }
-}*/
-
-#[cfg(feature = "unstable")]
-impl SideOffsets2DSimdI32 {
-    #[inline]
-    pub fn zero() -> SideOffsets2DSimdI32 {
-        SideOffsets2DSimdI32 {
-            top: 0,
-            bottom: 0,
-            right: 0,
-            left: 0,
-        }
-    }
-
-    #[cfg(not(target_arch = "x86_64"))]
-    #[inline]
-    pub fn is_zero(&self) -> bool {
-        self.top == 0 && self.right == 0 && self.bottom == 0 && self.left == 0
-    }
-
-    #[cfg(target_arch = "x86_64")]
-    #[inline]
-    pub fn is_zero(&self) -> bool {
-        let is_zero: bool;
-        unsafe {
-            asm! {
-                "ptest $1, $1
-                 setz $0"
-                : "=r"(is_zero)
-                : "x"(*self)
-                :
-                : "intel"
-            };
-        }
-        is_zero
-    }
-}
-
-#[cfg(feature = "unstable")]
-#[cfg(test)]
-mod tests {
-    use super::SideOffsets2DSimdI32;
-
-    #[test]
-    fn test_is_zero() {
-        assert!(SideOffsets2DSimdI32::new_all_same(0).is_zero());
-        assert!(!SideOffsets2DSimdI32::new_all_same(1).is_zero());
-        assert!(!SideOffsets2DSimdI32::new(1, 0, 0, 0).is_zero());
-        assert!(!SideOffsets2DSimdI32::new(0, 1, 0, 0).is_zero());
-        assert!(!SideOffsets2DSimdI32::new(0, 0, 1, 0).is_zero());
-        assert!(!SideOffsets2DSimdI32::new(0, 0, 0, 1).is_zero());
-    }
-}
-
-#[cfg(feature = "unstable")]
-#[cfg(bench)]
-mod bench {
-    use test::BenchHarness;
-    use std::num::Zero;
-    use rand::{XorShiftRng, Rng};
-    use super::SideOffsets2DSimdI32;
-
-    #[cfg(target_arch = "x86")]
-    #[cfg(target_arch = "x86_64")]
-    #[bench]
-    fn bench_naive_is_zero(bh: &mut BenchHarness) {
-        fn is_zero(x: &SideOffsets2DSimdI32) -> bool {
-            x.top.is_zero() && x.right.is_zero() && x.bottom.is_zero() && x.left.is_zero()
-        }
-        let mut rng = XorShiftRng::new().unwrap();
-        bh.iter(|| is_zero(&rng.gen::<SideOffsets2DSimdI32>()))
-    }
-
-    #[bench]
-    fn bench_is_zero(bh: &mut BenchHarness) {
-        let mut rng = XorShiftRng::new().unwrap();
-        bh.iter(|| rng.gen::<SideOffsets2DSimdI32>().is_zero())
-    }
-
-    #[bench]
-    fn bench_naive_add(bh: &mut BenchHarness) {
-        fn add(x: &SideOffsets2DSimdI32, y: &SideOffsets2DSimdI32) -> SideOffsets2DSimdI32 {
-            SideOffsets2DSimdI32 {
-                top: x.top + y.top,
-                right: x.right + y.right,
-                bottom: x.bottom + y.bottom,
-                left: x.left + y.left,
-            }
-        }
-        let mut rng = XorShiftRng::new().unwrap();
-        bh.iter(|| add(&rng.gen::<SideOffsets2DSimdI32>(), &rng.gen::<SideOffsets2DSimdI32>()))
-    }
-
-    #[bench]
-    fn bench_add(bh: &mut BenchHarness) {
-        let mut rng = XorShiftRng::new().unwrap();
-        bh.iter(|| rng.gen::<SideOffsets2DSimdI32>() + rng.gen::<SideOffsets2DSimdI32>())
-    }
-}
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/size.rs
+++ /dev/null
@@ -1,311 +0,0 @@
-// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use super::UnknownUnit;
-use length::Length;
-use scale_factor::ScaleFactor;
-use vector::{TypedVector2D, vec2};
-use num::*;
-
-use num_traits::{NumCast, Signed};
-use std::fmt;
-use std::ops::{Add, Div, Mul, Sub};
-use std::marker::PhantomData;
-
-/// A 2d size tagged with a unit.
-define_matrix! {
-    pub struct TypedSize2D<T, U> {
-        pub width: T,
-        pub height: T,
-    }
-}
-
-/// Default 2d size type with no unit.
-///
-/// `Size2D` provides the same methods as `TypedSize2D`.
-pub type Size2D<T> = TypedSize2D<T, UnknownUnit>;
-
-impl<T: fmt::Debug, U> fmt::Debug for TypedSize2D<T, U> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{:?}×{:?}", self.width, self.height)
-    }
-}
-
-impl<T: fmt::Display, U> fmt::Display for TypedSize2D<T, U> {
-    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
-        write!(formatter, "({}x{})", self.width, self.height)
-    }
-}
-
-impl<T, U> TypedSize2D<T, U> {
-    /// Constructor taking scalar values.
-    pub fn new(width: T, height: T) -> Self {
-        TypedSize2D {
-            width: width,
-            height: height,
-            _unit: PhantomData,
-        }
-    }
-}
-
-impl<T: Clone, U> TypedSize2D<T, U> {
-    /// Constructor taking scalar strongly typed lengths.
-    pub fn from_lengths(width: Length<T, U>, height: Length<T, U>) -> Self {
-        TypedSize2D::new(width.get(), height.get())
-    }
-}
-
-impl<T: Round, U> TypedSize2D<T, U> {
-    /// Rounds each component to the nearest integer value.
-    ///
-    /// This behavior is preserved for negative values (unlike the basic cast).
-    pub fn round(&self) -> Self {
-        TypedSize2D::new(self.width.round(), self.height.round())
-    }
-}
-
-impl<T: Ceil, U> TypedSize2D<T, U> {
-    /// Rounds each component to the smallest integer equal or greater than the original value.
-    ///
-    /// This behavior is preserved for negative values (unlike the basic cast).
-    pub fn ceil(&self) -> Self {
-        TypedSize2D::new(self.width.ceil(), self.height.ceil())
-    }
-}
-
-impl<T: Floor, U> TypedSize2D<T, U> {
-    /// Rounds each component to the biggest integer equal or lower than the original value.
-    ///
-    /// This behavior is preserved for negative values (unlike the basic cast).
-    pub fn floor(&self) -> Self {
-        TypedSize2D::new(self.width.floor(), self.height.floor())
-    }
-}
-
-impl<T: Copy + Add<T, Output=T>, U> Add for TypedSize2D<T, U> {
-    type Output = Self;
-    fn add(self, other: Self) -> Self {
-        TypedSize2D::new(self.width + other.width, self.height + other.height)
-    }
-}
-
-impl<T: Copy + Sub<T, Output=T>, U> Sub for TypedSize2D<T, U> {
-    type Output = Self;
-    fn sub(self, other: Self) -> Self {
-        TypedSize2D::new(self.width - other.width, self.height - other.height)
-    }
-}
-
-impl<T: Copy + Clone + Mul<T>, U> TypedSize2D<T, U> {
-    pub fn area(&self) -> T::Output { self.width * self.height }
-}
-
-impl<T, U> TypedSize2D<T, U>
-where T: Copy + One + Add<Output=T> + Sub<Output=T> + Mul<Output=T> {
-    /// Linearly interpolate between this size and another size.
-    ///
-    /// `t` is expected to be between zero and one.
-    #[inline]
-    pub fn lerp(&self, other: Self, t: T) -> Self {
-        let one_t = T::one() - t;
-        size2(
-            one_t * self.width + t * other.width,
-            one_t * self.height + t * other.height,
-        )
-    }
-}
-
-impl<T: Zero, U> TypedSize2D<T, U> {
-    pub fn zero() -> Self {
-        TypedSize2D::new(
-            Zero::zero(),
-            Zero::zero(),
-        )
-    }
-}
-
-impl<T: Zero, U> Zero for TypedSize2D<T, U> {
-    fn zero() -> Self {
-        TypedSize2D::new(
-            Zero::zero(),
-            Zero::zero(),
-        )
-    }
-}
-
-impl<T: Copy + Mul<T, Output=T>, U> Mul<T> for TypedSize2D<T, U> {
-    type Output = Self;
-    #[inline]
-    fn mul(self, scale: T) -> Self {
-        TypedSize2D::new(self.width * scale, self.height * scale)
-    }
-}
-
-impl<T: Copy + Div<T, Output=T>, U> Div<T> for TypedSize2D<T, U> {
-    type Output = Self;
-    #[inline]
-    fn div(self, scale: T) -> Self {
-        TypedSize2D::new(self.width / scale, self.height / scale)
-    }
-}
-
-impl<T: Copy + Mul<T, Output=T>, U1, U2> Mul<ScaleFactor<T, U1, U2>> for TypedSize2D<T, U1> {
-    type Output = TypedSize2D<T, U2>;
-    #[inline]
-    fn mul(self, scale: ScaleFactor<T, U1, U2>) -> TypedSize2D<T, U2> {
-        TypedSize2D::new(self.width * scale.get(), self.height * scale.get())
-    }
-}
-
-impl<T: Copy + Div<T, Output=T>, U1, U2> Div<ScaleFactor<T, U1, U2>> for TypedSize2D<T, U2> {
-    type Output = TypedSize2D<T, U1>;
-    #[inline]
-    fn div(self, scale: ScaleFactor<T, U1, U2>) -> TypedSize2D<T, U1> {
-        TypedSize2D::new(self.width / scale.get(), self.height / scale.get())
-    }
-}
-
-impl<T: Copy, U> TypedSize2D<T, U> {
-    /// Returns self.width as a Length carrying the unit.
-    #[inline]
-    pub fn width_typed(&self) -> Length<T, U> { Length::new(self.width) }
-
-    /// Returns self.height as a Length carrying the unit.
-    #[inline]
-    pub fn height_typed(&self) -> Length<T, U> { Length::new(self.height) }
-
-    #[inline]
-    pub fn to_array(&self) -> [T; 2] { [self.width, self.height] }
-
-    #[inline]
-    pub fn to_vector(&self) -> TypedVector2D<T, U> { vec2(self.width, self.height) }
-
-    /// Drop the units, preserving only the numeric value.
-    pub fn to_untyped(&self) -> Size2D<T> {
-        TypedSize2D::new(self.width, self.height)
-    }
-
-    /// Tag a unitless value with units.
-    pub fn from_untyped(p: &Size2D<T>) -> Self {
-        TypedSize2D::new(p.width, p.height)
-    }
-}
-
-impl<T: NumCast + Copy, Unit> TypedSize2D<T, Unit> {
-    /// Cast from one numeric representation to another, preserving the units.
-    ///
-    /// When casting from floating point to integer coordinates, the decimals are truncated
-    /// as one would expect from a simple cast, but this behavior does not always make sense
-    /// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting.
-    pub fn cast<NewT: NumCast + Copy>(&self) -> Option<TypedSize2D<NewT, Unit>> {
-        match (NumCast::from(self.width), NumCast::from(self.height)) {
-            (Some(w), Some(h)) => Some(TypedSize2D::new(w, h)),
-            _ => None
-        }
-    }
-
-    // Convenience functions for common casts
-
-    /// Cast into an `f32` size.
-    pub fn to_f32(&self) -> TypedSize2D<f32, Unit> {
-        self.cast().unwrap()
-    }
-
-    /// Cast into an `uint` size, truncating decimals if any.
-    ///
-    /// When casting from floating point sizes, it is worth considering whether
-    /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
-    /// the desired conversion behavior.
-    pub fn to_usize(&self) -> TypedSize2D<usize, Unit> {
-        self.cast().unwrap()
-    }
-
-    /// Cast into an `i32` size, truncating decimals if any.
-    ///
-    /// When casting from floating point sizes, it is worth considering whether
-    /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
-    /// the desired conversion behavior.
-    pub fn to_i32(&self) -> TypedSize2D<i32, Unit> {
-        self.cast().unwrap()
-    }
-
-    /// Cast into an `i64` size, truncating decimals if any.
-    ///
-    /// When casting from floating point sizes, it is worth considering whether
-    /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
-    /// the desired conversion behavior.
-    pub fn to_i64(&self) -> TypedSize2D<i64, Unit> {
-        self.cast().unwrap()
-    }
-}
-
-impl<T, U> TypedSize2D<T, U>
-where T: Signed {
-    pub fn abs(&self) -> Self {
-        size2(self.width.abs(), self.height.abs())
-    }
-
-    pub fn is_positive(&self) -> bool {
-        self.width.is_positive() && self.height.is_positive()
-    }
-}
-
-/// Shorthand for `TypedSize2D::new(w, h)`.
-pub fn size2<T, U>(w: T, h: T) -> TypedSize2D<T, U> {
-    TypedSize2D::new(w, h)
-}
-
-#[cfg(test)]
-mod size2d {
-    use super::Size2D;
-
-    #[test]
-    pub fn test_add() {
-        let p1 = Size2D::new(1.0, 2.0);
-        let p2 = Size2D::new(3.0, 4.0);
-        assert_eq!(p1 + p2, Size2D::new(4.0, 6.0));
-
-        let p1 = Size2D::new(1.0, 2.0);
-        let p2 = Size2D::new(0.0, 0.0);
-        assert_eq!(p1 + p2, Size2D::new(1.0, 2.0));
-
-        let p1 = Size2D::new(1.0, 2.0);
-        let p2 = Size2D::new(-3.0, -4.0);
-        assert_eq!(p1 + p2, Size2D::new(-2.0, -2.0));
-
-        let p1 = Size2D::new(0.0, 0.0);
-        let p2 = Size2D::new(0.0, 0.0);
-        assert_eq!(p1 + p2, Size2D::new(0.0, 0.0));
-    }
-
-    #[test]
-    pub fn test_sub() {
-        let p1 = Size2D::new(1.0, 2.0);
-        let p2 = Size2D::new(3.0, 4.0);
-        assert_eq!(p1 - p2, Size2D::new(-2.0, -2.0));
-
-        let p1 = Size2D::new(1.0, 2.0);
-        let p2 = Size2D::new(0.0, 0.0);
-        assert_eq!(p1 - p2, Size2D::new(1.0, 2.0));
-
-        let p1 = Size2D::new(1.0, 2.0);
-        let p2 = Size2D::new(-3.0, -4.0);
-        assert_eq!(p1 - p2, Size2D::new(4.0, 6.0));
-
-        let p1 = Size2D::new(0.0, 0.0);
-        let p2 = Size2D::new(0.0, 0.0);
-        assert_eq!(p1 - p2, Size2D::new(0.0, 0.0));
-    }
-
-    #[test]
-    pub fn test_area() {
-        let p = Size2D::new(1.5, 2.0);
-        assert_eq!(p.area(), 3.0);
-    }
-}
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/transform2d.rs
+++ /dev/null
@@ -1,526 +0,0 @@
-// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use super::{UnknownUnit, Radians};
-use num::{One, Zero};
-use point::TypedPoint2D;
-use vector::{TypedVector2D, vec2};
-use rect::TypedRect;
-use transform3d::TypedTransform3D;
-use std::ops::{Add, Mul, Div, Sub, Neg};
-use std::marker::PhantomData;
-use approxeq::ApproxEq;
-use trig::Trig;
-use std::fmt;
-use num_traits::NumCast;
-
-define_matrix! {
-    /// A 2d transform stored as a 2 by 3 matrix in row-major order in memory.
-    ///
-    /// Transforms can be parametrized over the source and destination units, to describe a
-    /// transformation from a space to another.
-    /// For example, `TypedTransform2D<f32, WordSpace, ScreenSpace>::transform_point4d`
-    /// takes a `TypedPoint2D<f32, WordSpace>` and returns a `TypedPoint2D<f32, ScreenSpace>`.
-    ///
-    /// Transforms expose a set of convenience methods for pre- and post-transformations.
-    /// A pre-transformation corresponds to adding an operation that is applied before
-    /// the rest of the transformation, while a post-transformation adds an operation
-    /// that is applied after.
-    pub struct TypedTransform2D<T, Src, Dst> {
-        pub m11: T, pub m12: T,
-        pub m21: T, pub m22: T,
-        pub m31: T, pub m32: T,
-    }
-}
-
-/// The default 2d transform type with no units.
-pub type Transform2D<T> = TypedTransform2D<T, UnknownUnit, UnknownUnit>;
-
-impl<T: Copy, Src, Dst> TypedTransform2D<T, Src, Dst> {
-    /// Create a transform specifying its matrix elements in row-major order.
-    pub fn row_major(m11: T, m12: T, m21: T, m22: T, m31: T, m32: T) -> Self {
-        TypedTransform2D {
-            m11: m11, m12: m12,
-            m21: m21, m22: m22,
-            m31: m31, m32: m32,
-            _unit: PhantomData,
-        }
-    }
-
-    /// Create a transform specifying its matrix elements in column-major order.
-    pub fn column_major(m11: T, m21: T, m31: T, m12: T, m22: T, m32: T) -> Self {
-        TypedTransform2D {
-            m11: m11, m12: m12,
-            m21: m21, m22: m22,
-            m31: m31, m32: m32,
-            _unit: PhantomData,
-        }
-    }
-
-    /// Returns an array containing this transform's terms in row-major order (the order
-    /// in which the transform is actually laid out in memory).
-    pub fn to_row_major_array(&self) -> [T; 6] {
-        [
-            self.m11, self.m12,
-            self.m21, self.m22,
-            self.m31, self.m32
-        ]
-    }
-
-    /// Returns an array containing this transform's terms in column-major order.
-    pub fn to_column_major_array(&self) -> [T; 6] {
-        [
-            self.m11, self.m21, self.m31,
-            self.m12, self.m22, self.m32
-        ]
-    }
-
-    /// Returns an array containing this transform's 3 rows in (in row-major order)
-    /// as arrays.
-    ///
-    /// This is a convenience method to interface with other libraries like glium.
-    pub fn to_row_arrays(&self) -> [[T; 2]; 3] {
-        [
-            [self.m11, self.m12],
-            [self.m21, self.m22],
-            [self.m31, self.m32],
-        ]
-    }
-
-    /// Creates a transform from an array of 6 elements in row-major order.
-    pub fn from_row_major_array(array: [T; 6]) -> Self {
-        Self::row_major(
-            array[0], array[1],
-            array[2], array[3],
-            array[4], array[5],
-        )
-    }
-
-    /// Creates a transform from 3 rows of 2 elements (row-major order).
-    pub fn from_row_arrays(array: [[T; 2]; 3]) -> Self {
-        Self::row_major(
-            array[0][0], array[0][1],
-            array[1][0], array[1][1],
-            array[2][0], array[2][1],
-        )
-    }
-
-    /// Drop the units, preserving only the numeric value.
-    pub fn to_untyped(&self) -> Transform2D<T> {
-        Transform2D::row_major(
-            self.m11, self.m12,
-            self.m21, self.m22,
-            self.m31, self.m32
-        )
-    }
-
-    /// Tag a unitless value with units.
-    pub fn from_untyped(p: &Transform2D<T>) -> Self {
-        TypedTransform2D::row_major(
-            p.m11, p.m12,
-            p.m21, p.m22,
-            p.m31, p.m32
-        )
-    }
-}
-
-impl<T0: NumCast + Copy, Src, Dst> TypedTransform2D<T0, Src, Dst> {
-    /// Cast from one numeric representation to another, preserving the units.
-    pub fn cast<T1: NumCast + Copy>(&self) -> Option<TypedTransform2D<T1, Src, Dst>> {
-        match (NumCast::from(self.m11), NumCast::from(self.m12),
-               NumCast::from(self.m21), NumCast::from(self.m22),
-               NumCast::from(self.m31), NumCast::from(self.m32)) {
-            (Some(m11), Some(m12),
-             Some(m21), Some(m22),
-             Some(m31), Some(m32)) => {
-                Some(TypedTransform2D::row_major(m11, m12,
-                                                 m21, m22,
-                                                 m31, m32))
-            },
-            _ => None
-        }
-    }
-}
-
-impl<T, Src, Dst> TypedTransform2D<T, Src, Dst>
-where T: Copy +
-         PartialEq +
-         One + Zero {
-    pub fn identity() -> Self {
-        let (_0, _1) = (Zero::zero(), One::one());
-        TypedTransform2D::row_major(
-           _1, _0,
-           _0, _1,
-           _0, _0
-        )
-    }
-
-    // Intentional not public, because it checks for exact equivalence
-    // while most consumers will probably want some sort of approximate
-    // equivalence to deal with floating-point errors.
-    fn is_identity(&self) -> bool {
-        *self == TypedTransform2D::identity()
-    }
-}
-
-impl<T, Src, Dst> TypedTransform2D<T, Src, Dst>
-where T: Copy + Clone +
-         Add<T, Output=T> +
-         Mul<T, Output=T> +
-         Div<T, Output=T> +
-         Sub<T, Output=T> +
-         Trig +
-         PartialOrd +
-         One + Zero  {
-
-    /// Returns the multiplication of the two matrices such that mat's transformation
-    /// applies after self's transformation.
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn post_mul<NewDst>(&self, mat: &TypedTransform2D<T, Dst, NewDst>) -> TypedTransform2D<T, Src, NewDst> {
-        TypedTransform2D::row_major(
-            self.m11 * mat.m11 + self.m12 * mat.m21,
-            self.m11 * mat.m12 + self.m12 * mat.m22,
-            self.m21 * mat.m11 + self.m22 * mat.m21,
-            self.m21 * mat.m12 + self.m22 * mat.m22,
-            self.m31 * mat.m11 + self.m32 * mat.m21 + mat.m31,
-            self.m31 * mat.m12 + self.m32 * mat.m22 + mat.m32,
-        )
-    }
-
-    /// Returns the multiplication of the two matrices such that mat's transformation
-    /// applies before self's transformation.
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn pre_mul<NewSrc>(&self, mat: &TypedTransform2D<T, NewSrc, Src>) -> TypedTransform2D<T, NewSrc, Dst> {
-        mat.post_mul(self)
-    }
-
-    /// Returns a translation transform.
-    pub fn create_translation(x: T, y: T) -> Self {
-         let (_0, _1): (T, T) = (Zero::zero(), One::one());
-         TypedTransform2D::row_major(
-            _1, _0,
-            _0, _1,
-             x,  y
-        )
-    }
-
-    /// Applies a translation after self's transformation and returns the resulting transform.
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn post_translate(&self, v: TypedVector2D<T, Dst>) -> Self {
-        self.post_mul(&TypedTransform2D::create_translation(v.x, v.y))
-    }
-
-    /// Applies a translation before self's transformation and returns the resulting transform.
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn pre_translate(&self, v: TypedVector2D<T, Src>) -> Self {
-        self.pre_mul(&TypedTransform2D::create_translation(v.x, v.y))
-    }
-
-    /// Returns a scale transform.
-    pub fn create_scale(x: T, y: T) -> Self {
-        let _0 = Zero::zero();
-        TypedTransform2D::row_major(
-             x, _0,
-            _0,  y,
-            _0, _0
-        )
-    }
-
-    /// Applies a scale after self's transformation and returns the resulting transform.
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn post_scale(&self, x: T, y: T) -> Self {
-        self.post_mul(&TypedTransform2D::create_scale(x, y))
-    }
-
-    /// Applies a scale before self's transformation and returns the resulting transform.
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn pre_scale(&self, x: T, y: T) -> Self {
-        TypedTransform2D::row_major(
-            self.m11 * x, self.m12,
-            self.m21,     self.m22 * y,
-            self.m31,     self.m32
-        )
-    }
-
-    /// Returns a rotation transform.
-    pub fn create_rotation(theta: Radians<T>) -> Self {
-        let _0 = Zero::zero();
-        let cos = theta.get().cos();
-        let sin = theta.get().sin();
-        TypedTransform2D::row_major(
-            cos, _0 - sin,
-            sin, cos,
-             _0, _0
-        )
-    }
-
-    /// Applies a rotation after self's transformation and returns the resulting transform.
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn post_rotate(&self, theta: Radians<T>) -> Self {
-        self.post_mul(&TypedTransform2D::create_rotation(theta))
-    }
-
-    /// Applies a rotation after self's transformation and returns the resulting transform.
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn pre_rotate(&self, theta: Radians<T>) -> Self {
-        self.pre_mul(&TypedTransform2D::create_rotation(theta))
-    }
-
-    /// Returns the given point transformed by this transform.
-    #[inline]
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn transform_point(&self, point: &TypedPoint2D<T, Src>) -> TypedPoint2D<T, Dst> {
-        TypedPoint2D::new(point.x * self.m11 + point.y * self.m21 + self.m31,
-                          point.x * self.m12 + point.y * self.m22 + self.m32)
-    }
-
-    /// Returns the given vector transformed by this matrix.
-    #[inline]
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn transform_vector(&self, vec: &TypedVector2D<T, Src>) -> TypedVector2D<T, Dst> {
-        vec2(vec.x * self.m11 + vec.y * self.m21,
-             vec.x * self.m12 + vec.y * self.m22)
-    }
-
-    /// Returns a rectangle that encompasses the result of transforming the given rectangle by this
-    /// transform.
-    #[inline]
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn transform_rect(&self, rect: &TypedRect<T, Src>) -> TypedRect<T, Dst> {
-        TypedRect::from_points(&[
-            self.transform_point(&rect.origin),
-            self.transform_point(&rect.top_right()),
-            self.transform_point(&rect.bottom_left()),
-            self.transform_point(&rect.bottom_right()),
-        ])
-    }
-
-    /// Computes and returns the determinant of this transform.
-    pub fn determinant(&self) -> T {
-        self.m11 * self.m22 - self.m12 * self.m21
-    }
-
-    /// Returns the inverse transform if possible.
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn inverse(&self) -> Option<TypedTransform2D<T, Dst, Src>> {
-        let det = self.determinant();
-
-        let _0: T = Zero::zero();
-        let _1: T = One::one();
-
-        if det == _0 {
-          return None;
-        }
-
-        let inv_det = _1 / det;
-        Some(TypedTransform2D::row_major(
-            inv_det * self.m22,
-            inv_det * (_0 - self.m12),
-            inv_det * (_0 - self.m21),
-            inv_det * self.m11,
-            inv_det * (self.m21 * self.m32 - self.m22 * self.m31),
-            inv_det * (self.m31 * self.m12 - self.m11 * self.m32),
-        ))
-    }
-
-    /// Returns the same transform with a different destination unit.
-    #[inline]
-    pub fn with_destination<NewDst>(&self) -> TypedTransform2D<T, Src, NewDst> {
-        TypedTransform2D::row_major(
-            self.m11, self.m12,
-            self.m21, self.m22,
-            self.m31, self.m32,
-        )
-    }
-
-    /// Returns the same transform with a different source unit.
-    #[inline]
-    pub fn with_source<NewSrc>(&self) -> TypedTransform2D<T, NewSrc, Dst> {
-        TypedTransform2D::row_major(
-            self.m11, self.m12,
-            self.m21, self.m22,
-            self.m31, self.m32,
-        )
-    }   
-}
-
-impl <T, Src, Dst> TypedTransform2D<T, Src, Dst>
-where T: Copy + Clone +
-         Add<T, Output=T> +
-         Sub<T, Output=T> +
-         Mul<T, Output=T> +
-         Div<T, Output=T> +
-         Neg<Output=T> +
-         ApproxEq<T> +
-         PartialOrd +
-         Trig +
-         One + Zero {
-    /// Create a 3D transform from the current transform
-    pub fn to_3d(&self) -> TypedTransform3D<T, Src, Dst> {
-        TypedTransform3D::row_major_2d(self.m11, self.m12, self.m21, self.m22, self.m31, self.m32)
-    }
-
-}
-
-impl<T: ApproxEq<T>, Src, Dst> TypedTransform2D<T, Src, Dst> {
-    pub fn approx_eq(&self, other: &Self) -> bool {
-        self.m11.approx_eq(&other.m11) && self.m12.approx_eq(&other.m12) &&
-        self.m21.approx_eq(&other.m21) && self.m22.approx_eq(&other.m22) &&
-        self.m31.approx_eq(&other.m31) && self.m32.approx_eq(&other.m32)
-    }
-}
-
-impl<T: Copy + fmt::Debug, Src, Dst> fmt::Debug for TypedTransform2D<T, Src, Dst>
-where T: Copy + fmt::Debug +
-         PartialEq +
-         One + Zero {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        if self.is_identity() {
-            write!(f, "[I]")
-        } else {
-            self.to_row_major_array().fmt(f)
-        }
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use super::*;
-    use approxeq::ApproxEq;
-    use point::Point2D;
-    use Radians;
-
-    use std::f32::consts::FRAC_PI_2;
-
-    type Mat = Transform2D<f32>;
-
-    fn rad(v: f32) -> Radians<f32> { Radians::new(v) }
-
-    #[test]
-    pub fn test_translation() {
-        let t1 = Mat::create_translation(1.0, 2.0);
-        let t2 = Mat::identity().pre_translate(vec2(1.0, 2.0));
-        let t3 = Mat::identity().post_translate(vec2(1.0, 2.0));
-        assert_eq!(t1, t2);
-        assert_eq!(t1, t3);
-
-        assert_eq!(t1.transform_point(&Point2D::new(1.0, 1.0)), Point2D::new(2.0, 3.0));
-
-        assert_eq!(t1.post_mul(&t1), Mat::create_translation(2.0, 4.0));
-    }
-
-    #[test]
-    pub fn test_rotation() {
-        let r1 = Mat::create_rotation(rad(FRAC_PI_2));
-        let r2 = Mat::identity().pre_rotate(rad(FRAC_PI_2));
-        let r3 = Mat::identity().post_rotate(rad(FRAC_PI_2));
-        assert_eq!(r1, r2);
-        assert_eq!(r1, r3);
-
-        assert!(r1.transform_point(&Point2D::new(1.0, 2.0)).approx_eq(&Point2D::new(2.0, -1.0)));
-
-        assert!(r1.post_mul(&r1).approx_eq(&Mat::create_rotation(rad(FRAC_PI_2*2.0))));
-    }
-
-    #[test]
-    pub fn test_scale() {
-        let s1 = Mat::create_scale(2.0, 3.0);
-        let s2 = Mat::identity().pre_scale(2.0, 3.0);
-        let s3 = Mat::identity().post_scale(2.0, 3.0);
-        assert_eq!(s1, s2);
-        assert_eq!(s1, s3);
-
-        assert!(s1.transform_point(&Point2D::new(2.0, 2.0)).approx_eq(&Point2D::new(4.0, 6.0)));
-    }
-
-    #[test]
-    fn test_column_major() {
-        assert_eq!(
-            Mat::row_major(
-                1.0,  2.0,
-                3.0,  4.0,
-                5.0,  6.0
-            ),
-            Mat::column_major(
-                1.0,  3.0,  5.0,
-                2.0,  4.0,  6.0,
-            )
-        );
-    }
-
-    #[test]
-    pub fn test_inverse_simple() {
-        let m1 = Mat::identity();
-        let m2 = m1.inverse().unwrap();
-        assert!(m1.approx_eq(&m2));
-    }
-
-    #[test]
-    pub fn test_inverse_scale() {
-        let m1 = Mat::create_scale(1.5, 0.3);
-        let m2 = m1.inverse().unwrap();
-        assert!(m1.pre_mul(&m2).approx_eq(&Mat::identity()));
-    }
-
-    #[test]
-    pub fn test_inverse_translate() {
-        let m1 = Mat::create_translation(-132.0, 0.3);
-        let m2 = m1.inverse().unwrap();
-        assert!(m1.pre_mul(&m2).approx_eq(&Mat::identity()));
-    }
-
-    #[test]
-    fn test_inverse_none() {
-        assert!(Mat::create_scale(2.0, 0.0).inverse().is_none());
-        assert!(Mat::create_scale(2.0, 2.0).inverse().is_some());
-    }
-
-    #[test]
-    pub fn test_pre_post() {
-        let m1 = Transform2D::identity().post_scale(1.0, 2.0).post_translate(vec2(1.0, 2.0));
-        let m2 = Transform2D::identity().pre_translate(vec2(1.0, 2.0)).pre_scale(1.0, 2.0);
-        assert!(m1.approx_eq(&m2));
-
-        let r = Mat::create_rotation(rad(FRAC_PI_2));
-        let t = Mat::create_translation(2.0, 3.0);
-
-        let a = Point2D::new(1.0, 1.0);
-
-        assert!(r.post_mul(&t).transform_point(&a).approx_eq(&Point2D::new(3.0, 2.0)));
-        assert!(t.post_mul(&r).transform_point(&a).approx_eq(&Point2D::new(4.0, -3.0)));
-        assert!(t.post_mul(&r).transform_point(&a).approx_eq(&r.transform_point(&t.transform_point(&a))));
-
-        assert!(r.pre_mul(&t).transform_point(&a).approx_eq(&Point2D::new(4.0, -3.0)));
-        assert!(t.pre_mul(&r).transform_point(&a).approx_eq(&Point2D::new(3.0, 2.0)));
-        assert!(t.pre_mul(&r).transform_point(&a).approx_eq(&t.transform_point(&r.transform_point(&a))));
-    }
-
-    #[test]
-    fn test_size_of() {
-        use std::mem::size_of;
-        assert_eq!(size_of::<Transform2D<f32>>(), 6*size_of::<f32>());
-        assert_eq!(size_of::<Transform2D<f64>>(), 6*size_of::<f64>());
-    }
-
-    #[test]
-    pub fn test_is_identity() {
-        let m1 = Transform2D::identity();
-        assert!(m1.is_identity());
-        let m2 = m1.post_translate(vec2(0.1, 0.0));
-        assert!(!m2.is_identity());
-    }
-
-    #[test]
-    pub fn test_transform_vector() {
-        // Translation does not apply to vectors.
-        let m1 = Mat::create_translation(1.0, 1.0);
-        let v1 = vec2(10.0, -10.0);
-        assert_eq!(v1, m1.transform_vector(&v1));
-    }
-}
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/transform3d.rs
+++ /dev/null
@@ -1,945 +0,0 @@
-// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use super::{UnknownUnit, Radians};
-use approxeq::ApproxEq;
-use trig::Trig;
-use point::{TypedPoint2D, TypedPoint3D, point2, point3};
-use vector::{TypedVector2D, TypedVector3D, vec2, vec3};
-use rect::TypedRect;
-use transform2d::TypedTransform2D;
-use scale_factor::ScaleFactor;
-use num::{One, Zero};
-use std::ops::{Add, Mul, Sub, Div, Neg};
-use std::marker::PhantomData;
-use std::fmt;
-use num_traits::NumCast;
-
-define_matrix! {
-    /// A 3d transform stored as a 4 by 4 matrix in row-major order in memory.
-    ///
-    /// Transforms can be parametrized over the source and destination units, to describe a
-    /// transformation from a space to another.
-    /// For example, `TypedTransform3D<f32, WordSpace, ScreenSpace>::transform_point3d`
-    /// takes a `TypedPoint3D<f32, WordSpace>` and returns a `TypedPoint3D<f32, ScreenSpace>`.
-    ///
-    /// Transforms expose a set of convenience methods for pre- and post-transformations.
-    /// A pre-transformation corresponds to adding an operation that is applied before
-    /// the rest of the transformation, while a post-transformation adds an operation
-    /// that is applied after.
-    pub struct TypedTransform3D<T, Src, Dst> {
-        pub m11: T, pub m12: T, pub m13: T, pub m14: T,
-        pub m21: T, pub m22: T, pub m23: T, pub m24: T,
-        pub m31: T, pub m32: T, pub m33: T, pub m34: T,
-        pub m41: T, pub m42: T, pub m43: T, pub m44: T,
-    }
-}
-
-/// The default 4d transform type with no units.
-pub type Transform3D<T> = TypedTransform3D<T, UnknownUnit, UnknownUnit>;
-
-impl<T, Src, Dst> TypedTransform3D<T, Src, Dst> {
-    /// Create a transform specifying its components in row-major order.
-    ///
-    /// For example, the translation terms m41, m42, m43 on the last row with the
-    /// row-major convention) are the 13rd, 14th and 15th parameters.
-    #[inline]
-    pub fn row_major(
-            m11: T, m12: T, m13: T, m14: T,
-            m21: T, m22: T, m23: T, m24: T,
-            m31: T, m32: T, m33: T, m34: T,
-            m41: T, m42: T, m43: T, m44: T)
-         -> Self {
-        TypedTransform3D {
-            m11: m11, m12: m12, m13: m13, m14: m14,
-            m21: m21, m22: m22, m23: m23, m24: m24,
-            m31: m31, m32: m32, m33: m33, m34: m34,
-            m41: m41, m42: m42, m43: m43, m44: m44,
-            _unit: PhantomData,
-        }
-    }
-
-    /// Create a transform specifying its components in column-major order.
-    ///
-    /// For example, the translation terms m41, m42, m43 on the last column with the
-    /// column-major convention) are the 4th, 8th and 12nd parameters.
-    #[inline]
-    pub fn column_major(
-            m11: T, m21: T, m31: T, m41: T,
-            m12: T, m22: T, m32: T, m42: T,
-            m13: T, m23: T, m33: T, m43: T,
-            m14: T, m24: T, m34: T, m44: T)
-         -> Self {
-        TypedTransform3D {
-            m11: m11, m12: m12, m13: m13, m14: m14,
-            m21: m21, m22: m22, m23: m23, m24: m24,
-            m31: m31, m32: m32, m33: m33, m34: m34,
-            m41: m41, m42: m42, m43: m43, m44: m44,
-            _unit: PhantomData,
-        }
-    }
-}
-
-impl <T, Src, Dst> TypedTransform3D<T, Src, Dst>
-where T: Copy + Clone +
-         PartialEq +
-         One + Zero {
-    #[inline]
-    pub fn identity() -> Self {
-        let (_0, _1): (T, T) = (Zero::zero(), One::one());
-        TypedTransform3D::row_major(
-            _1, _0, _0, _0,
-            _0, _1, _0, _0,
-            _0, _0, _1, _0,
-            _0, _0, _0, _1
-        )
-    }
-
-    // Intentional not public, because it checks for exact equivalence
-    // while most consumers will probably want some sort of approximate
-    // equivalence to deal with floating-point errors.
-    #[inline]
-    fn is_identity(&self) -> bool {
-        *self == TypedTransform3D::identity()
-    }
-}
-
-impl <T, Src, Dst> TypedTransform3D<T, Src, Dst>
-where T: Copy + Clone +
-         Add<T, Output=T> +
-         Sub<T, Output=T> +
-         Mul<T, Output=T> +
-         Div<T, Output=T> +
-         Neg<Output=T> +
-         ApproxEq<T> +
-         PartialOrd +
-         Trig +
-         One + Zero {
-
-    /// Create a 4 by 4 transform representing a 2d transformation, specifying its components
-    /// in row-major order.
-    #[inline]
-    pub fn row_major_2d(m11: T, m12: T, m21: T, m22: T, m41: T, m42: T) -> Self {
-        let (_0, _1): (T, T) = (Zero::zero(), One::one());
-        TypedTransform3D::row_major(
-            m11, m12, _0, _0,
-            m21, m22, _0, _0,
-             _0,  _0, _1, _0,
-            m41, m42, _0, _1
-       )
-    }
-
-    /// Create an orthogonal projection transform.
-    pub fn ortho(left: T, right: T,
-                 bottom: T, top: T,
-                 near: T, far: T) -> Self {
-        let tx = -((right + left) / (right - left));
-        let ty = -((top + bottom) / (top - bottom));
-        let tz = -((far + near) / (far - near));
-
-        let (_0, _1): (T, T) = (Zero::zero(), One::one());
-        let _2 = _1 + _1;
-        TypedTransform3D::row_major(
-            _2 / (right - left), _0                 , _0                , _0,
-            _0                 , _2 / (top - bottom), _0                , _0,
-            _0                 , _0                 , -_2 / (far - near), _0,
-            tx                 , ty                 , tz                , _1
-        )
-    }
-
-    /// Returns true if this transform can be represented with a TypedTransform2D.
-    ///
-    /// See https://drafts.csswg.org/css-transforms/#2d-transform
-    #[inline]
-    pub fn is_2d(&self) -> bool {
-        let (_0, _1): (T, T) = (Zero::zero(), One::one());
-        self.m31 == _0 && self.m32 == _0 &&
-        self.m13 == _0 && self.m23 == _0 &&
-        self.m43 == _0 && self.m14 == _0 &&
-        self.m24 == _0 && self.m34 == _0 &&
-        self.m33 == _1 && self.m44 == _1
-    }
-
-    /// Create a 2D transform picking the relevent terms from this transform.
-    ///
-    /// This method assumes that self represents a 2d transformation, callers
-    /// should check that self.is_2d() returns true beforehand.
-    pub fn to_2d(&self) -> TypedTransform2D<T, Src, Dst> {
-        TypedTransform2D::row_major(
-            self.m11, self.m12,
-            self.m21, self.m22,
-            self.m41, self.m42
-        )
-    }
-
-    /// Check whether shapes on the XY plane with Z pointing towards the
-    /// screen transformed by this matrix would be facing back.
-    pub fn is_backface_visible(&self) -> bool {
-        // inverse().m33 < 0;
-        let det = self.determinant();
-        let m33 = self.m12 * self.m24 * self.m41 - self.m14 * self.m22 * self.m41 +
-                  self.m14 * self.m21 * self.m42 - self.m11 * self.m24 * self.m42 -
-                  self.m12 * self.m21 * self.m44 + self.m11 * self.m22 * self.m44;
-        let _0: T = Zero::zero();
-        (m33 * det) < _0
-    }
-
-    pub fn approx_eq(&self, other: &Self) -> bool {
-        self.m11.approx_eq(&other.m11) && self.m12.approx_eq(&other.m12) &&
-        self.m13.approx_eq(&other.m13) && self.m14.approx_eq(&other.m14) &&
-        self.m21.approx_eq(&other.m21) && self.m22.approx_eq(&other.m22) &&
-        self.m23.approx_eq(&other.m23) && self.m24.approx_eq(&other.m24) &&
-        self.m31.approx_eq(&other.m31) && self.m32.approx_eq(&other.m32) &&
-        self.m33.approx_eq(&other.m33) && self.m34.approx_eq(&other.m34) &&
-        self.m41.approx_eq(&other.m41) && self.m42.approx_eq(&other.m42) &&
-        self.m43.approx_eq(&other.m43) && self.m44.approx_eq(&other.m44)
-    }
-
-    /// Returns the same transform with a different destination unit.
-    #[inline]
-    pub fn with_destination<NewDst>(&self) -> TypedTransform3D<T, Src, NewDst> {
-        TypedTransform3D::row_major(
-            self.m11, self.m12, self.m13, self.m14,
-            self.m21, self.m22, self.m23, self.m24,
-            self.m31, self.m32, self.m33, self.m34,
-            self.m41, self.m42, self.m43, self.m44,
-        )
-    }
-
-    /// Returns the same transform with a different source unit.
-    #[inline]
-    pub fn with_source<NewSrc>(&self) -> TypedTransform3D<T, NewSrc, Dst> {
-        TypedTransform3D::row_major(
-            self.m11, self.m12, self.m13, self.m14,
-            self.m21, self.m22, self.m23, self.m24,
-            self.m31, self.m32, self.m33, self.m34,
-            self.m41, self.m42, self.m43, self.m44,
-        )
-    }
-
-    /// Drop the units, preserving only the numeric value.
-    #[inline]
-    pub fn to_untyped(&self) -> Transform3D<T> {
-        Transform3D::row_major(
-            self.m11, self.m12, self.m13, self.m14,
-            self.m21, self.m22, self.m23, self.m24,
-            self.m31, self.m32, self.m33, self.m34,
-            self.m41, self.m42, self.m43, self.m44,
-        )
-    }
-
-    /// Tag a unitless value with units.
-    #[inline]
-    pub fn from_untyped(m: &Transform3D<T>) -> Self {
-        TypedTransform3D::row_major(
-            m.m11, m.m12, m.m13, m.m14,
-            m.m21, m.m22, m.m23, m.m24,
-            m.m31, m.m32, m.m33, m.m34,
-            m.m41, m.m42, m.m43, m.m44,
-        )
-    }
-
-    /// Returns the multiplication of the two matrices such that mat's transformation
-    /// applies after self's transformation.
-    pub fn post_mul<NewDst>(&self, mat: &TypedTransform3D<T, Dst, NewDst>) -> TypedTransform3D<T, Src, NewDst> {
-        TypedTransform3D::row_major(
-            self.m11 * mat.m11  +  self.m12 * mat.m21  +  self.m13 * mat.m31  +  self.m14 * mat.m41,
-            self.m11 * mat.m12  +  self.m12 * mat.m22  +  self.m13 * mat.m32  +  self.m14 * mat.m42,
-            self.m11 * mat.m13  +  self.m12 * mat.m23  +  self.m13 * mat.m33  +  self.m14 * mat.m43,
-            self.m11 * mat.m14  +  self.m12 * mat.m24  +  self.m13 * mat.m34  +  self.m14 * mat.m44,
-            self.m21 * mat.m11  +  self.m22 * mat.m21  +  self.m23 * mat.m31  +  self.m24 * mat.m41,
-            self.m21 * mat.m12  +  self.m22 * mat.m22  +  self.m23 * mat.m32  +  self.m24 * mat.m42,
-            self.m21 * mat.m13  +  self.m22 * mat.m23  +  self.m23 * mat.m33  +  self.m24 * mat.m43,
-            self.m21 * mat.m14  +  self.m22 * mat.m24  +  self.m23 * mat.m34  +  self.m24 * mat.m44,
-            self.m31 * mat.m11  +  self.m32 * mat.m21  +  self.m33 * mat.m31  +  self.m34 * mat.m41,
-            self.m31 * mat.m12  +  self.m32 * mat.m22  +  self.m33 * mat.m32  +  self.m34 * mat.m42,
-            self.m31 * mat.m13  +  self.m32 * mat.m23  +  self.m33 * mat.m33  +  self.m34 * mat.m43,
-            self.m31 * mat.m14  +  self.m32 * mat.m24  +  self.m33 * mat.m34  +  self.m34 * mat.m44,
-            self.m41 * mat.m11  +  self.m42 * mat.m21  +  self.m43 * mat.m31  +  self.m44 * mat.m41,
-            self.m41 * mat.m12  +  self.m42 * mat.m22  +  self.m43 * mat.m32  +  self.m44 * mat.m42,
-            self.m41 * mat.m13  +  self.m42 * mat.m23  +  self.m43 * mat.m33  +  self.m44 * mat.m43,
-            self.m41 * mat.m14  +  self.m42 * mat.m24  +  self.m43 * mat.m34  +  self.m44 * mat.m44,
-        )
-    }
-
-    /// Returns the multiplication of the two matrices such that mat's transformation
-    /// applies before self's transformation.
-    pub fn pre_mul<NewSrc>(&self, mat: &TypedTransform3D<T, NewSrc, Src>) -> TypedTransform3D<T, NewSrc, Dst> {
-        mat.post_mul(self)
-    }
-
-    /// Returns the inverse transform if possible.
-    pub fn inverse(&self) -> Option<TypedTransform3D<T, Dst, Src>> {
-        let det = self.determinant();
-
-        if det == Zero::zero() {
-            return None;
-        }
-
-        // todo(gw): this could be made faster by special casing
-        // for simpler transform types.
-        let m = TypedTransform3D::row_major(
-            self.m23*self.m34*self.m42 - self.m24*self.m33*self.m42 +
-            self.m24*self.m32*self.m43 - self.m22*self.m34*self.m43 -
-            self.m23*self.m32*self.m44 + self.m22*self.m33*self.m44,
-
-            self.m14*self.m33*self.m42 - self.m13*self.m34*self.m42 -
-            self.m14*self.m32*self.m43 + self.m12*self.m34*self.m43 +
-            self.m13*self.m32*self.m44 - self.m12*self.m33*self.m44,
-
-            self.m13*self.m24*self.m42 - self.m14*self.m23*self.m42 +
-            self.m14*self.m22*self.m43 - self.m12*self.m24*self.m43 -
-            self.m13*self.m22*self.m44 + self.m12*self.m23*self.m44,
-
-            self.m14*self.m23*self.m32 - self.m13*self.m24*self.m32 -
-            self.m14*self.m22*self.m33 + self.m12*self.m24*self.m33 +
-            self.m13*self.m22*self.m34 - self.m12*self.m23*self.m34,
-
-            self.m24*self.m33*self.m41 - self.m23*self.m34*self.m41 -
-            self.m24*self.m31*self.m43 + self.m21*self.m34*self.m43 +
-            self.m23*self.m31*self.m44 - self.m21*self.m33*self.m44,
-
-            self.m13*self.m34*self.m41 - self.m14*self.m33*self.m41 +
-            self.m14*self.m31*self.m43 - self.m11*self.m34*self.m43 -
-            self.m13*self.m31*self.m44 + self.m11*self.m33*self.m44,
-
-            self.m14*self.m23*self.m41 - self.m13*self.m24*self.m41 -
-            self.m14*self.m21*self.m43 + self.m11*self.m24*self.m43 +
-            self.m13*self.m21*self.m44 - self.m11*self.m23*self.m44,
-
-            self.m13*self.m24*self.m31 - self.m14*self.m23*self.m31 +
-            self.m14*self.m21*self.m33 - self.m11*self.m24*self.m33 -
-            self.m13*self.m21*self.m34 + self.m11*self.m23*self.m34,
-
-            self.m22*self.m34*self.m41 - self.m24*self.m32*self.m41 +
-            self.m24*self.m31*self.m42 - self.m21*self.m34*self.m42 -
-            self.m22*self.m31*self.m44 + self.m21*self.m32*self.m44,
-
-            self.m14*self.m32*self.m41 - self.m12*self.m34*self.m41 -
-            self.m14*self.m31*self.m42 + self.m11*self.m34*self.m42 +
-            self.m12*self.m31*self.m44 - self.m11*self.m32*self.m44,
-
-            self.m12*self.m24*self.m41 - self.m14*self.m22*self.m41 +
-            self.m14*self.m21*self.m42 - self.m11*self.m24*self.m42 -
-            self.m12*self.m21*self.m44 + self.m11*self.m22*self.m44,
-
-            self.m14*self.m22*self.m31 - self.m12*self.m24*self.m31 -
-            self.m14*self.m21*self.m32 + self.m11*self.m24*self.m32 +
-            self.m12*self.m21*self.m34 - self.m11*self.m22*self.m34,
-
-            self.m23*self.m32*self.m41 - self.m22*self.m33*self.m41 -
-            self.m23*self.m31*self.m42 + self.m21*self.m33*self.m42 +
-            self.m22*self.m31*self.m43 - self.m21*self.m32*self.m43,
-
-            self.m12*self.m33*self.m41 - self.m13*self.m32*self.m41 +
-            self.m13*self.m31*self.m42 - self.m11*self.m33*self.m42 -
-            self.m12*self.m31*self.m43 + self.m11*self.m32*self.m43,
-
-            self.m13*self.m22*self.m41 - self.m12*self.m23*self.m41 -
-            self.m13*self.m21*self.m42 + self.m11*self.m23*self.m42 +
-            self.m12*self.m21*self.m43 - self.m11*self.m22*self.m43,
-
-            self.m12*self.m23*self.m31 - self.m13*self.m22*self.m31 +
-            self.m13*self.m21*self.m32 - self.m11*self.m23*self.m32 -
-            self.m12*self.m21*self.m33 + self.m11*self.m22*self.m33
-        );
-
-        let _1: T = One::one();
-        Some(m.mul_s(_1 / det))
-    }
-
-    /// Compute the determinant of the transform.
-    pub fn determinant(&self) -> T {
-        self.m14 * self.m23 * self.m32 * self.m41 -
-        self.m13 * self.m24 * self.m32 * self.m41 -
-        self.m14 * self.m22 * self.m33 * self.m41 +
-        self.m12 * self.m24 * self.m33 * self.m41 +
-        self.m13 * self.m22 * self.m34 * self.m41 -
-        self.m12 * self.m23 * self.m34 * self.m41 -
-        self.m14 * self.m23 * self.m31 * self.m42 +
-        self.m13 * self.m24 * self.m31 * self.m42 +
-        self.m14 * self.m21 * self.m33 * self.m42 -
-        self.m11 * self.m24 * self.m33 * self.m42 -
-        self.m13 * self.m21 * self.m34 * self.m42 +
-        self.m11 * self.m23 * self.m34 * self.m42 +
-        self.m14 * self.m22 * self.m31 * self.m43 -
-        self.m12 * self.m24 * self.m31 * self.m43 -
-        self.m14 * self.m21 * self.m32 * self.m43 +
-        self.m11 * self.m24 * self.m32 * self.m43 +
-        self.m12 * self.m21 * self.m34 * self.m43 -
-        self.m11 * self.m22 * self.m34 * self.m43 -
-        self.m13 * self.m22 * self.m31 * self.m44 +
-        self.m12 * self.m23 * self.m31 * self.m44 +
-        self.m13 * self.m21 * self.m32 * self.m44 -
-        self.m11 * self.m23 * self.m32 * self.m44 -
-        self.m12 * self.m21 * self.m33 * self.m44 +
-        self.m11 * self.m22 * self.m33 * self.m44
-    }
-
-    /// Multiplies all of the transform's component by a scalar and returns the result.
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn mul_s(&self, x: T) -> Self {
-        TypedTransform3D::row_major(
-            self.m11 * x, self.m12 * x, self.m13 * x, self.m14 * x,
-            self.m21 * x, self.m22 * x, self.m23 * x, self.m24 * x,
-            self.m31 * x, self.m32 * x, self.m33 * x, self.m34 * x,
-            self.m41 * x, self.m42 * x, self.m43 * x, self.m44 * x
-        )
-    }
-
-    /// Convenience function to create a scale transform from a ScaleFactor.
-    pub fn from_scale_factor(scale: ScaleFactor<T, Src, Dst>) -> Self {
-        TypedTransform3D::create_scale(scale.get(), scale.get(), scale.get())
-    }
-
-    /// Returns the given 2d point transformed by this transform.
-    ///
-    /// The input point must be use the unit Src, and the returned point has the unit Dst.
-    #[inline]
-    pub fn transform_point2d(&self, p: &TypedPoint2D<T, Src>) -> TypedPoint2D<T, Dst> {
-        let x = p.x * self.m11 + p.y * self.m21 + self.m41;
-        let y = p.x * self.m12 + p.y * self.m22 + self.m42;
-
-        let w = p.x * self.m14 + p.y * self.m24 + self.m44;
-
-        point2(x/w, y/w)
-    }
-
-    /// Returns the given 2d vector transformed by this matrix.
-    ///
-    /// The input point must be use the unit Src, and the returned point has the unit Dst.
-    #[inline]
-    pub fn transform_vector2d(&self, v: &TypedVector2D<T, Src>) -> TypedVector2D<T, Dst> {
-        vec2(
-            v.x * self.m11 + v.y * self.m21,
-            v.x * self.m12 + v.y * self.m22,
-        )
-    }
-
-    /// Returns the given 3d point transformed by this transform.
-    ///
-    /// The input point must be use the unit Src, and the returned point has the unit Dst.
-    #[inline]
-    pub fn transform_point3d(&self, p: &TypedPoint3D<T, Src>) -> TypedPoint3D<T, Dst> {
-        let x = p.x * self.m11 + p.y * self.m21 + p.z * self.m31 + self.m41;
-        let y = p.x * self.m12 + p.y * self.m22 + p.z * self.m32 + self.m42;
-        let z = p.x * self.m13 + p.y * self.m23 + p.z * self.m33 + self.m43;
-        let w = p.x * self.m14 + p.y * self.m24 + p.z * self.m34 + self.m44;
-
-        point3(x/w, y/w, z/w)
-    }
-
-    /// Returns the given 3d vector transformed by this matrix.
-    ///
-    /// The input point must be use the unit Src, and the returned point has the unit Dst.
-    #[inline]
-    pub fn transform_vector3d(&self, v: &TypedVector3D<T, Src>) -> TypedVector3D<T, Dst> {
-        vec3(
-            v.x * self.m11 + v.y * self.m21 + v.z * self.m31,
-            v.x * self.m12 + v.y * self.m22 + v.z * self.m32,
-            v.x * self.m13 + v.y * self.m23 + v.z * self.m33,
-        )
-    }
-
-    /// Returns a rectangle that encompasses the result of transforming the given rectangle by this
-    /// transform.
-    pub fn transform_rect(&self, rect: &TypedRect<T, Src>) -> TypedRect<T, Dst> {
-        TypedRect::from_points(&[
-            self.transform_point2d(&rect.origin),
-            self.transform_point2d(&rect.top_right()),
-            self.transform_point2d(&rect.bottom_left()),
-            self.transform_point2d(&rect.bottom_right()),
-        ])
-    }
-
-    /// Create a 3d translation transform
-    pub fn create_translation(x: T, y: T, z: T) -> Self {
-        let (_0, _1): (T, T) = (Zero::zero(), One::one());
-        TypedTransform3D::row_major(
-            _1, _0, _0, _0,
-            _0, _1, _0, _0,
-            _0, _0, _1, _0,
-             x,  y,  z, _1
-        )
-    }
-
-    /// Returns a transform with a translation applied before self's transformation.
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn pre_translate(&self, v: TypedVector3D<T, Src>) -> Self {
-        self.pre_mul(&TypedTransform3D::create_translation(v.x, v.y, v.z))
-    }
-
-    /// Returns a transform with a translation applied after self's transformation.
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn post_translate(&self, v: TypedVector3D<T, Dst>) -> Self {
-        self.post_mul(&TypedTransform3D::create_translation(v.x, v.y, v.z))
-    }
-
-    /// Create a 3d scale transform
-    pub fn create_scale(x: T, y: T, z: T) -> Self {
-        let (_0, _1): (T, T) = (Zero::zero(), One::one());
-        TypedTransform3D::row_major(
-             x, _0, _0, _0,
-            _0,  y, _0, _0,
-            _0, _0,  z, _0,
-            _0, _0, _0, _1
-        )
-    }
-
-    /// Returns a transform with a scale applied before self's transformation.
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn pre_scale(&self, x: T, y: T, z: T) -> Self {
-        TypedTransform3D::row_major(
-            self.m11 * x, self.m12,     self.m13,     self.m14,
-            self.m21    , self.m22 * y, self.m23,     self.m24,
-            self.m31    , self.m32,     self.m33 * z, self.m34,
-            self.m41    , self.m42,     self.m43,     self.m44
-        )
-    }
-
-    /// Returns a transform with a scale applied after self's transformation.
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn post_scale(&self, x: T, y: T, z: T) -> Self {
-        self.post_mul(&TypedTransform3D::create_scale(x, y, z))
-    }
-
-    /// Create a 3d rotation transform from an angle / axis.
-    /// The supplied axis must be normalized.
-    pub fn create_rotation(x: T, y: T, z: T, theta: Radians<T>) -> Self {
-        let (_0, _1): (T, T) = (Zero::zero(), One::one());
-        let _2 = _1 + _1;
-
-        let xx = x * x;
-        let yy = y * y;
-        let zz = z * z;
-
-        let half_theta = theta.get() / _2;
-        let sc = half_theta.sin() * half_theta.cos();
-        let sq = half_theta.sin() * half_theta.sin();
-
-        TypedTransform3D::row_major(
-            _1 - _2 * (yy + zz) * sq,
-            _2 * (x * y * sq - z * sc),
-            _2 * (x * z * sq + y * sc),
-            _0,
-
-            _2 * (x * y * sq + z * sc),
-            _1 - _2 * (xx + zz) * sq,
-            _2 * (y * z * sq - x * sc),
-            _0,
-
-            _2 * (x * z * sq - y * sc),
-            _2 * (y * z * sq + x * sc),
-            _1 - _2 * (xx + yy) * sq,
-            _0,
-
-            _0,
-            _0,
-            _0,
-            _1
-        )
-    }
-
-    /// Returns a transform with a rotation applied after self's transformation.
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn post_rotate(&self, x: T, y: T, z: T, theta: Radians<T>) -> Self {
-        self.post_mul(&TypedTransform3D::create_rotation(x, y, z, theta))
-    }
-
-    /// Returns a transform with a rotation applied before self's transformation.
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn pre_rotate(&self, x: T, y: T, z: T, theta: Radians<T>) -> Self {
-        self.pre_mul(&TypedTransform3D::create_rotation(x, y, z, theta))
-    }
-
-    /// Create a 2d skew transform.
-    ///
-    /// See https://drafts.csswg.org/css-transforms/#funcdef-skew
-    pub fn create_skew(alpha: Radians<T>, beta: Radians<T>) -> Self {
-        let (_0, _1): (T, T) = (Zero::zero(), One::one());
-        let (sx, sy) = (beta.get().tan(), alpha.get().tan());
-        TypedTransform3D::row_major(
-            _1, sx, _0, _0,
-            sy, _1, _0, _0,
-            _0, _0, _1, _0,
-            _0, _0, _0, _1
-        )
-    }
-
-    /// Create a simple perspective projection transform
-    pub fn create_perspective(d: T) -> Self {
-        let (_0, _1): (T, T) = (Zero::zero(), One::one());
-        TypedTransform3D::row_major(
-            _1, _0, _0, _0,
-            _0, _1, _0, _0,
-            _0, _0, _1, -_1 / d,
-            _0, _0, _0, _1
-        )
-    }
-}
-
-impl<T: Copy, Src, Dst> TypedTransform3D<T, Src, Dst> {
-    /// Returns an array containing this transform's terms in row-major order (the order
-    /// in which the transform is actually laid out in memory).
-    pub fn to_row_major_array(&self) -> [T; 16] {
-        [
-            self.m11, self.m12, self.m13, self.m14,
-            self.m21, self.m22, self.m23, self.m24,
-            self.m31, self.m32, self.m33, self.m34,
-            self.m41, self.m42, self.m43, self.m44
-        ]
-    }
-
-    /// Returns an array containing this transform's terms in column-major order.
-    pub fn to_column_major_array(&self) -> [T; 16] {
-        [
-            self.m11, self.m21, self.m31, self.m41,
-            self.m12, self.m22, self.m32, self.m42,
-            self.m13, self.m23, self.m33, self.m43,
-            self.m14, self.m24, self.m34, self.m44
-        ]
-    }
-
-    /// Returns an array containing this transform's 4 rows in (in row-major order)
-    /// as arrays.
-    ///
-    /// This is a convenience method to interface with other libraries like glium.
-    pub fn to_row_arrays(&self) -> [[T; 4]; 4] {
-        [
-            [self.m11, self.m12, self.m13, self.m14],
-            [self.m21, self.m22, self.m23, self.m24],
-            [self.m31, self.m32, self.m33, self.m34],
-            [self.m41, self.m42, self.m43, self.m44]
-        ]
-    }
-
-    /// Returns an array containing this transform's 4 columns in (in row-major order,
-    /// or 4 rows in column-major order) as arrays.
-    ///
-    /// This is a convenience method to interface with other libraries like glium.
-    pub fn to_column_arrays(&self) -> [[T; 4]; 4] {
-        [
-            [self.m11, self.m21, self.m31, self.m41],
-            [self.m12, self.m22, self.m32, self.m42],
-            [self.m13, self.m23, self.m33, self.m43],
-            [self.m14, self.m24, self.m34, self.m44]
-        ]
-    }
-
-    /// Creates a transform from an array of 16 elements in row-major order.
-    pub fn from_array(array: [T; 16]) -> Self {
-        Self::row_major(
-            array[0],  array[1],  array[2],  array[3],
-            array[4],  array[5],  array[6],  array[7],
-            array[8],  array[9],  array[10], array[11],
-            array[12], array[13], array[14], array[15],
-        )
-    }
-
-    /// Creates a transform from 4 rows of 4 elements (row-major order).
-    pub fn from_row_arrays(array: [[T; 4]; 4]) -> Self {
-        Self::row_major(
-            array[0][0], array[0][1], array[0][2], array[0][3],
-            array[1][0], array[1][1], array[1][2], array[1][3],
-            array[2][0], array[2][1], array[2][2], array[2][3],
-            array[3][0], array[3][1], array[3][2], array[3][3],
-        )
-    }
-}
-
-impl<T0: NumCast + Copy, Src, Dst> TypedTransform3D<T0, Src, Dst> {
-    /// Cast from one numeric representation to another, preserving the units.
-    pub fn cast<T1: NumCast + Copy>(&self) -> Option<TypedTransform3D<T1, Src, Dst>> {
-        match (NumCast::from(self.m11), NumCast::from(self.m12),
-               NumCast::from(self.m13), NumCast::from(self.m14),
-               NumCast::from(self.m21), NumCast::from(self.m22),
-               NumCast::from(self.m23), NumCast::from(self.m24),
-               NumCast::from(self.m31), NumCast::from(self.m32),
-               NumCast::from(self.m33), NumCast::from(self.m34),
-               NumCast::from(self.m41), NumCast::from(self.m42),
-               NumCast::from(self.m43), NumCast::from(self.m44)) {
-            (Some(m11), Some(m12), Some(m13), Some(m14),
-             Some(m21), Some(m22), Some(m23), Some(m24),
-             Some(m31), Some(m32), Some(m33), Some(m34),
-             Some(m41), Some(m42), Some(m43), Some(m44)) => {
-                Some(TypedTransform3D::row_major(m11, m12, m13, m14,
-                                                 m21, m22, m23, m24,
-                                                 m31, m32, m33, m34,
-                                                 m41, m42, m43, m44))
-            },
-            _ => None
-        }
-    }
-}
-
-impl<T, Src, Dst> fmt::Debug for TypedTransform3D<T, Src, Dst>
-where T: Copy + fmt::Debug +
-         PartialEq +
-         One + Zero {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        if self.is_identity() {
-            write!(f, "[I]")
-        } else {
-            self.to_row_major_array().fmt(f)
-        }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use approxeq::ApproxEq;
-    use transform2d::Transform2D;
-    use point::{Point2D, Point3D};
-    use Radians;
-    use super::*;
-
-    use std::f32::consts::{FRAC_PI_2, PI};
-
-    type Mf32 = Transform3D<f32>;
-
-    // For convenience.
-    fn rad(v: f32) -> Radians<f32> { Radians::new(v) }
-
-    #[test]
-    pub fn test_translation() {
-        let t1 = Mf32::create_translation(1.0, 2.0, 3.0);
-        let t2 = Mf32::identity().pre_translate(vec3(1.0, 2.0, 3.0));
-        let t3 = Mf32::identity().post_translate(vec3(1.0, 2.0, 3.0));
-        assert_eq!(t1, t2);
-        assert_eq!(t1, t3);
-
-        assert_eq!(t1.transform_point3d(&Point3D::new(1.0, 1.0, 1.0)), Point3D::new(2.0, 3.0, 4.0));
-        assert_eq!(t1.transform_point2d(&Point2D::new(1.0, 1.0)), Point2D::new(2.0, 3.0));
-
-        assert_eq!(t1.post_mul(&t1), Mf32::create_translation(2.0, 4.0, 6.0));
-
-        assert!(!t1.is_2d());
-        assert_eq!(Mf32::create_translation(1.0, 2.0, 3.0).to_2d(), Transform2D::create_translation(1.0, 2.0));
-    }
-
-    #[test]
-    pub fn test_rotation() {
-        let r1 = Mf32::create_rotation(0.0, 0.0, 1.0, rad(FRAC_PI_2));
-        let r2 = Mf32::identity().pre_rotate(0.0, 0.0, 1.0, rad(FRAC_PI_2));
-        let r3 = Mf32::identity().post_rotate(0.0, 0.0, 1.0, rad(FRAC_PI_2));
-        assert_eq!(r1, r2);
-        assert_eq!(r1, r3);
-
-        assert!(r1.transform_point3d(&Point3D::new(1.0, 2.0, 3.0)).approx_eq(&Point3D::new(2.0, -1.0, 3.0)));
-        assert!(r1.transform_point2d(&Point2D::new(1.0, 2.0)).approx_eq(&Point2D::new(2.0, -1.0)));
-
-        assert!(r1.post_mul(&r1).approx_eq(&Mf32::create_rotation(0.0, 0.0, 1.0, rad(FRAC_PI_2*2.0))));
-
-        assert!(r1.is_2d());
-        assert!(r1.to_2d().approx_eq(&Transform2D::create_rotation(rad(FRAC_PI_2))));
-    }
-
-    #[test]
-    pub fn test_scale() {
-        let s1 = Mf32::create_scale(2.0, 3.0, 4.0);
-        let s2 = Mf32::identity().pre_scale(2.0, 3.0, 4.0);
-        let s3 = Mf32::identity().post_scale(2.0, 3.0, 4.0);
-        assert_eq!(s1, s2);
-        assert_eq!(s1, s3);
-
-        assert!(s1.transform_point3d(&Point3D::new(2.0, 2.0, 2.0)).approx_eq(&Point3D::new(4.0, 6.0, 8.0)));
-        assert!(s1.transform_point2d(&Point2D::new(2.0, 2.0)).approx_eq(&Point2D::new(4.0, 6.0)));
-
-        assert_eq!(s1.post_mul(&s1), Mf32::create_scale(4.0, 9.0, 16.0));
-
-        assert!(!s1.is_2d());
-        assert_eq!(Mf32::create_scale(2.0, 3.0, 0.0).to_2d(), Transform2D::create_scale(2.0, 3.0));
-    }
-
-    #[test]
-    pub fn test_ortho() {
-        let (left, right, bottom, top) = (0.0f32, 1.0f32, 0.1f32, 1.0f32);
-        let (near, far) = (-1.0f32, 1.0f32);
-        let result = Mf32::ortho(left, right, bottom, top, near, far);
-        let expected = Mf32::row_major(
-             2.0,  0.0,         0.0, 0.0,
-             0.0,  2.22222222,  0.0, 0.0,
-             0.0,  0.0,        -1.0, 0.0,
-            -1.0, -1.22222222, -0.0, 1.0
-        );
-        debug!("result={:?} expected={:?}", result, expected);
-        assert!(result.approx_eq(&expected));
-    }
-
-    #[test]
-    pub fn test_is_2d() {
-        assert!(Mf32::identity().is_2d());
-        assert!(Mf32::create_rotation(0.0, 0.0, 1.0, rad(0.7854)).is_2d());
-        assert!(!Mf32::create_rotation(0.0, 1.0, 0.0, rad(0.7854)).is_2d());
-    }
-
-    #[test]
-    pub fn test_row_major_2d() {
-        let m1 = Mf32::row_major_2d(1.0, 2.0, 3.0, 4.0, 5.0, 6.0);
-        let m2 = Mf32::row_major(
-            1.0, 2.0, 0.0, 0.0,
-            3.0, 4.0, 0.0, 0.0,
-            0.0, 0.0, 1.0, 0.0,
-            5.0, 6.0, 0.0, 1.0
-        );
-        assert_eq!(m1, m2);
-    }
-
-    #[test]
-    fn test_column_major() {
-        assert_eq!(
-            Mf32::row_major(
-                1.0,  2.0,  3.0,  4.0,
-                5.0,  6.0,  7.0,  8.0,
-                9.0,  10.0, 11.0, 12.0,
-                13.0, 14.0, 15.0, 16.0,
-            ),
-            Mf32::column_major(
-                1.0,  5.0,  9.0,  13.0,
-                2.0,  6.0,  10.0, 14.0,
-                3.0,  7.0,  11.0, 15.0,
-                4.0,  8.0,  12.0, 16.0,
-            )
-        );
-    }
-
-    #[test]
-    pub fn test_inverse_simple() {
-        let m1 = Mf32::identity();
-        let m2 = m1.inverse().unwrap();
-        assert!(m1.approx_eq(&m2));
-    }
-
-    #[test]
-    pub fn test_inverse_scale() {
-        let m1 = Mf32::create_scale(1.5, 0.3, 2.1);
-        let m2 = m1.inverse().unwrap();
-        assert!(m1.pre_mul(&m2).approx_eq(&Mf32::identity()));
-    }
-
-    #[test]
-    pub fn test_inverse_translate() {
-        let m1 = Mf32::create_translation(-132.0, 0.3, 493.0);
-        let m2 = m1.inverse().unwrap();
-        assert!(m1.pre_mul(&m2).approx_eq(&Mf32::identity()));
-    }
-
-    #[test]
-    pub fn test_inverse_rotate() {
-        let m1 = Mf32::create_rotation(0.0, 1.0, 0.0, rad(1.57));
-        let m2 = m1.inverse().unwrap();
-        assert!(m1.pre_mul(&m2).approx_eq(&Mf32::identity()));
-    }
-
-    #[test]
-    pub fn test_inverse_transform_point_2d() {
-        let m1 = Mf32::create_translation(100.0, 200.0, 0.0);
-        let m2 = m1.inverse().unwrap();
-        assert!(m1.pre_mul(&m2).approx_eq(&Mf32::identity()));
-
-        let p1 = Point2D::new(1000.0, 2000.0);
-        let p2 = m1.transform_point2d(&p1);
-        assert!(p2.eq(&Point2D::new(1100.0, 2200.0)));
-
-        let p3 = m2.transform_point2d(&p2);
-        assert!(p3.eq(&p1));
-    }
-
-    #[test]
-    fn test_inverse_none() {
-        assert!(Mf32::create_scale(2.0, 0.0, 2.0).inverse().is_none());
-        assert!(Mf32::create_scale(2.0, 2.0, 2.0).inverse().is_some());
-    }
-
-    #[test]
-    pub fn test_pre_post() {
-        let m1 = Transform3D::identity().post_scale(1.0, 2.0, 3.0).post_translate(vec3(1.0, 2.0, 3.0));
-        let m2 = Transform3D::identity().pre_translate(vec3(1.0, 2.0, 3.0)).pre_scale(1.0, 2.0, 3.0);
-        assert!(m1.approx_eq(&m2));
-
-        let r = Mf32::create_rotation(0.0, 0.0, 1.0, rad(FRAC_PI_2));
-        let t = Mf32::create_translation(2.0, 3.0, 0.0);
-
-        let a = Point3D::new(1.0, 1.0, 1.0);
-
-        assert!(r.post_mul(&t).transform_point3d(&a).approx_eq(&Point3D::new(3.0, 2.0, 1.0)));
-        assert!(t.post_mul(&r).transform_point3d(&a).approx_eq(&Point3D::new(4.0, -3.0, 1.0)));
-        assert!(t.post_mul(&r).transform_point3d(&a).approx_eq(&r.transform_point3d(&t.transform_point3d(&a))));
-
-        assert!(r.pre_mul(&t).transform_point3d(&a).approx_eq(&Point3D::new(4.0, -3.0, 1.0)));
-        assert!(t.pre_mul(&r).transform_point3d(&a).approx_eq(&Point3D::new(3.0, 2.0, 1.0)));
-        assert!(t.pre_mul(&r).transform_point3d(&a).approx_eq(&t.transform_point3d(&r.transform_point3d(&a))));
-    }
-
-    #[test]
-    fn test_size_of() {
-        use std::mem::size_of;
-        assert_eq!(size_of::<Transform3D<f32>>(), 16*size_of::<f32>());
-        assert_eq!(size_of::<Transform3D<f64>>(), 16*size_of::<f64>());
-    }
-
-    #[test]
-    pub fn test_transform_associativity() {
-        let m1 = Mf32::row_major(3.0, 2.0, 1.5, 1.0,
-                                 0.0, 4.5, -1.0, -4.0,
-                                 0.0, 3.5, 2.5, 40.0,
-                                 0.0, 3.0, 0.0, 1.0);
-        let m2 = Mf32::row_major(1.0, -1.0, 3.0, 0.0,
-                                 -1.0, 0.5, 0.0, 2.0,
-                                 1.5, -2.0, 6.0, 0.0,
-                                 -2.5, 6.0, 1.0, 1.0);
-
-        let p = Point3D::new(1.0, 3.0, 5.0);
-        let p1 = m2.pre_mul(&m1).transform_point3d(&p);
-        let p2 = m2.transform_point3d(&m1.transform_point3d(&p));
-        assert!(p1.approx_eq(&p2));
-    }
-
-    #[test]
-    pub fn test_is_identity() {
-        let m1 = Transform3D::identity();
-        assert!(m1.is_identity());
-        let m2 = m1.post_translate(vec3(0.1, 0.0, 0.0));
-        assert!(!m2.is_identity());
-    }
-
-    #[test]
-    pub fn test_transform_vector() {
-        // Translation does not apply to vectors.
-        let m = Mf32::create_translation(1.0, 2.0, 3.0);
-        let v1 = vec3(10.0, -10.0, 3.0);
-        assert_eq!(v1, m.transform_vector3d(&v1));
-        // While it does apply to points.
-        assert!(v1.to_point() != m.transform_point3d(&v1.to_point()));
-
-        // same thing with 2d vectors/points
-        let v2 = vec2(10.0, -5.0);
-        assert_eq!(v2, m.transform_vector2d(&v2));
-        assert!(v2.to_point() != m.transform_point2d(&v2.to_point()));
-    }
-
-    #[test]
-    pub fn test_is_backface_visible() {
-        // backface is not visible for rotate-x 0 degree.
-        let r1 = Mf32::create_rotation(1.0, 0.0, 0.0, rad(0.0));
-        assert!(!r1.is_backface_visible());
-        // backface is not visible for rotate-x 45 degree.
-        let r1 = Mf32::create_rotation(1.0, 0.0, 0.0, rad(PI * 0.25));
-        assert!(!r1.is_backface_visible());
-        // backface is visible for rotate-x 180 degree.
-        let r1 = Mf32::create_rotation(1.0, 0.0, 0.0, rad(PI));
-        assert!(r1.is_backface_visible());
-        // backface is visible for rotate-x 225 degree.
-        let r1 = Mf32::create_rotation(1.0, 0.0, 0.0, rad(PI * 1.25));
-        assert!(r1.is_backface_visible());
-        // backface is not visible for non-inverseable matrix
-        let r1 = Mf32::create_scale(2.0, 0.0, 2.0);
-        assert!(!r1.is_backface_visible());
-    }
-}
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/trig.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution.
-//
-// 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.
-
-
-/// Trait for basic trigonometry functions, so they can be used on generic numeric types
-pub trait Trig {
-    fn sin(self) -> Self;
-    fn cos(self) -> Self;
-    fn tan(self) -> Self;
-}
-
-macro_rules! trig {
-    ($ty:ty) => (
-        impl Trig for $ty {
-            #[inline]
-            fn sin(self) -> $ty { self.sin() }
-            #[inline]
-            fn cos(self) -> $ty { self.cos() }
-            #[inline]
-            fn tan(self) -> $ty { self.tan() }
-        }
-    )
-}
-
-trig!(f32);
-trig!(f64);
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/vector.rs
+++ /dev/null
@@ -1,949 +0,0 @@
-// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use super::UnknownUnit;
-use approxeq::ApproxEq;
-use length::Length;
-use point::{TypedPoint2D, TypedPoint3D, point2, point3};
-use size::{TypedSize2D, size2};
-use scale_factor::ScaleFactor;
-use num::*;
-use num_traits::{Float, NumCast, Signed};
-use std::fmt;
-use std::ops::{Add, Neg, Mul, Sub, Div, AddAssign, SubAssign, MulAssign, DivAssign};
-use std::marker::PhantomData;
-
-define_matrix! {
-    /// A 2d Vector tagged with a unit.
-    pub struct TypedVector2D<T, U> {
-        pub x: T,
-        pub y: T,
-    }
-}
-
-/// Default 2d vector type with no unit.
-///
-/// `Vector2D` provides the same methods as `TypedVector2D`.
-pub type Vector2D<T> = TypedVector2D<T, UnknownUnit>;
-
-impl<T: Copy + Zero, U> TypedVector2D<T, U> {
-    /// Constructor, setting all components to zero.
-    #[inline]
-    pub fn zero() -> Self {
-        TypedVector2D::new(Zero::zero(), Zero::zero())
-    }
-
-    /// Convert into a 3d vector.
-    #[inline]
-    pub fn to_3d(&self) -> TypedVector3D<T, U> {
-        vec3(self.x, self.y, Zero::zero())
-    }
-}
-
-impl<T: fmt::Debug, U> fmt::Debug for TypedVector2D<T, U> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "({:?},{:?})", self.x, self.y)
-    }
-}
-
-impl<T: fmt::Display, U> fmt::Display for TypedVector2D<T, U> {
-    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
-        write!(formatter, "({},{})", self.x, self.y)
-    }
-}
-
-impl<T, U> TypedVector2D<T, U> {
-    /// Constructor taking scalar values directly.
-    #[inline]
-    pub fn new(x: T, y: T) -> Self {
-        TypedVector2D { x: x, y: y, _unit: PhantomData }
-    }
-}
-
-impl<T: Copy, U> TypedVector2D<T, U> {
-    /// Constructor taking properly typed Lengths instead of scalar values.
-    #[inline]
-    pub fn from_lengths(x: Length<T, U>, y: Length<T, U>) -> Self {
-        vec2(x.0, y.0)
-    }
-
-    /// Create a 3d vector from this one, using the specified z value.
-    #[inline]
-    pub fn extend(&self, z: T) -> TypedVector3D<T, U> {
-        vec3(self.x, self.y, z)
-    }
-
-    /// Cast this vector into a point.
-    ///
-    /// Equivalent to adding this vector to the origin.
-    #[inline]
-    pub fn to_point(&self) -> TypedPoint2D<T, U> {
-        point2(self.x, self.y)
-    }
-
-    /// Swap x and y.
-    #[inline]
-    pub fn yx(&self) -> Self {
-        vec2(self.y, self.x)
-    }
-
-    /// Cast this vector into a size.
-    #[inline]
-    pub fn to_size(&self) -> TypedSize2D<T, U> {
-        size2(self.x, self.y)
-    }
-
-
-    /// Returns self.x as a Length carrying the unit.
-    #[inline]
-    pub fn x_typed(&self) -> Length<T, U> { Length::new(self.x) }
-
-    /// Returns self.y as a Length carrying the unit.
-    #[inline]
-    pub fn y_typed(&self) -> Length<T, U> { Length::new(self.y) }
-
-    /// Drop the units, preserving only the numeric value.
-    #[inline]
-    pub fn to_untyped(&self) -> Vector2D<T> {
-        vec2(self.x, self.y)
-    }
-
-    /// Tag a unitless value with units.
-    #[inline]
-    pub fn from_untyped(p: &Vector2D<T>) -> Self {
-        vec2(p.x, p.y)
-    }
-
-    #[inline]
-    pub fn to_array(&self) -> [T; 2] {
-        [self.x, self.y]
-    }
-}
-
-impl<T, U> TypedVector2D<T, U>
-where T: Copy + Mul<T, Output=T> + Add<T, Output=T> + Sub<T, Output=T> {
-    /// Dot product.
-    #[inline]
-    pub fn dot(self, other: Self) -> T {
-        self.x * other.x + self.y * other.y
-    }
-
-    /// Returns the norm of the cross product [self.x, self.y, 0] x [other.x, other.y, 0]..
-    #[inline]
-    pub fn cross(self, other: Self) -> T {
-        self.x * other.y - self.y * other.x
-    }
-
-    #[inline]
-    pub fn normalize(self) -> Self where T: Float + ApproxEq<T> {
-        let dot = self.dot(self);
-        if dot.approx_eq(&T::zero()) {
-            self
-        } else {
-            self / dot.sqrt()
-        }
-    }
-
-    #[inline]
-    pub fn square_length(&self) -> T {
-        self.x * self.x + self.y * self.y
-    }
-
-    #[inline]
-    pub fn length(&self) -> T where T: Float + ApproxEq<T> {
-        self.square_length().sqrt()
-    }
-}
-
-impl<T, U> TypedVector2D<T, U>
-where T: Copy + One + Add<Output=T> + Sub<Output=T> + Mul<Output=T> {
-    /// Linearly interpolate between this vector and another vector.
-    ///
-    /// `t` is expected to be between zero and one.
-    #[inline]
-    pub fn lerp(&self, other: Self, t: T) -> Self {
-        let one_t = T::one() - t;
-        (*self) * one_t + other * t
-    }
-}
-
-impl<T: Copy + Add<T, Output=T>, U> Add for TypedVector2D<T, U> {
-    type Output = Self;
-    fn add(self, other: Self) -> Self {
-        TypedVector2D::new(self.x + other.x, self.y + other.y)
-    }
-}
-
-impl<T: Copy + Add<T, Output=T>, U> AddAssign for TypedVector2D<T, U> {
-    #[inline]
-    fn add_assign(&mut self, other: Self) {
-        *self = *self + other
-    }
-}
-
-impl<T: Copy + Sub<T, Output=T>, U> SubAssign<TypedVector2D<T, U>> for TypedVector2D<T, U> {
-    #[inline]
-    fn sub_assign(&mut self, other: Self) {
-        *self = *self - other
-    }
-}
-
-impl<T: Copy + Sub<T, Output=T>, U> Sub for TypedVector2D<T, U> {
-    type Output = Self;
-    #[inline]
-    fn sub(self, other: Self) -> Self {
-        vec2(self.x - other.x, self.y - other.y)
-    }
-}
-
-impl <T: Copy + Neg<Output=T>, U> Neg for TypedVector2D<T, U> {
-    type Output = Self;
-    #[inline]
-    fn neg(self) -> Self {
-        vec2(-self.x, -self.y)
-    }
-}
-
-impl<T: Float, U> TypedVector2D<T, U> {
-    #[inline]
-    pub fn min(self, other: Self) -> Self {
-         vec2(self.x.min(other.x), self.y.min(other.y))
-    }
-
-    #[inline]
-    pub fn max(self, other: Self) -> Self {
-        vec2(self.x.max(other.x), self.y.max(other.y))
-    }
-}
-
-impl<T: Copy + Mul<T, Output=T>, U> Mul<T> for TypedVector2D<T, U> {
-    type Output = Self;
-    #[inline]
-    fn mul(self, scale: T) -> Self {
-        vec2(self.x * scale, self.y * scale)
-    }
-}
-
-impl<T: Copy + Div<T, Output=T>, U> Div<T> for TypedVector2D<T, U> {
-    type Output = Self;
-    #[inline]
-    fn div(self, scale: T) -> Self {
-        vec2(self.x / scale, self.y / scale)
-    }
-}
-
-impl<T: Copy + Mul<T, Output=T>, U> MulAssign<T> for TypedVector2D<T, U> {
-    #[inline]
-    fn mul_assign(&mut self, scale: T) {
-        *self = *self * scale
-    }
-}
-
-impl<T: Copy + Div<T, Output=T>, U> DivAssign<T> for TypedVector2D<T, U> {
-    #[inline]
-    fn div_assign(&mut self, scale: T) {
-        *self = *self / scale
-    }
-}
-
-impl<T: Copy + Mul<T, Output=T>, U1, U2> Mul<ScaleFactor<T, U1, U2>> for TypedVector2D<T, U1> {
-    type Output = TypedVector2D<T, U2>;
-    #[inline]
-    fn mul(self, scale: ScaleFactor<T, U1, U2>) -> TypedVector2D<T, U2> {
-        vec2(self.x * scale.get(), self.y * scale.get())
-    }
-}
-
-impl<T: Copy + Div<T, Output=T>, U1, U2> Div<ScaleFactor<T, U1, U2>> for TypedVector2D<T, U2> {
-    type Output = TypedVector2D<T, U1>;
-    #[inline]
-    fn div(self, scale: ScaleFactor<T, U1, U2>) -> TypedVector2D<T, U1> {
-        vec2(self.x / scale.get(), self.y / scale.get())
-    }
-}
-
-impl<T: Round, U> TypedVector2D<T, U> {
-    /// Rounds each component to the nearest integer value.
-    ///
-    /// This behavior is preserved for negative values (unlike the basic cast).
-    /// For example `{ -0.1, -0.8 }.round() == { 0.0, -1.0 }`.
-    #[inline]
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn round(&self) -> Self {
-        vec2(self.x.round(), self.y.round())
-    }
-}
-
-impl<T: Ceil, U> TypedVector2D<T, U> {
-    /// Rounds each component to the smallest integer equal or greater than the original value.
-    ///
-    /// This behavior is preserved for negative values (unlike the basic cast).
-    /// For example `{ -0.1, -0.8 }.ceil() == { 0.0, 0.0 }`.
-    #[inline]
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn ceil(&self) -> Self {
-        vec2(self.x.ceil(), self.y.ceil())
-    }
-}
-
-impl<T: Floor, U> TypedVector2D<T, U> {
-    /// Rounds each component to the biggest integer equal or lower than the original value.
-    ///
-    /// This behavior is preserved for negative values (unlike the basic cast).
-    /// For example `{ -0.1, -0.8 }.floor() == { -1.0, -1.0 }`.
-    #[inline]
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn floor(&self) -> Self {
-        vec2(self.x.floor(), self.y.floor())
-    }
-}
-
-impl<T: NumCast + Copy, U> TypedVector2D<T, U> {
-    /// Cast from one numeric representation to another, preserving the units.
-    ///
-    /// When casting from floating vector to integer coordinates, the decimals are truncated
-    /// as one would expect from a simple cast, but this behavior does not always make sense
-    /// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting.
-    #[inline]
-    pub fn cast<NewT: NumCast + Copy>(&self) -> Option<TypedVector2D<NewT, U>> {
-        match (NumCast::from(self.x), NumCast::from(self.y)) {
-            (Some(x), Some(y)) => Some(TypedVector2D::new(x, y)),
-            _ => None
-        }
-    }
-
-    // Convenience functions for common casts
-
-    /// Cast into an `f32` vector.
-    #[inline]
-    pub fn to_f32(&self) -> TypedVector2D<f32, U> {
-        self.cast().unwrap()
-    }
-
-    /// Cast into an `usize` vector, truncating decimals if any.
-    ///
-    /// When casting from floating vector vectors, it is worth considering whether
-    /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
-    /// the desired conversion behavior.
-    #[inline]
-    pub fn to_usize(&self) -> TypedVector2D<usize, U> {
-        self.cast().unwrap()
-    }
-
-    /// Cast into an i32 vector, truncating decimals if any.
-    ///
-    /// When casting from floating vector vectors, it is worth considering whether
-    /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
-    /// the desired conversion behavior.
-    #[inline]
-    pub fn to_i32(&self) -> TypedVector2D<i32, U> {
-        self.cast().unwrap()
-    }
-
-    /// Cast into an i64 vector, truncating decimals if any.
-    ///
-    /// When casting from floating vector vectors, it is worth considering whether
-    /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
-    /// the desired conversion behavior.
-    #[inline]
-    pub fn to_i64(&self) -> TypedVector2D<i64, U> {
-        self.cast().unwrap()
-    }
-}
-
-impl<T: Copy+ApproxEq<T>, U> ApproxEq<TypedVector2D<T, U>> for TypedVector2D<T, U> {
-    #[inline]
-    fn approx_epsilon() -> Self {
-        vec2(T::approx_epsilon(), T::approx_epsilon())
-    }
-
-    #[inline]
-    fn approx_eq(&self, other: &Self) -> bool {
-        self.x.approx_eq(&other.x) && self.y.approx_eq(&other.y)
-    }
-
-    #[inline]
-    fn approx_eq_eps(&self, other: &Self, eps: &Self) -> bool {
-        self.x.approx_eq_eps(&other.x, &eps.x) && self.y.approx_eq_eps(&other.y, &eps.y)
-    }
-}
-
-impl<T: Copy, U> Into<[T; 2]> for TypedVector2D<T, U> {
-    fn into(self) -> [T; 2] {
-        self.to_array()
-    }
-}
-
-impl<T: Copy, U> From<[T; 2]> for TypedVector2D<T, U> {
-    fn from(array: [T; 2]) -> Self {
-        vec2(array[0], array[1])
-    }
-}
-
-impl<T, U> TypedVector2D<T, U>
-where T: Signed {
-    pub fn abs(&self) -> Self {
-        vec2(self.x.abs(), self.y.abs())
-    }
-}
-
-define_matrix! {
-    /// A 3d Vector tagged with a unit.
-    pub struct TypedVector3D<T, U> {
-        pub x: T,
-        pub y: T,
-        pub z: T,
-    }
-}
-
-/// Default 3d vector type with no unit.
-///
-/// `Vector3D` provides the same methods as `TypedVector3D`.
-pub type Vector3D<T> = TypedVector3D<T, UnknownUnit>;
-
-impl<T: Copy + Zero, U> TypedVector3D<T, U> {
-    /// Constructor, setting all copmonents to zero.
-    #[inline]
-    pub fn zero() -> Self {
-        vec3(Zero::zero(), Zero::zero(), Zero::zero())
-    }
-
-    #[inline]
-    pub fn to_array_4d(&self) -> [T; 4] {
-        [self.x, self.y, self.z, Zero::zero()]
-    }
-}
-
-impl<T: fmt::Debug, U> fmt::Debug for TypedVector3D<T, U> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "({:?},{:?},{:?})", self.x, self.y, self.z)
-    }
-}
-
-impl<T: fmt::Display, U> fmt::Display for TypedVector3D<T, U> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "({},{},{})", self.x, self.y, self.z)
-    }
-}
-
-impl<T, U> TypedVector3D<T, U> {
-    /// Constructor taking scalar values directly.
-    #[inline]
-    pub fn new(x: T, y: T, z: T) -> Self {
-        TypedVector3D { x: x, y: y, z: z, _unit: PhantomData }
-    }
-}
-
-impl<T: Copy, U> TypedVector3D<T, U> {
-    /// Constructor taking properly typed Lengths instead of scalar values.
-    #[inline]
-    pub fn from_lengths(x: Length<T, U>, y: Length<T, U>, z: Length<T, U>) -> TypedVector3D<T, U> {
-        vec3(x.0, y.0, z.0)
-    }
-
-    /// Cast this vector into a point.
-    ///
-    /// Equivalent to adding this vector to the origin.
-    #[inline]
-    pub fn to_point(&self) -> TypedPoint3D<T, U> {
-        point3(self.x, self.y, self.z)
-    }
-
-    /// Returns a 2d vector using this vector's x and y coordinates
-    #[inline]
-    pub fn xy(&self) -> TypedVector2D<T, U> {
-        vec2(self.x, self.y)
-    }
-
-    /// Returns a 2d vector using this vector's x and z coordinates
-    #[inline]
-    pub fn xz(&self) -> TypedVector2D<T, U> {
-        vec2(self.x, self.z)
-    }
-
-    /// Returns a 2d vector using this vector's x and z coordinates
-    #[inline]
-    pub fn yz(&self) -> TypedVector2D<T, U> {
-        vec2(self.y, self.z)
-    }
-
-    /// Returns self.x as a Length carrying the unit.
-    #[inline]
-    pub fn x_typed(&self) -> Length<T, U> { Length::new(self.x) }
-
-    /// Returns self.y as a Length carrying the unit.
-    #[inline]
-    pub fn y_typed(&self) -> Length<T, U> { Length::new(self.y) }
-
-    /// Returns self.z as a Length carrying the unit.
-    #[inline]
-    pub fn z_typed(&self) -> Length<T, U> { Length::new(self.z) }
-
-    #[inline]
-    pub fn to_array(&self) -> [T; 3] { [self.x, self.y, self.z] }
-
-    /// Drop the units, preserving only the numeric value.
-    #[inline]
-    pub fn to_untyped(&self) -> Vector3D<T> {
-        vec3(self.x, self.y, self.z)
-    }
-
-    /// Tag a unitless value with units.
-    #[inline]
-    pub fn from_untyped(p: &Vector3D<T>) -> Self {
-        vec3(p.x, p.y, p.z)
-    }
-
-    /// Convert into a 2d vector.
-    #[inline]
-    pub fn to_2d(&self) -> TypedVector2D<T, U> {
-        self.xy()
-    }
-}
-
-impl<T: Mul<T, Output=T> +
-        Add<T, Output=T> +
-        Sub<T, Output=T> +
-        Copy, U> TypedVector3D<T, U> {
-
-    // Dot product.
-    #[inline]
-    pub fn dot(self, other: Self) -> T {
-        self.x * other.x +
-        self.y * other.y +
-        self.z * other.z
-    }
-
-    // Cross product.
-    #[inline]
-    pub fn cross(self, other: Self) -> Self {
-        vec3(
-            self.y * other.z - self.z * other.y,
-            self.z * other.x - self.x * other.z,
-            self.x * other.y - self.y * other.x
-        )
-    }
-
-    #[inline]
-    pub fn normalize(self) -> Self where T: Float + ApproxEq<T> {
-        let dot = self.dot(self);
-        if dot.approx_eq(&T::zero()) {
-            self
-        } else {
-            self / dot.sqrt()
-        }
-    }
-
-    #[inline]
-    pub fn square_length(&self) -> T {
-        self.x * self.x + self.y * self.y + self.z * self.z
-    }
-
-    #[inline]
-    pub fn length(&self) -> T where T: Float + ApproxEq<T> {
-        self.square_length().sqrt()
-    }
-}
-
-impl<T, U> TypedVector3D<T, U>
-where T: Copy + One + Add<Output=T> + Sub<Output=T> + Mul<Output=T> {
-    /// Linearly interpolate between this vector and another vector.
-    ///
-    /// `t` is expected to be between zero and one.
-    #[inline]
-    pub fn lerp(&self, other: Self, t: T) -> Self {
-        let one_t = T::one() - t;
-        (*self) * one_t + other * t
-    }
-}
-
-impl<T: Copy + Add<T, Output=T>, U> Add for TypedVector3D<T, U> {
-    type Output = Self;
-    #[inline]
-    fn add(self, other: Self) -> Self {
-        vec3(self.x + other.x, self.y + other.y, self.z + other.z)
-    }
-}
-
-impl<T: Copy + Sub<T, Output=T>, U> Sub for TypedVector3D<T, U> {
-    type Output = Self;
-    #[inline]
-    fn sub(self, other: Self) -> Self {
-        vec3(self.x - other.x, self.y - other.y, self.z - other.z)
-    }
-}
-
-impl<T: Copy + Add<T, Output=T>, U> AddAssign for TypedVector3D<T, U> {
-    #[inline]
-    fn add_assign(&mut self, other: Self) {
-        *self = *self + other
-    }
-}
-
-impl<T: Copy + Sub<T, Output=T>, U> SubAssign<TypedVector3D<T, U>> for TypedVector3D<T, U> {
-    #[inline]
-    fn sub_assign(&mut self, other: Self) {
-        *self = *self - other
-    }
-}
-
-impl <T: Copy + Neg<Output=T>, U> Neg for TypedVector3D<T, U> {
-    type Output = Self;
-    #[inline]
-    fn neg(self) -> Self {
-        vec3(-self.x, -self.y, -self.z)
-    }
-}
-
-impl<T: Copy + Mul<T, Output=T>, U> Mul<T> for TypedVector3D<T, U> {
-    type Output = Self;
-    #[inline]
-    fn mul(self, scale: T) -> Self {
-        Self::new(self.x * scale, self.y * scale, self.z * scale)
-    }
-}
-
-impl<T: Copy + Div<T, Output=T>, U> Div<T> for TypedVector3D<T, U> {
-    type Output = Self;
-    #[inline]
-    fn div(self, scale: T) -> Self {
-        Self::new(self.x / scale, self.y / scale, self.z / scale)
-    }
-}
-
-impl<T: Copy + Mul<T, Output=T>, U> MulAssign<T> for TypedVector3D<T, U> {
-    #[inline]
-    fn mul_assign(&mut self, scale: T) {
-        *self = *self * scale
-    }
-}
-
-impl<T: Copy + Div<T, Output=T>, U> DivAssign<T> for TypedVector3D<T, U> {
-    #[inline]
-    fn div_assign(&mut self, scale: T) {
-        *self = *self / scale
-    }
-}
-
-impl<T: Float, U> TypedVector3D<T, U> {
-    #[inline]
-    pub fn min(self, other: Self) -> Self {
-         vec3(self.x.min(other.x), self.y.min(other.y), self.z.min(other.z))
-    }
-
-    #[inline]
-    pub fn max(self, other: Self) -> Self {
-        vec3(self.x.max(other.x), self.y.max(other.y), self.z.max(other.z))
-    }
-}
-
-impl<T: Round, U> TypedVector3D<T, U> {
-    /// Rounds each component to the nearest integer value.
-    ///
-    /// This behavior is preserved for negative values (unlike the basic cast).
-    #[inline]
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn round(&self) -> Self {
-        vec3(self.x.round(), self.y.round(), self.z.round())
-    }
-}
-
-impl<T: Ceil, U> TypedVector3D<T, U> {
-    /// Rounds each component to the smallest integer equal or greater than the original value.
-    ///
-    /// This behavior is preserved for negative values (unlike the basic cast).
-    #[inline]
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn ceil(&self) -> Self {
-        vec3(self.x.ceil(), self.y.ceil(), self.z.ceil())
-    }
-}
-
-impl<T: Floor, U> TypedVector3D<T, U> {
-    /// Rounds each component to the biggest integer equal or lower than the original value.
-    ///
-    /// This behavior is preserved for negative values (unlike the basic cast).
-    #[inline]
-    #[cfg_attr(feature = "unstable", must_use)]
-    pub fn floor(&self) -> Self {
-        vec3(self.x.floor(), self.y.floor(), self.z.floor())
-    }
-}
-
-impl<T: NumCast + Copy, U> TypedVector3D<T, U> {
-    /// Cast from one numeric representation to another, preserving the units.
-    ///
-    /// When casting from floating vector to integer coordinates, the decimals are truncated
-    /// as one would expect from a simple cast, but this behavior does not always make sense
-    /// geometrically. Consider using round(), ceil or floor() before casting.
-    #[inline]
-    pub fn cast<NewT: NumCast + Copy>(&self) -> Option<TypedVector3D<NewT, U>> {
-        match (NumCast::from(self.x),
-               NumCast::from(self.y),
-               NumCast::from(self.z)) {
-            (Some(x), Some(y), Some(z)) => Some(vec3(x, y, z)),
-            _ => None
-        }
-    }
-
-    // Convenience functions for common casts
-
-    /// Cast into an `f32` vector.
-    #[inline]
-    pub fn to_f32(&self) -> TypedVector3D<f32, U> {
-        self.cast().unwrap()
-    }
-
-    /// Cast into an `usize` vector, truncating decimals if any.
-    ///
-    /// When casting from floating vector vectors, it is worth considering whether
-    /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
-    /// the desired conversion behavior.
-    #[inline]
-    pub fn to_usize(&self) -> TypedVector3D<usize, U> {
-        self.cast().unwrap()
-    }
-
-    /// Cast into an `i32` vector, truncating decimals if any.
-    ///
-    /// When casting from floating vector vectors, it is worth considering whether
-    /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
-    /// the desired conversion behavior.
-    #[inline]
-    pub fn to_i32(&self) -> TypedVector3D<i32, U> {
-        self.cast().unwrap()
-    }
-
-    /// Cast into an `i64` vector, truncating decimals if any.
-    ///
-    /// When casting from floating vector vectors, it is worth considering whether
-    /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
-    /// the desired conversion behavior.
-    #[inline]
-    pub fn to_i64(&self) -> TypedVector3D<i64, U> {
-        self.cast().unwrap()
-    }
-}
-
-impl<T: Copy+ApproxEq<T>, U> ApproxEq<TypedVector3D<T, U>> for TypedVector3D<T, U> {
-    #[inline]
-    fn approx_epsilon() -> Self {
-        vec3(T::approx_epsilon(), T::approx_epsilon(), T::approx_epsilon())
-    }
-
-    #[inline]
-    fn approx_eq(&self, other: &Self) -> bool {
-        self.x.approx_eq(&other.x)
-            && self.y.approx_eq(&other.y)
-            && self.z.approx_eq(&other.z)
-    }
-
-    #[inline]
-    fn approx_eq_eps(&self, other: &Self, eps: &Self) -> bool {
-        self.x.approx_eq_eps(&other.x, &eps.x)
-            && self.y.approx_eq_eps(&other.y, &eps.y)
-            && self.z.approx_eq_eps(&other.z, &eps.z)
-    }
-}
-
-impl<T: Copy, U> Into<[T; 3]> for TypedVector3D<T, U> {
-    fn into(self) -> [T; 3] {
-        self.to_array()
-    }
-}
-
-impl<T: Copy, U> From<[T; 3]> for TypedVector3D<T, U> {
-    fn from(array: [T; 3]) -> Self {
-        vec3(array[0], array[1], array[2])
-    }
-}
-
-impl<T, U> TypedVector3D<T, U>
-where T: Signed {
-    pub fn abs(&self) -> Self {
-        vec3(self.x.abs(), self.y.abs(), self.z.abs())
-    }
-}
-
-/// Convenience constructor.
-#[inline]
-pub fn vec2<T, U>(x: T, y: T) -> TypedVector2D<T, U> {
-    TypedVector2D::new(x, y)
-}
-
-/// Convenience constructor.
-#[inline]
-pub fn vec3<T, U>(x: T, y: T, z: T) -> TypedVector3D<T, U> {
-    TypedVector3D::new(x, y, z)
-}
-
-#[cfg(test)]
-mod vector2d {
-    use super::{Vector2D, vec2};
-    type Vec2 = Vector2D<f32>;
-
-    #[test]
-    pub fn test_scalar_mul() {
-        let p1: Vec2 = vec2(3.0, 5.0);
-
-        let result = p1 * 5.0;
-
-        assert_eq!(result, Vector2D::new(15.0, 25.0));
-    }
-
-    #[test]
-    pub fn test_dot() {
-        let p1: Vec2 = vec2(2.0, 7.0);
-        let p2: Vec2 = vec2(13.0, 11.0);
-        assert_eq!(p1.dot(p2), 103.0);
-    }
-
-    #[test]
-    pub fn test_cross() {
-        let p1: Vec2 = vec2(4.0, 7.0);
-        let p2: Vec2 = vec2(13.0, 8.0);
-        let r = p1.cross(p2);
-        assert_eq!(r, -59.0);
-    }
-
-    #[test]
-    pub fn test_normalize() {
-        let p0: Vec2 = Vec2::zero();
-        let p1: Vec2 = vec2(4.0, 0.0);
-        let p2: Vec2 = vec2(3.0, -4.0);
-        assert_eq!(p0.normalize(), p0);
-        assert_eq!(p1.normalize(), vec2(1.0, 0.0));
-        assert_eq!(p2.normalize(), vec2(0.6, -0.8));
-    }
-
-    #[test]
-    pub fn test_min() {
-        let p1: Vec2 = vec2(1.0, 3.0);
-        let p2: Vec2 = vec2(2.0, 2.0);
-
-        let result = p1.min(p2);
-
-        assert_eq!(result, vec2(1.0, 2.0));
-    }
-
-    #[test]
-    pub fn test_max() {
-        let p1: Vec2 = vec2(1.0, 3.0);
-        let p2: Vec2 = vec2(2.0, 2.0);
-
-        let result = p1.max(p2);
-
-        assert_eq!(result, vec2(2.0, 3.0));
-    }
-}
-
-#[cfg(test)]
-mod typedvector2d {
-    use super::{TypedVector2D, Vector2D, vec2};
-    use scale_factor::ScaleFactor;
-
-    pub enum Mm {}
-    pub enum Cm {}
-
-    pub type Vector2DMm<T> = TypedVector2D<T, Mm>;
-    pub type Vector2DCm<T> = TypedVector2D<T, Cm>;
-
-    #[test]
-    pub fn test_add() {
-        let p1 = Vector2DMm::new(1.0, 2.0);
-        let p2 = Vector2DMm::new(3.0, 4.0);
-
-        let result = p1 + p2;
-
-        assert_eq!(result, vec2(4.0, 6.0));
-    }
-
-    #[test]
-    pub fn test_add_assign() {
-        let mut p1 = Vector2DMm::new(1.0, 2.0);
-        p1 += vec2(3.0, 4.0);
-
-        assert_eq!(p1, vec2(4.0, 6.0));
-    }
-
-    #[test]
-    pub fn test_scalar_mul() {
-        let p1 = Vector2DMm::new(1.0, 2.0);
-        let cm_per_mm: ScaleFactor<f32, Mm, Cm> = ScaleFactor::new(0.1);
-
-        let result: Vector2DCm<f32> = p1 * cm_per_mm;
-
-        assert_eq!(result, vec2(0.1, 0.2));
-    }
-
-    #[test]
-    pub fn test_swizzling() {
-        let p: Vector2D<i32> = vec2(1, 2);
-        assert_eq!(p.yx(), vec2(2, 1));
-    }
-}
-
-#[cfg(test)]
-mod vector3d {
-    use super::{Vector3D, vec2, vec3};
-    type Vec3 = Vector3D<f32>;
-
-    #[test]
-    pub fn test_dot() {
-        let p1: Vec3 = vec3(7.0, 21.0, 32.0);
-        let p2: Vec3 = vec3(43.0, 5.0, 16.0);
-        assert_eq!(p1.dot(p2), 918.0);
-    }
-
-    #[test]
-    pub fn test_cross() {
-        let p1: Vec3 = vec3(4.0, 7.0, 9.0);
-        let p2: Vec3 = vec3(13.0, 8.0, 3.0);
-        let p3 = p1.cross(p2);
-        assert_eq!(p3, vec3(-51.0, 105.0, -59.0));
-    }
-
-    #[test]
-    pub fn test_normalize() {
-        let p0: Vec3 = Vec3::zero();
-        let p1: Vec3 = vec3(0.0, -6.0, 0.0);
-        let p2: Vec3 = vec3(1.0, 2.0, -2.0);
-        assert_eq!(p0.normalize(), p0);
-        assert_eq!(p1.normalize(), vec3(0.0, -1.0, 0.0));
-        assert_eq!(p2.normalize(), vec3(1.0/3.0, 2.0/3.0, -2.0/3.0));
-    }
-
-    #[test]
-    pub fn test_min() {
-        let p1: Vec3 = vec3(1.0, 3.0, 5.0);
-        let p2: Vec3 = vec3(2.0, 2.0, -1.0);
-
-        let result = p1.min(p2);
-
-        assert_eq!(result, vec3(1.0, 2.0, -1.0));
-    }
-
-    #[test]
-    pub fn test_max() {
-        let p1: Vec3 = vec3(1.0, 3.0, 5.0);
-        let p2: Vec3 = vec3(2.0, 2.0, -1.0);
-
-        let result = p1.max(p2);
-
-        assert_eq!(result, vec3(2.0, 3.0, 5.0));
-    }
-
-    #[test]
-    pub fn test_swizzling() {
-        let p: Vector3D<i32> = vec3(1, 2, 3);
-        assert_eq!(p.xy(), vec2(1, 2));
-        assert_eq!(p.xz(), vec2(1, 3));
-        assert_eq!(p.yz(), vec2(2, 3));
-    }
-}
--- a/third_party/rust/plane-split/.cargo-checksum.json
+++ b/third_party/rust/plane-split/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".travis.yml":"b76d49f66f842c652d40825c67791352364a6b6bbb7d8d1009f2ac79eb413e66","Cargo.toml":"dafb727ecf8ce1c097737e0fc3c82a047591ac34c1c04362cd489c1e1fb1f91e","LICENSE":"b946744aeda89b467929585fe8eeb5461847695220c1b168fb375d8abd4ea3d0","README.md":"62f99334c17b451342fcea70eb1cc27b26612616b7c1a58fab50dd493f766f32","benches/split.rs":"dfe01759652e2098f20547e0ddcc1b2937e88c6d6ddb025353c037a46b7ef85d","src/bsp.rs":"66e1690aa8540f744ee013ac0e550ecdee84633727cb3a2d8239db3597ad25d6","src/lib.rs":"21d6135c10dd820c2b9ac484cc018e1149f2bf44c315d27134edd3ecb8a7f3d2","src/naive.rs":"444d3298224009209ae329458fe8df953193b15a04da29cdd6f498572a6471bf","tests/main.rs":"d65d7fe01ff3091a9b470a2f26b28108968ca5d32a5a14defba4336df31c7d7f","tests/split.rs":"19d5bfaaf93115ddecdac0f720893c61b2ed73a0bcb4711534ac7e4500cc06ae"},"package":"e57800a97ca52c556db6b6184a3201f05366ad5e11876f7d17e234589ca2fa26"}
\ No newline at end of file
+{"files":{".travis.yml":"b76d49f66f842c652d40825c67791352364a6b6bbb7d8d1009f2ac79eb413e66","Cargo.toml":"74145a361386c636f61349e165ef59dd1631a4a5f7e1c16c96b0163184e6ccaa","LICENSE":"b946744aeda89b467929585fe8eeb5461847695220c1b168fb375d8abd4ea3d0","README.md":"62f99334c17b451342fcea70eb1cc27b26612616b7c1a58fab50dd493f766f32","benches/split.rs":"dfe01759652e2098f20547e0ddcc1b2937e88c6d6ddb025353c037a46b7ef85d","src/bsp.rs":"66e1690aa8540f744ee013ac0e550ecdee84633727cb3a2d8239db3597ad25d6","src/lib.rs":"21d6135c10dd820c2b9ac484cc018e1149f2bf44c315d27134edd3ecb8a7f3d2","src/naive.rs":"444d3298224009209ae329458fe8df953193b15a04da29cdd6f498572a6471bf","tests/main.rs":"54104b672128ae623e1ef6000c30110c2b713482b81bc5f18ac1f86088813cb1","tests/split.rs":"67259be206c2e9eb77b0ff285dc5c5d912f7e539c15fc9e278e5ec9959bc24af"},"package":"d2adb8d1523b2ddcd98275613e9bc04eef75b47a39e252e63733a3218ae3c1b7"}
\ No newline at end of file
--- a/third_party/rust/plane-split/Cargo.toml
+++ b/third_party/rust/plane-split/Cargo.toml
@@ -1,15 +1,33 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g. crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
 [package]
 name = "plane-split"
-version = "0.6.0"
+version = "0.7.0"
+authors = ["Dzmitry Malyshau <kvark@mozilla.com>"]
 description = "Plane splitting"
-authors = ["Dzmitry Malyshau <kvark@mozilla.com>"]
+documentation = "https://docs.rs/plane-split"
+keywords = ["geometry", "math"]
 license = "MPL-2.0"
 repository = "https://github.com/kvark/plane-split"
-keywords = ["geometry", "math"]
-documentation = "https://docs.rs/plane-split"
+[dependencies.binary-space-partition]
+version = "0.1.2"
+
+[dependencies.euclid]
+version = "0.16"
 
-[dependencies]
-binary-space-partition = "0.1.2"
-euclid = "0.15"
-log = "0.3"
-num-traits = {version = "0.1.37", default-features = false}
+[dependencies.log]
+version = "0.3"
+
+[dependencies.num-traits]
+version = "0.1.37"
+default-features = false
--- a/third_party/rust/plane-split/tests/main.rs
+++ b/third_party/rust/plane-split/tests/main.rs
@@ -1,12 +1,12 @@
 extern crate euclid;
 extern crate plane_split;
 
-use euclid::{Radians, TypedRect, TypedSize2D, TypedTransform3D, point2, point3, vec3};
+use euclid::{Angle, TypedRect, TypedSize2D, TypedTransform3D, point2, point3, vec3};
 use euclid::approxeq::ApproxEq;
 use plane_split::{Intersection, Line, LineProjection, Polygon};
 
 
 #[test]
 fn line_proj_bounds() {
     assert_eq!((-5i8, 4), LineProjection { markers: [-5i8, 1, 4, 2] }.get_bounds());
     assert_eq!((1f32, 4.0), LineProjection { markers: [4f32, 3.0, 2.0, 1.0] }.get_bounds());
@@ -51,17 +51,17 @@ fn valid() {
     };
     assert!(poly_c.is_valid());
 }
 
 #[test]
 fn from_transformed_rect() {
     let rect: TypedRect<f32, ()> = TypedRect::new(point2(10.0, 10.0), TypedSize2D::new(20.0, 30.0));
     let transform: TypedTransform3D<f32, (), ()> =
-        TypedTransform3D::create_rotation(0.5f32.sqrt(), 0.0, 0.5f32.sqrt(), Radians::new(5.0))
+        TypedTransform3D::create_rotation(0.5f32.sqrt(), 0.0, 0.5f32.sqrt(), Angle::radians(5.0))
         .pre_translate(vec3(0.0, 0.0, 10.0));
     let poly = Polygon::from_transformed_rect(rect, transform, 0);
     assert!(poly.is_valid());
 }
 
 #[test]
 fn untransform_point() {
     let poly: Polygon<f32, ()> = Polygon {
--- a/third_party/rust/plane-split/tests/split.rs
+++ b/third_party/rust/plane-split/tests/split.rs
@@ -1,13 +1,13 @@
 extern crate euclid;
 extern crate plane_split;
 
 use std::f32::consts::FRAC_PI_4;
-use euclid::{Radians, TypedTransform3D, TypedRect, vec3};
+use euclid::{Angle, TypedTransform3D, TypedRect, vec3};
 use plane_split::{BspSplitter, NaiveSplitter, Polygon, Splitter, _make_grid};
 
 
 fn grid_impl(count: usize, splitter: &mut Splitter<f32, ()>) {
     let polys = _make_grid(count);
     let result = splitter.solve(&polys, vec3(0.0, 0.0, 1.0));
     assert_eq!(result.len(), count + count*count + count*count*count);
 }
@@ -20,21 +20,21 @@ fn grid_naive() {
 #[test]
 fn grid_bsp() {
     grid_impl(2, &mut BspSplitter::new());
 }
 
 
 fn sort_rotation(splitter: &mut Splitter<f32, ()>) {
     let transform0: TypedTransform3D<f32, (), ()> =
-        TypedTransform3D::create_rotation(0.0, 1.0, 0.0, Radians::new(-FRAC_PI_4));
+        TypedTransform3D::create_rotation(0.0, 1.0, 0.0, Angle::radians(-FRAC_PI_4));
     let transform1: TypedTransform3D<f32, (), ()> =
-        TypedTransform3D::create_rotation(0.0, 1.0, 0.0, Radians::new(0.0));
+        TypedTransform3D::create_rotation(0.0, 1.0, 0.0, Angle::radians(0.0));
     let transform2: TypedTransform3D<f32, (), ()> =
-        TypedTransform3D::create_rotation(0.0, 1.0, 0.0, Radians::new(FRAC_PI_4));
+        TypedTransform3D::create_rotation(0.0, 1.0, 0.0, Angle::radians(FRAC_PI_4));
 
     let rect: TypedRect<f32, ()> = euclid::rect(-10.0, -10.0, 20.0, 20.0);
     let polys = [
         Polygon::from_transformed_rect(rect, transform0, 0),
         Polygon::from_transformed_rect(rect, transform1, 1),
         Polygon::from_transformed_rect(rect, transform2, 2),
     ];
 
--- a/third_party/rust/serde/.cargo-checksum.json
+++ b/third_party/rust/serde/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"0537077146c955003ccbb274e748e727b66447fc4f07b585935a407e9ecee73a","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"eedee04bddb61e99bc816656bb3b8ae2fa50ff00045ecdb5212682f3592d9ab2","src/de/from_primitive.rs":"28ec3ab1c430cf27d632b642ccfccb6d055eeb9fb576e7e446ba24c66f507fb4","src/de/ignored_any.rs":"1b5ee592f5ae58d69e321144d4397f149c047e327529d0b880e1a5285e781a35","src/de/impls.rs":"8088c7cb2427c9c32bb7104b6d473c9242e98b630b95949543b322348dba4969","src/de/mod.rs":"761d9bd018fe75b8dbd9ec78e2882e533e2488a7cb7980805c1939143eb7a5af","src/de/utf8.rs":"956b124b7ce98353cb781b56e43a6fed2e67f1389d35b7a468d5be75b1485853","src/de/value.rs":"26eec47336c3d31ecbc2b7c131d71954a68ae62b8f13574d85d118eb69177ed1","src/export.rs":"a3e62187f57748cc12109b109cc850343adfab83b74b6b60123fd531c68d5d8d","src/lib.rs":"7659af7266821d1aca648ae48146216dfed0415f134f3989fa25a00ed6f265e2","src/macros.rs":"e1d542b1dac2c1d1f9d5ada7cc5b6639767fc67851421cc3adfb942a7cf750b6","src/private/de.rs":"598f6736d3c23b2e1481932df3636701f36cc5943428647742335081c5c7a650","src/private/macros.rs":"6861a4f332ea24d0ed5db1c28fe3105d2716523902f045c0bbbd439ebf9e44de","src/private/mod.rs":"bcd7c54838e139475c23a323678e20eccbe88c0be93f7977f7675cead4d3b6ed","src/private/ser.rs":"12e686fa3bf7f10ca21642c6308c6ef0b2158ee66ebda412b5d5c388019e7cd7","src/ser/impls.rs":"534f0f94757b0e87304bdbe6f2440b51cb4fc2933d23a62ac61b8c382d80b4c0","src/ser/impossible.rs":"35bd09bb517b28eda0048b0622eb5a0313d5aebf37c03b5a44dbca200d0a9ac8","src/ser/mod.rs":"fc6d1d8dc5e1e1459fda4349634a955c3e59a9bc6d98978be5f8a37bc9c1b02c"},"package":"c2f530d36fb84ec48fb7146936881f026cdbf4892028835fd9398475f82c1bb4"}
\ No newline at end of file
+{"files":{"Cargo.toml":"f98dcc6eedbfb307be98a2d8ca49d3cc10a76a08e7d7dfa2f6ec69987f0c679d","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"7dc6376a88195594cd6b43cb891aad10f57144ff737178b55d046aa04739b43a","src/de/from_primitive.rs":"28ec3ab1c430cf27d632b642ccfccb6d055eeb9fb576e7e446ba24c66f507fb4","src/de/ignored_any.rs":"1b5ee592f5ae58d69e321144d4397f149c047e327529d0b880e1a5285e781a35","src/de/impls.rs":"d220ded8bebc3367c3a0ac1360b59be1b435df40be65a5b688a6ba8108e96bea","src/de/mod.rs":"b8fd19e4a2d40369cb85e3ed6bc5197800c06b2271a846ed6e9b0cb7af41c5f0","src/de/utf8.rs":"956b124b7ce98353cb781b56e43a6fed2e67f1389d35b7a468d5be75b1485853","src/de/value.rs":"fe31174cc41035a1b53d4657b6cae6f3bcb660be39eccaae281a6e3705655578","src/export.rs":"7477f5bd345ca9e0b8d56bccdc62484e42a92fc6cd909bf17fb6e05cd1eb7946","src/lib.rs":"f549fbbd92b2e5e946a327eadf18216b9fe076f569bd623a32872797dc9eb4bc","src/macros.rs":"e1d542b1dac2c1d1f9d5ada7cc5b6639767fc67851421cc3adfb942a7cf750b6","src/private/de.rs":"15b82edcadaa60e748bf6ee0e0e14464cf945f39cb7493d3c1684cc34f6594b6","src/private/macros.rs":"6861a4f332ea24d0ed5db1c28fe3105d2716523902f045c0bbbd439ebf9e44de","src/private/mod.rs":"bcd7c54838e139475c23a323678e20eccbe88c0be93f7977f7675cead4d3b6ed","src/private/ser.rs":"eec5aecf077cebf4dc3fdbe83780f716bf33d311806ee59ce42a0c53c2f92211","src/ser/impls.rs":"dc5219e898d67c9422fef81d1f36d25ea92341c5ad3d976c0017886f371a8d51","src/ser/impossible.rs":"35bd09bb517b28eda0048b0622eb5a0313d5aebf37c03b5a44dbca200d0a9ac8","src/ser/mod.rs":"3d92794f13c8d90c2ebc33716bd6e4d4dde552c6f7de42dfaf9967d8a9ab7d10"},"package":null}
\ No newline at end of file
--- a/third_party/rust/serde/Cargo.toml
+++ b/third_party/rust/serde/Cargo.toml
@@ -1,45 +1,68 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g. crates.io) dependencies
-#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
 [package]
 name = "serde"
-version = "1.0.8"
+version = "1.0.23" # remember to update html_root_url
 authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
-include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
+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"]
-license = "MIT/Apache-2.0"
-repository = "https://github.com/serde-rs/serde"
-[dependencies.serde_derive]
-version = "1.0"
-optional = true
-[dev-dependencies.serde_derive]
-version = "1.0"
+readme = "README.md"
+include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
+
+[badges]
+travis-ci = { repository = "serde-rs/serde" }
+appveyor = { repository = "serde-rs/serde" }
+
+[dependencies]
+serde_derive = { version = "1.0", optional = true, path = "../serde_derive" }
+
+[dev-dependencies]
+serde_derive = { version = "1.0", path = "../serde_derive" }
+
+
+### FEATURES #################################################################
 
 [features]
-playground = ["serde_derive"]
+default = ["std"]
+
+# Re-export the derive(Serialize, Deserialize) macros. This is specifically
+# intended for library crates that provide optional Serde impls behind a Cargo
+# cfg of their own. All other crates should depend on serde_derive directly.
+#
+# Please refer to the long comment above the line `pub use serde_derive::*` in
+# src/lib.rs before enabling this feature. If you think you need this feature
+# and your use case does not precisely match the one described in the comment,
+# please open an issue to let us know about your use case.
 derive = ["serde_derive"]
+
+# Provide impls for common standard library types like Vec<T> and HashMap<K, V>.
+# Requires a dependency on the Rust standard library.
+std = []
+
+# Provide impls for types that require unstable functionality. For tracking and
+# discussion of unstable functionality please refer to this issue:
+#
+#    https://github.com/serde-rs/serde/issues/812
+unstable = []
+
+# Provide impls for types in the Rust core allocation and collections library
+# including String, Box<T>, Vec<T>, and Cow<T>. This is a subset of std but may
+# be enabled without depending on all of std.
+#
+# Requires a dependency on the unstable core allocation library:
+#
+#    https://doc.rust-lang.org/alloc/
 alloc = ["unstable"]
-unstable = []
-std = []
-collections = ["alloc"]
+
+# Opt into impls for Rc<T> and Arc<T>. Serializing and deserializing these types
+# does not preserve identity and may result in multiple copies of the same data.
+# Be sure that this is what you want before enabling this feature.
 rc = []
-default = ["std"]
-[badges.appveyor]
-repository = "serde-rs/serde"
 
-[badges.travis-ci]
-repository = "serde-rs/serde"
+# Get serde_derive picked up by the Integer 32 playground. Not public API.
+#
+#    http://play.integer32.com/
+playground = ["serde_derive"]
--- a/third_party/rust/serde/README.md
+++ b/third_party/rust/serde/README.md
@@ -15,19 +15,40 @@ You may be looking for:
 - [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
 
-<a href="http://play.integer32.com/?gist=9003c5b88c1f4989941925d7190c6eec" target="_blank">
-<img align="right" width="50" src="https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/run.png">
-</a>
+<details>
+<summary>
+Click to show Cargo.toml.
+<a href="http://play.integer32.com/?gist=9003c5b88c1f4989941925d7190c6eec" target="_blank">Run this code in the playground.</a>
+</summary>
+
+```toml
+[dependencies]
+
+# The core APIs, including the Serialize and Deserialize traits. Always
+# required when using Serde.
+serde = "1.0"
+
+# Support for #[derive(Serialize, Deserialize)]. Required if you want Serde
+# to work for structs and enums defined in your crate.
+serde_derive = "1.0"
+
+# Each data format lives in its own crate; the sample code below uses JSON
+# but you may be using a different one.
+serde_json = "1.0"
+```
+
+</details>
+<p></p>
 
 ```rust
 #[macro_use]
 extern crate serde_derive;
 
 extern crate serde;
 extern crate serde_json;
 
--- a/third_party/rust/serde/src/de/impls.rs
+++ b/third_party/rust/serde/src/de/impls.rs
@@ -6,22 +6,23 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
 use lib::*;
 
 use de::{Deserialize, Deserializer, EnumAccess, Error, SeqAccess, Unexpected, VariantAccess,
          Visitor};
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 use de::MapAccess;
 
 use de::from_primitive::FromPrimitive;
+use private::de::DeserializeFromSeed;
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 use private::de::size_hint;
 
 ////////////////////////////////////////////////////////////////////////////////
 
 struct UnitVisitor;
 
 impl<'de> Visitor<'de> for UnitVisitor {
     type Value = ();
@@ -46,16 +47,17 @@ impl<'de> Deserialize<'de> for () {
         deserializer.deserialize_unit(UnitVisitor)
     }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 struct BoolVisitor;
 
+
 impl<'de> Visitor<'de> 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>
@@ -203,20 +205,22 @@ impl<'de> Deserialize<'de> for char {
         D: Deserializer<'de>,
     {
         deserializer.deserialize_char(CharVisitor)
     }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 struct StringVisitor;
+#[cfg(any(feature = "std", feature = "alloc"))]
+struct StringFromVisitor<'a>(&'a mut String);
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 impl<'de> Visitor<'de> 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>
@@ -249,24 +253,84 @@ impl<'de> Visitor<'de> for StringVisitor
     {
         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"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, 'de> Visitor<'de> for StringFromVisitor<'a> {
+    type Value = ();
+
+    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        formatter.write_str("a string")
+    }
+
+    fn visit_str<E>(self, v: &str) -> Result<(), E>
+    where
+        E: Error,
+    {
+        self.0.clear();
+        self.0.push_str(v);
+        Ok(())
+    }
+
+    fn visit_string<E>(self, v: String) -> Result<(), E>
+    where
+        E: Error,
+    {
+        *self.0 = v;
+        Ok(())
+    }
+
+    fn visit_bytes<E>(self, v: &[u8]) -> Result<(), E>
+    where
+        E: Error,
+    {
+        match str::from_utf8(v) {
+            Ok(s) => {
+                self.0.clear();
+                self.0.push_str(s);
+                Ok(())
+            }
+            Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)),
+        }
+    }
+
+    fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<(), E>
+    where
+        E: Error,
+    {
+        match String::from_utf8(v) {
+            Ok(s) => {
+                *self.0 = s;
+                Ok(())
+            }
+            Err(e) => Err(Error::invalid_value(Unexpected::Bytes(&e.into_bytes()), &self),),
+        }
+    }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
 impl<'de> Deserialize<'de> for String {
     fn deserialize<D>(deserializer: D) -> Result<String, D::Error>
     where
         D: Deserializer<'de>,
     {
         deserializer.deserialize_string(StringVisitor)
     }
+
+    fn deserialize_from<D>(&mut self, deserializer: D) -> Result<(), D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        deserializer.deserialize_string(StringFromVisitor(self))
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 struct StrVisitor;
 
 impl<'a> Visitor<'a> for StrVisitor {
     type Value = &'a str;
@@ -395,31 +459,38 @@ impl<'de> Deserialize<'de> for CString {
     fn deserialize<D>(deserializer: D) -> Result<CString, D::Error>
     where
         D: Deserializer<'de>,
     {
         deserializer.deserialize_byte_buf(CStringVisitor)
     }
 }
 
-#[cfg(all(feature = "std", feature = "unstable"))]
-impl<'de> Deserialize<'de> for Box<CStr> {
-    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        CString::deserialize(deserializer).map(CString::into_boxed_c_str)
+macro_rules! forwarded_impl {
+    (( $($id: ident),* ), $ty: ty, $func: expr) => {
+        impl<'de $(, $id : Deserialize<'de>,)*> Deserialize<'de> for $ty {
+            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+            where
+                D: Deserializer<'de>,
+            {
+                Deserialize::deserialize(deserializer).map($func)
+            }
+        }
     }
 }
 
+#[cfg(all(feature = "std", feature = "unstable"))]
+forwarded_impl!((), Box<CStr>, CString::into_boxed_c_str);
+
 ////////////////////////////////////////////////////////////////////////////////
 
 struct OptionVisitor<T> {
     marker: PhantomData<T>,
 }
+struct OptionFromVisitor<'a, T: 'a>(&'a mut Option<T>);
 
 impl<'de, T> Visitor<'de> for OptionVisitor<T>
 where
     T: Deserialize<'de>,
 {
     type Value = Option<T>;
 
     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
@@ -446,26 +517,76 @@ where
     fn visit_some<D>(self, deserializer: D) -> Result<Option<T>, D::Error>
     where
         D: Deserializer<'de>,
     {
         T::deserialize(deserializer).map(Some)
     }
 }
 
+impl<'a, 'de, T> Visitor<'de> for OptionFromVisitor<'a, T>
+where
+    T: Deserialize<'de>,
+{
+    type Value = ();
+
+    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        formatter.write_str("option")
+    }
+
+    #[inline]
+    fn visit_unit<E>(self) -> Result<(), E>
+    where
+        E: Error,
+    {
+        *self.0 = None;
+        Ok(())
+    }
+
+    #[inline]
+    fn visit_none<E>(self) -> Result<(), E>
+    where
+        E: Error,
+    {
+        *self.0 = None;
+        Ok(())
+    }
+
+    #[inline]
+    fn visit_some<D>(self, deserializer: D) -> Result<(), D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        // The some enum's repr is opaque, so we can't play cute tricks with
+        // its tag to build this in place unconditionally.
+        //
+        // FIXME: investigate whether branching on the old value being Some to
+        // deserialize_from the value is profitable (probably data-dependent?)
+        *self.0 = try!(T::deserialize(deserializer).map(Some));
+        Ok(())
+    }
+}
+
 impl<'de, T> Deserialize<'de> for Option<T>
 where
     T: Deserialize<'de>,
 {
     fn deserialize<D>(deserializer: D) -> Result<Option<T>, D::Error>
     where
         D: Deserializer<'de>,
     {
         deserializer.deserialize_option(OptionVisitor { marker: PhantomData })
     }
+
+    fn deserialize_from<D>(&mut self, deserializer: D) -> Result<(), D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        deserializer.deserialize_option(OptionFromVisitor(self))
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 struct PhantomDataVisitor<T> {
     marker: PhantomData<T>,
 }
 
@@ -492,23 +613,25 @@ impl<'de, T> Deserialize<'de> for Phanto
     {
         let visitor = PhantomDataVisitor { marker: PhantomData };
         deserializer.deserialize_unit_struct("PhantomData", visitor)
     }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 macro_rules! seq_impl {
     (
         $ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >,
         $access:ident,
         $ctor:expr,
+        $clear:expr,
         $with_capacity:expr,
+        $reserve:expr,
         $insert:expr
     ) => {
         impl<'de, T $(, $typaram)*> Deserialize<'de> for $ty<T $(, $typaram)*>
         where
             T: Deserialize<'de> $(+ $tbound1 $(+ $tbound2)*)*,
             $($typaram: $bound1 $(+ $bound2)*,)*
         {
             fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
@@ -543,73 +666,127 @@ macro_rules! seq_impl {
 
                         Ok(values)
                     }
                 }
 
                 let visitor = SeqVisitor { marker: PhantomData };
                 deserializer.deserialize_seq(visitor)
             }
+
+            fn deserialize_from<D>(&mut self, deserializer: D) -> Result<(), D::Error>
+            where
+                D: Deserializer<'de>,
+            {
+                struct SeqVisitor<'a, T: 'a $(, $typaram: 'a)*>(&'a mut $ty<T $(, $typaram)*>);
+
+                impl<'a, 'de, T $(, $typaram)*> Visitor<'de> for SeqVisitor<'a, T $(, $typaram)*>
+                where
+                    T: Deserialize<'de> $(+ $tbound1 $(+ $tbound2)*)*,
+                    $($typaram: $bound1 $(+ $bound2)*,)*
+                {
+                    type Value = ();
+
+                    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+                        formatter.write_str("a sequence")
+                    }
+
+                    #[inline]
+                    fn visit_seq<A>(mut self, mut $access: A) -> Result<(), A::Error>
+                    where
+                        A: SeqAccess<'de>,
+                    {
+                        $clear(&mut self.0);
+                        $reserve(&mut self.0, size_hint::cautious($access.size_hint()));
+
+                        // FIXME: try to overwrite old values here? (Vec, VecDeque, LinkedList)
+                        while let Some(value) = try!($access.next_element()) {
+                            $insert(&mut self.0, value);
+                        }
+
+                        Ok(())
+                    }
+                }
+
+                deserializer.deserialize_seq(SeqVisitor(self))
+            }
         }
     }
 }
 
-#[cfg(any(feature = "std", feature = "collections"))]
+// Dummy impl of reserve
+#[cfg(any(feature = "std", feature = "alloc"))]
+fn nop_reserve<T, U>(_x: T, _y: U) { }
+
+#[cfg(any(feature = "std", feature = "alloc"))]
 seq_impl!(
     BinaryHeap<T: Ord>,
     seq,
     BinaryHeap::new(),
+    BinaryHeap::clear,
     BinaryHeap::with_capacity(size_hint::cautious(seq.size_hint())),
+    BinaryHeap::reserve,
     BinaryHeap::push);
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 seq_impl!(
     BTreeSet<T: Eq + Ord>,
     seq,
     BTreeSet::new(),
+    BTreeSet::clear,
     BTreeSet::new(),
+    nop_reserve,
     BTreeSet::insert);
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 seq_impl!(
     LinkedList<T>,
     seq,
     LinkedList::new(),
+    LinkedList::clear,
     LinkedList::new(),
+    nop_reserve,
     LinkedList::push_back);
 
 #[cfg(feature = "std")]
 seq_impl!(
     HashSet<T: Eq + Hash, S: BuildHasher + Default>,
     seq,
     HashSet::with_hasher(S::default()),
+    HashSet::clear,
     HashSet::with_capacity_and_hasher(size_hint::cautious(seq.size_hint()), S::default()),
+    HashSet::reserve,
     HashSet::insert);
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 seq_impl!(
     Vec<T>,
     seq,
     Vec::new(),
+    Vec::clear,
     Vec::with_capacity(size_hint::cautious(seq.size_hint())),
+    Vec::reserve,
     Vec::push);
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 seq_impl!(
     VecDeque<T>,
     seq,
     VecDeque::new(),
+    VecDeque::clear,
     VecDeque::with_capacity(size_hint::cautious(seq.size_hint())),
+    VecDeque::reserve,
     VecDeque::push_back);
 
 ////////////////////////////////////////////////////////////////////////////////
 
 struct ArrayVisitor<A> {
     marker: PhantomData<A>,
 }
+struct ArrayFromVisitor<'a, A: 'a>(&'a mut A);
 
 impl<A> ArrayVisitor<A> {
     fn new() -> Self {
         ArrayVisitor { marker: PhantomData }
     }
 }
 
 impl<'de, T> Visitor<'de> for ArrayVisitor<[T; 0]> {
@@ -662,26 +839,62 @@ macro_rules! array_impls {
                             None => return Err(Error::invalid_length($n, &self)),
                         };
                     )+
 
                     Ok([$($name),+])
                 }
             }
 
+            impl<'a, 'de, T> Visitor<'de> for ArrayFromVisitor<'a, [T; $len]>
+            where
+                T: Deserialize<'de>,
+            {
+                type Value = ();
+
+                fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+                    formatter.write_str(concat!("an array of length ", $len))
+                }
+
+                #[inline]
+                fn visit_seq<A>(self, mut seq: A) -> Result<(), A::Error>
+                where
+                    A: SeqAccess<'de>,
+                {
+                    let mut fail_idx = None;
+                    for (idx, dest) in self.0[..].iter_mut().enumerate() {
+                        if try!(seq.next_element_seed(DeserializeFromSeed(dest))).is_none() {
+                            fail_idx = Some(idx);
+                            break;
+                        }
+                    }
+                    if let Some(idx) = fail_idx {
+                        return Err(Error::invalid_length(idx, &self));
+                    }
+                    Ok(())
+                }
+            }
+
             impl<'de, T> Deserialize<'de> for [T; $len]
             where
                 T: Deserialize<'de>,
             {
                 fn deserialize<D>(deserializer: D) -> Result<[T; $len], D::Error>
                 where
                     D: Deserializer<'de>,
                 {
                     deserializer.deserialize_tuple($len, ArrayVisitor::<[T; $len]>::new())
                 }
+
+                fn deserialize_from<D>(&mut self, deserializer: D) -> Result<(), D::Error>
+                where
+                    D: Deserializer<'de>,
+                {
+                    deserializer.deserialize_tuple($len, ArrayFromVisitor(self))
+                }
             }
         )+
     }
 }
 
 array_impls! {
     1 => (0 a)
     2 => (0 a 1 b)
@@ -715,87 +928,114 @@ array_impls! {
     30 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o 15 p 16 q 17 r 18 s 19 t 20 u 21 v 22 w 23 x 24 y 25 z 26 aa 27 ab 28 ac 29 ad)
     31 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o 15 p 16 q 17 r 18 s 19 t 20 u 21 v 22 w 23 x 24 y 25 z 26 aa 27 ab 28 ac 29 ad 30 ae)
     32 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o 15 p 16 q 17 r 18 s 19 t 20 u 21 v 22 w 23 x 24 y 25 z 26 aa 27 ab 28 ac 29 ad 30 ae 31 af)
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 macro_rules! tuple_impls {
-    ($($len:tt $visitor:ident => ($($n:tt $name:ident)+))+) => {
+    ($($len:tt => ($($n:tt $name:ident)+))+) => {
         $(
-            struct $visitor<$($name,)+> {
-                marker: PhantomData<($($name,)+)>,
-            }
-
-            impl<$($name,)+> $visitor<$($name,)+> {
-                fn new() -> Self {
-                    $visitor { marker: PhantomData }
-                }
-            }
-
-            impl<'de, $($name: Deserialize<'de>),+> Visitor<'de> for $visitor<$($name,)+> {
-                type Value = ($($name,)+);
-
-                fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
-                    formatter.write_str(concat!("a tuple of size ", $len))
-                }
-
-                #[inline]
-                #[allow(non_snake_case)]
-                fn visit_seq<A>(self, mut seq: A) -> Result<($($name,)+), A::Error>
-                where
-                    A: SeqAccess<'de>,
-                {
-                    $(
-                        let $name = match try!(seq.next_element()) {
-                            Some(value) => value,
-                            None => return Err(Error::invalid_length($n, &self)),
-                        };
-                    )+
-
-                    Ok(($($name,)+))
-                }
-            }
-
             impl<'de, $($name: Deserialize<'de>),+> Deserialize<'de> for ($($name,)+) {
                 #[inline]
                 fn deserialize<D>(deserializer: D) -> Result<($($name,)+), D::Error>
                 where
                     D: Deserializer<'de>,
                 {
-                    deserializer.deserialize_tuple($len, $visitor::new())
+                    struct TupleVisitor<$($name,)+> {
+                        marker: PhantomData<($($name,)+)>,
+                    }
+
+                    impl<'de, $($name: Deserialize<'de>),+> Visitor<'de> for TupleVisitor<$($name,)+> {
+                        type Value = ($($name,)+);
+
+                        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+                            formatter.write_str(concat!("a tuple of size ", $len))
+                        }
+
+                        #[inline]
+                        #[allow(non_snake_case)]
+                        fn visit_seq<A>(self, mut seq: A) -> Result<($($name,)+), A::Error>
+                        where
+                            A: SeqAccess<'de>,
+                        {
+                            $(
+                                let $name = match try!(seq.next_element()) {
+                                    Some(value) => value,
+                                    None => return Err(Error::invalid_length($n, &self)),
+                                };
+                            )+
+
+                            Ok(($($name,)+))
+                        }
+                    }
+
+                    deserializer.deserialize_tuple($len, TupleVisitor { marker: PhantomData })
+                }
+
+                #[inline]
+                fn deserialize_from<D>(&mut self, deserializer: D) -> Result<(), D::Error>
+                where
+                    D: Deserializer<'de>,
+                {
+                    struct TupleVisitor<'a, $($name: 'a,)+>(&'a mut ($($name,)+));
+
+                    impl<'a, 'de, $($name: Deserialize<'de>),+> Visitor<'de> for TupleVisitor<'a, $($name,)+> {
+                        type Value = ();
+
+                        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+                            formatter.write_str(concat!("a tuple of size ", $len))
+                        }
+
+                        #[inline]
+                        #[allow(non_snake_case)]
+                        fn visit_seq<A>(self, mut seq:                                                                      A) -> Result<(), A::Error>
+                        where
+                            A: SeqAccess<'de>,
+                        {
+                            $(
+                                if try!(seq.next_element_seed(DeserializeFromSeed(&mut (self.0).$n))).is_none() {
+                                    return Err(Error::invalid_length($n, &self));
+                                }
+                            )+
+
+                            Ok(())
+                        }
+                    }
+
+                    deserializer.deserialize_tuple($len, TupleVisitor(self))
                 }
             }
         )+
     }
 }
 
 tuple_impls! {
-    1 TupleVisitor1 => (0 T0)
-    2 TupleVisitor2 => (0 T0 1 T1)
-    3 TupleVisitor3 => (0 T0 1 T1 2 T2)
-    4 TupleVisitor4 => (0 T0 1 T1 2 T2 3 T3)
-    5 TupleVisitor5 => (0 T0 1 T1 2 T2 3 T3 4 T4)
-    6 TupleVisitor6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5)
-    7 TupleVisitor7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6)
-    8 TupleVisitor8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7)
-    9 TupleVisitor9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8)
-    10 TupleVisitor10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9)
-    11 TupleVisitor11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10)
-    12 TupleVisitor12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11)
-    13 TupleVisitor13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12)
-    14 TupleVisitor14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13)
-    15 TupleVisitor15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14)
-    16 TupleVisitor16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15)
+    1  => (0 T0)
+    2  => (0 T0 1 T1)
+    3  => (0 T0 1 T1 2 T2)
+    4  => (0 T0 1 T1 2 T2 3 T3)
+    5  => (0 T0 1 T1 2 T2 3 T3 4 T4)
+    6  => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5)
+    7  => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6)
+    8  => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7)
+    9  => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8)
+    10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9)
+    11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10)
+    12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11)
+    13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12)
+    14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13)
+    15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14)
+    16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15)
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 macro_rules! map_impl {
     (
         $ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >,
         $access:ident,
         $ctor:expr,
         $with_capacity:expr
     ) => {
         impl<'de, K, V $(, $typaram)*> Deserialize<'de> for $ty<K, V $(, $typaram)*>
@@ -841,64 +1081,233 @@ macro_rules! map_impl {
 
                 let visitor = MapVisitor { marker: PhantomData };
                 deserializer.deserialize_map(visitor)
             }
         }
     }
 }
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 map_impl!(
     BTreeMap<K: Ord, V>,
     map,
     BTreeMap::new(),
     BTreeMap::new());
 
 #[cfg(feature = "std")]
 map_impl!(
     HashMap<K: Eq + Hash, V, S: BuildHasher + Default>,
     map,
     HashMap::with_hasher(S::default()),
     HashMap::with_capacity_and_hasher(size_hint::cautious(map.size_hint()), S::default()));
 
 ////////////////////////////////////////////////////////////////////////////////
 
 #[cfg(feature = "std")]
-macro_rules! parse_impl {
-    ($ty:ty) => {
+macro_rules! parse_ip_impl {
+    ($ty:ty; $size: expr) => {
         impl<'de> Deserialize<'de> for $ty {
             fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
             where
                 D: Deserializer<'de>,
             {
-                let s = try!(String::deserialize(deserializer));
-                s.parse().map_err(Error::custom)
+                if deserializer.is_human_readable() {
+                    let s = try!(String::deserialize(deserializer));
+                    s.parse().map_err(Error::custom)
+                } else {
+                    <[u8; $size]>::deserialize(deserializer).map(<$ty>::from)
+                }
+            }
+        }
+    }
+}
+
+#[cfg(feature = "std")]
+macro_rules! variant_identifier {
+    (
+        $name_kind: ident ( $($variant: ident; $bytes: expr; $index: expr),* )
+        $expecting_message: expr,
+        $variants_name: ident
+    ) => {
+        enum $name_kind {
+            $( $variant ),*
+        }
+
+        static $variants_name: &'static [&'static str] = &[ $( stringify!($variant) ),*];
+
+        impl<'de> Deserialize<'de> for $name_kind {
+            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+            where
+                D: Deserializer<'de>,
+            {
+                struct KindVisitor;
+
+                impl<'de> Visitor<'de> for KindVisitor {
+                    type Value = $name_kind;
+
+                    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+                        formatter.write_str($expecting_message)
+                    }
+
+                    fn visit_u32<E>(self, value: u32) -> Result<Self::Value, E>
+                    where
+                        E: Error,
+                    {
+                        match value {
+                            $(
+                                $index => Ok($name_kind :: $variant),
+                            )*
+                            _ => Err(Error::invalid_value(Unexpected::Unsigned(value as u64), &self),),
+                        }
+                    }
+
+                    fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
+                    where
+                        E: Error,
+                    {
+                        match value {
+                            $(
+                                stringify!($variant) => Ok($name_kind :: $variant),
+                            )*
+                            _ => Err(Error::unknown_variant(value, $variants_name)),
+                        }
+                    }
+
+                    fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
+                    where
+                        E: Error,
+                    {
+                        match value {
+                            $(
+                                $bytes => Ok($name_kind :: $variant),
+                            )*
+                            _ => {
+                                match str::from_utf8(value) {
+                                    Ok(value) => Err(Error::unknown_variant(value, $variants_name)),
+                                    Err(_) => Err(Error::invalid_value(Unexpected::Bytes(value), &self)),
+                                }
+                            }
+                        }
+                    }
+                }
+
+                deserializer.deserialize_identifier(KindVisitor)
             }
         }
     }
 }
 
 #[cfg(feature = "std")]
-parse_impl!(net::IpAddr);
+macro_rules! deserialize_enum {
+    (
+        $name: ident $name_kind: ident ( $($variant: ident; $bytes: expr; $index: expr),* )
+        $expecting_message: expr,
+        $deserializer: expr
+    ) => {
+        variant_identifier!{
+            $name_kind ( $($variant; $bytes; $index),* )
+            $expecting_message,
+            VARIANTS
+        }
+
+        struct EnumVisitor;
+        impl<'de> Visitor<'de> for EnumVisitor {
+            type Value = $name;
 
-#[cfg(feature = "std")]
-parse_impl!(net::Ipv4Addr);
+            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+                formatter.write_str(concat!("a ", stringify!($name)))
+            }
+
+
+            fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
+            where
+                A: EnumAccess<'de>,
+            {
+                match try!(data.variant()) {
+                    $(
+                        ($name_kind :: $variant, v) => v.newtype_variant().map($name :: $variant),
+                    )*
+                }
+            }
+        }
+        $deserializer.deserialize_enum(stringify!($name), VARIANTS, EnumVisitor)
+    }
+}
 
 #[cfg(feature = "std")]
-parse_impl!(net::Ipv6Addr);
+impl<'de> Deserialize<'de> for net::IpAddr {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        if deserializer.is_human_readable() {
+            let s = try!(String::deserialize(deserializer));
+            s.parse().map_err(Error::custom)
+        } else {
+            use lib::net::IpAddr;
+            deserialize_enum!{
+                IpAddr IpAddrKind (V4; b"V4"; 0, V6; b"V6"; 1)
+                "`V4` or `V6`",
+                deserializer
+            }
+        }
+    }
+}
+
+#[cfg(feature = "std")]
+parse_ip_impl!(net::Ipv4Addr; 4);
+
+#[cfg(feature = "std")]
+parse_ip_impl!(net::Ipv6Addr; 16);
 
 #[cfg(feature = "std")]
-parse_impl!(net::SocketAddr);
+macro_rules! parse_socket_impl {
+    ($ty:ty, $new: expr) => {
+        impl<'de> Deserialize<'de> for $ty {
+            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+            where
+                D: Deserializer<'de>,
+            {
+                if deserializer.is_human_readable() {
+                    let s = try!(String::deserialize(deserializer));
+                    s.parse().map_err(Error::custom)
+                } else {
+                    <(_, u16)>::deserialize(deserializer).map(|(ip, port)| $new(ip, port))
+                }
+            }
+        }
+    }
+}
 
 #[cfg(feature = "std")]
-parse_impl!(net::SocketAddrV4);
+impl<'de> Deserialize<'de> for net::SocketAddr {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        if deserializer.is_human_readable() {
+            let s = try!(String::deserialize(deserializer));
+            s.parse().map_err(Error::custom)
+        } else {
+            use lib::net::SocketAddr;
+            deserialize_enum!{
+                SocketAddr SocketAddrKind (V4; b"V4"; 0, V6; b"V6"; 1)
+                "`V4` or `V6`",
+                deserializer
+            }
+        }
+    }
+}
 
 #[cfg(feature = "std")]
-parse_impl!(net::SocketAddrV6);
+parse_socket_impl!(net::SocketAddrV4, net::SocketAddrV4::new);
+
+#[cfg(feature = "std")]
+parse_socket_impl!(net::SocketAddrV6, |ip, port| net::SocketAddrV6::new(ip, port, 0, 0));
 
 ////////////////////////////////////////////////////////////////////////////////
 
 #[cfg(feature = "std")]
 struct PathVisitor;
 
 #[cfg(feature = "std")]
 impl<'a> Visitor<'a> for PathVisitor {
@@ -973,80 +1382,20 @@ impl<'de> Deserialize<'de> for PathBuf {
 
 ////////////////////////////////////////////////////////////////////////////////
 
 // If this were outside of the serde crate, it would just use:
 //
 //    #[derive(Deserialize)]
 //    #[serde(variant_identifier)]
 #[cfg(all(feature = "std", any(unix, windows)))]
-enum OsStringKind {
-    Unix,
-    Windows,
-}
-
-#[cfg(all(feature = "std", any(unix, windows)))]
-static OSSTR_VARIANTS: &'static [&'static str] = &["Unix", "Windows"];
-
-#[cfg(all(feature = "std", any(unix, windows)))]
-impl<'de> Deserialize<'de> for OsStringKind {
-    fn deserialize<D>(deserializer: D) -> Result<OsStringKind, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        struct KindVisitor;
-
-        impl<'de> Visitor<'de> for KindVisitor {
-            type Value = OsStringKind;
-
-            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
-                formatter.write_str("`Unix` or `Windows`")
-            }
-
-            fn visit_u32<E>(self, value: u32) -> Result<OsStringKind, E>
-            where
-                E: Error,
-            {
-                match value {
-                    0 => Ok(OsStringKind::Unix),
-                    1 => Ok(OsStringKind::Windows),
-                    _ => Err(Error::invalid_value(Unexpected::Unsigned(value as u64), &self),),
-                }
-            }
-
-            fn visit_str<E>(self, value: &str) -> Result<OsStringKind, E>
-            where
-                E: Error,
-            {
-                match value {
-                    "Unix" => Ok(OsStringKind::Unix),
-                    "Windows" => Ok(OsStringKind::Windows),
-                    _ => Err(Error::unknown_variant(value, OSSTR_VARIANTS)),
-                }
-            }
-
-            fn visit_bytes<E>(self, value: &[u8]) -> Result<OsStringKind, E>
-            where
-                E: Error,
-            {
-                match value {
-                    b"Unix" => Ok(OsStringKind::Unix),
-                    b"Windows" => Ok(OsStringKind::Windows),
-                    _ => {
-                        match str::from_utf8(value) {
-                            Ok(value) => Err(Error::unknown_variant(value, OSSTR_VARIANTS)),
-                            Err(_) => Err(Error::invalid_value(Unexpected::Bytes(value), &self)),
-                        }
-                    }
-                }
-            }
-        }
-
-        deserializer.deserialize_identifier(KindVisitor)
-    }
+variant_identifier!{
+    OsStringKind (Unix; b"Unix"; 0, Windows; b"Windows"; 1)
+    "`Unix` or `Windows`",
+    OSSTR_VARIANTS
 }
 
 #[cfg(all(feature = "std", any(unix, windows)))]
 struct OsStringVisitor;
 
 #[cfg(all(feature = "std", any(unix, windows)))]
 impl<'de> Visitor<'de> for OsStringVisitor {
     type Value = OsString;
@@ -1093,143 +1442,91 @@ impl<'de> Deserialize<'de> for OsString 
     {
         deserializer.deserialize_enum("OsString", OSSTR_VARIANTS, OsStringVisitor)
     }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 #[cfg(any(feature = "std", feature = "alloc"))]
-impl<'de, T> Deserialize<'de> for Box<T>
-where
-    T: Deserialize<'de>,
-{
-    fn deserialize<D>(deserializer: D) -> Result<Box<T>, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        T::deserialize(deserializer).map(Box::new)
-    }
-}
+forwarded_impl!((T), Box<T>, Box::new);
 
-#[cfg(any(feature = "std", feature = "collections"))]
-impl<'de, T> Deserialize<'de> for Box<[T]>
-where
-    T: Deserialize<'de>,
-{
-    fn deserialize<D>(deserializer: D) -> Result<Box<[T]>, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        Vec::<T>::deserialize(deserializer).map(Vec::into_boxed_slice)
-    }
-}
+#[cfg(any(feature = "std", feature = "alloc"))]
+forwarded_impl!((T), Box<[T]>, Vec::into_boxed_slice);
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+forwarded_impl!((), Box<str>, String::into_boxed_str);
 
-#[cfg(any(feature = "std", feature = "collections"))]
-impl<'de> Deserialize<'de> for Box<str> {
-    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        String::deserialize(deserializer).map(String::into_boxed_str)
-    }
-}
+#[cfg(all(not(feature = "unstable"), feature = "rc", any(feature = "std", feature = "alloc")))]
+forwarded_impl!((T), Arc<T>, Arc::new);
 
-#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
-impl<'de, T> Deserialize<'de> for Arc<T>
-where
-    T: Deserialize<'de>,
-{
-    fn deserialize<D>(deserializer: D) -> Result<Arc<T>, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        T::deserialize(deserializer).map(Arc::new)
-    }
-}
+#[cfg(all(not(feature = "unstable"), feature = "rc", any(feature = "std", feature = "alloc")))]
+forwarded_impl!((T), Rc<T>, Rc::new);
 
-#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
-impl<'de, T> Deserialize<'de> for Rc<T>
-where
-    T: Deserialize<'de>,
-{
-    fn deserialize<D>(deserializer: D) -> Result<Rc<T>, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        T::deserialize(deserializer).map(Rc::new)
-    }
-}
-
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 impl<'de, 'a, T: ?Sized> Deserialize<'de> for Cow<'a, T>
 where
     T: ToOwned,
     T::Owned: Deserialize<'de>,
 {
     #[inline]
     fn deserialize<D>(deserializer: D) -> Result<Cow<'a, T>, D::Error>
     where
         D: Deserializer<'de>,
     {
         T::Owned::deserialize(deserializer).map(Cow::Owned)
     }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
+#[cfg(all(feature = "unstable", feature = "rc", any(feature = "std", feature = "alloc")))]
+macro_rules! box_forwarded_impl {
+    ($t:ident) => {
+        impl<'de, T: ?Sized> Deserialize<'de> for $t<T>
+        where
+            Box<T>: Deserialize<'de>,
+        {
+            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+            where
+                D: Deserializer<'de>,
+            {
+                Box::deserialize(deserializer).map(Into::into)
+            }
+        }
+    }
+}
+
+#[cfg(all(feature = "unstable", feature = "rc", any(feature = "std", feature = "alloc")))]
+box_forwarded_impl!(Rc);
+
+#[cfg(all(feature = "unstable", feature = "rc", any(feature = "std", feature = "alloc")))]
+box_forwarded_impl!(Arc);
+
+////////////////////////////////////////////////////////////////////////////////
+
 impl<'de, T> Deserialize<'de> for Cell<T>
 where
     T: Deserialize<'de> + Copy,
 {
     fn deserialize<D>(deserializer: D) -> Result<Cell<T>, D::Error>
     where
         D: Deserializer<'de>,
     {
         T::deserialize(deserializer).map(Cell::new)
     }
 }
 
-impl<'de, T> Deserialize<'de> for RefCell<T>
-where
-    T: Deserialize<'de>,
-{
-    fn deserialize<D>(deserializer: D) -> Result<RefCell<T>, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        T::deserialize(deserializer).map(RefCell::new)
-    }
-}
+forwarded_impl!((T), RefCell<T>, RefCell::new);
 
 #[cfg(feature = "std")]
-impl<'de, T> Deserialize<'de> for Mutex<T>
-where
-    T: Deserialize<'de>,
-{
-    fn deserialize<D>(deserializer: D) -> Result<Mutex<T>, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        T::deserialize(deserializer).map(Mutex::new)
-    }
-}
+forwarded_impl!((T), Mutex<T>, Mutex::new);
 
 #[cfg(feature = "std")]
-impl<'de, T> Deserialize<'de> for RwLock<T>
-where
-    T: Deserialize<'de>,
-{
-    fn deserialize<D>(deserializer: D) -> Result<RwLock<T>, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        T::deserialize(deserializer).map(RwLock::new)
-    }
-}
+forwarded_impl!((T), RwLock<T>, RwLock::new);
 
 ////////////////////////////////////////////////////////////////////////////////
 
 // This is a cleaned-up version of the impl generated by:
 //
 //     #[derive(Deserialize)]
 //     #[serde(deny_unknown_fields)]
 //     struct Duration {
@@ -1359,16 +1656,142 @@ impl<'de> Deserialize<'de> for Duration 
 
         const FIELDS: &'static [&'static str] = &["secs", "nanos"];
         deserializer.deserialize_struct("Duration", FIELDS, DurationVisitor)
     }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
+#[cfg(feature = "std")]
+impl<'de> Deserialize<'de> for SystemTime {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        // Reuse duration
+        enum Field {
+            Secs,
+            Nanos,
+        };
+
+        impl<'de> Deserialize<'de> for Field {
+            fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
+            where
+                D: Deserializer<'de>,
+            {
+                struct FieldVisitor;
+
+                impl<'de> Visitor<'de> for FieldVisitor {
+                    type Value = Field;
+
+                    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+                        formatter.write_str("`secs_since_epoch` or `nanos_since_epoch`")
+                    }
+
+                    fn visit_str<E>(self, value: &str) -> Result<Field, E>
+                    where
+                        E: Error,
+                    {
+                        match value {
+                            "secs_since_epoch" => Ok(Field::Secs),
+                            "nanos_since_epoch" => Ok(Field::Nanos),
+                            _ => Err(Error::unknown_field(value, FIELDS)),
+                        }
+                    }
+
+                    fn visit_bytes<E>(self, value: &[u8]) -> Result<Field, E>
+                    where
+                        E: Error,
+                    {
+                        match value {
+                            b"secs_since_epoch" => Ok(Field::Secs),
+                            b"nanos_since_epoch" => Ok(Field::Nanos),
+                            _ => {
+                                let value = String::from_utf8_lossy(value);
+                                Err(Error::unknown_field(&value, FIELDS))
+                            }
+                        }
+                    }
+                }
+
+                deserializer.deserialize_identifier(FieldVisitor)
+            }
+        }
+
+        struct DurationVisitor;
+
+        impl<'de> Visitor<'de> for DurationVisitor {
+            type Value = Duration;
+
+            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+                formatter.write_str("struct SystemTime")
+            }
+
+            fn visit_seq<A>(self, mut seq: A) -> Result<Duration, A::Error>
+            where
+                A: SeqAccess<'de>,
+            {
+                let secs: u64 = match try!(seq.next_element()) {
+                    Some(value) => value,
+                    None => {
+                        return Err(Error::invalid_length(0, &self));
+                    }
+                };
+                let nanos: u32 = match try!(seq.next_element()) {
+                    Some(value) => value,
+                    None => {
+                        return Err(Error::invalid_length(1, &self));
+                    }
+                };
+                Ok(Duration::new(secs, nanos))
+            }
+
+            fn visit_map<A>(self, mut map: A) -> Result<Duration, A::Error>
+            where
+                A: MapAccess<'de>,
+            {
+                let mut secs: Option<u64> = None;
+                let mut nanos: Option<u32> = None;
+                while let Some(key) = try!(map.next_key()) {
+                    match key {
+                        Field::Secs => {
+                            if secs.is_some() {
+                                return Err(<A::Error as Error>::duplicate_field("secs_since_epoch"));
+                            }
+                            secs = Some(try!(map.next_value()));
+                        }
+                        Field::Nanos => {
+                            if nanos.is_some() {
+                                return Err(<A::Error as Error>::duplicate_field("nanos_since_epoch"));
+                            }
+                            nanos = Some(try!(map.next_value()));
+                        }
+                    }
+                }
+                let secs = match secs {
+                    Some(secs) => secs,
+                    None => return Err(<A::Error as Error>::missing_field("secs_since_epoch")),
+                };
+                let nanos = match nanos {
+                    Some(nanos) => nanos,
+                    None => return Err(<A::Error as Error>::missing_field("nanos_since_epoch")),
+                };
+                Ok(Duration::new(secs, nanos))
+            }
+        }
+
+        const FIELDS: &'static [&'static str] = &["secs_since_epoch", "nanos_since_epoch"];
+        let duration = try!(deserializer.deserialize_struct("SystemTime", FIELDS, DurationVisitor));
+        Ok(UNIX_EPOCH + duration)
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
 // Similar to:
 //
 //     #[derive(Deserialize)]
 //     #[serde(deny_unknown_fields)]
 //     struct Range {
 //         start: u64,
 //         end: u32,
 //     }
@@ -1513,24 +1936,19 @@ impl<'de, T> Deserialize<'de> for NonZer
 where
     T: Deserialize<'de> + Zeroable,
 {
     fn deserialize<D>(deserializer: D) -> Result<NonZero<T>, D::Error>
     where
         D: Deserializer<'de>,
     {
         let value = try!(Deserialize::deserialize(deserializer));
-        unsafe {
-            let ptr = &value as *const T as *const u8;
-            if slice::from_raw_parts(ptr, mem::size_of::<T>()).iter().all(|&b| b == 0) {
-                return Err(Error::custom("expected a non-zero value"));
-            }
-            // Waiting for a safe way to construct NonZero<T>:
-            // https://github.com/rust-lang/rust/issues/27730#issuecomment-269726075
-            Ok(NonZero::new(value))
+        match NonZero::new(value) {
+            Some(nonzero) => Ok(nonzero),
+            None => Err(Error::custom("expected a non-zero value")),
         }
     }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 impl<'de, T, E> Deserialize<'de> for Result<T, E>
 where
@@ -1636,8 +2054,23 @@ where
             }
         }
 
         const VARIANTS: &'static [&'static str] = &["Ok", "Err"];
 
         deserializer.deserialize_enum("Result", VARIANTS, ResultVisitor(PhantomData))
     }
 }
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(feature = "std")]
+impl<'de, T> Deserialize<'de> for Wrapping<T>
+where
+    T: Deserialize<'de>
+{
+    fn deserialize<D>(deserializer: D) -> Result<Wrapping<T>, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        Deserialize::deserialize(deserializer).map(Wrapping)
+    }
+}
--- a/third_party/rust/serde/src/de/mod.rs
+++ b/third_party/rust/serde/src/de/mod.rs
@@ -89,16 +89,17 @@
 //!    - &str
 //!    - &[u8]
 //!  - **FFI types**:
 //!    - CString
 //!    - Box\<CStr\>
 //!    - OsString
 //!  - **Miscellaneous standard library types**:
 //!    - Duration
+//!    - SystemTime
 //!    - Path
 //!    - PathBuf
 //!    - Range\<T\>
 //!    - NonZero\<T\> (unstable)
 //!  - **Net types**:
 //!    - IpAddr
 //!    - Ipv4Addr
 //!    - Ipv6Addr
@@ -498,16 +499,45 @@ pub trait Deserialize<'de>: Sized {
     ///
     /// 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<'de>;
+
+    /// Deserializes a value into `self` from the given Deserializer.
+    ///
+    /// The purpose of this method is to allow the deserializer to reuse
+    /// resources and avoid copies. As such, if this method returns an error,
+    /// `self` will be in an indeterminate state where some parts of the struct
+    /// have been overwritten. Although whatever state that is will be
+    /// memory-safe.
+    ///
+    /// This is generally useful when repeateadly deserializing values that
+    /// are processed one at a time, where the value of `self` doesn't matter
+    /// when the next deserialization occurs.
+    ///
+    /// If you manually implement this, your recursive deserializations should
+    /// use `deserialize_from`.
+    ///
+    /// TODO: example
+    ///
+    /// ```
+    /// // Something with a loop that returns on error.
+    ///
+    /// ```
+    fn deserialize_from<D>(&mut self, deserializer: D) -> Result<(), D::Error>
+        where D: Deserializer<'de>
+    {
+        // Default implementation just delegates to `deserialize` impl.
+        *self = Deserialize::deserialize(deserializer)?;
+        Ok(())
+    }
 }
 
 /// A data structure that can be deserialized without borrowing any data from
 /// the deserializer.
 ///
 /// This is primarily useful for trait bounds on functions. For example a
 /// `from_str` function may be able to deserialize a data structure that borrows
 /// from the input string, but a `from_reader` function may only deserialize
@@ -1005,16 +1035,84 @@ pub trait Deserializer<'de>: Sized {
 
     /// 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<'de>;
+
+    /// Determine whether `Deserialize` implementations should expect to
+    /// deserialize their human-readable form.
+    ///
+    /// Some types have a human-readable form that may be somewhat expensive to
+    /// construct, as well as a binary form that is compact and efficient.
+    /// Generally text-based formats like JSON and YAML will prefer to use the
+    /// human-readable one and binary formats like Bincode will prefer the
+    /// compact one.
+    ///
+    /// ```
+    /// # use std::ops::Add;
+    /// # use std::str::FromStr;
+    /// #
+    /// # struct Timestamp;
+    /// #
+    /// # impl Timestamp {
+    /// #     const EPOCH: Timestamp = Timestamp;
+    /// # }
+    /// #
+    /// # impl FromStr for Timestamp {
+    /// #     type Err = String;
+    /// #     fn from_str(_: &str) -> Result<Self, Self::Err> {
+    /// #         unimplemented!()
+    /// #     }
+    /// # }
+    /// #
+    /// # struct Duration;
+    /// #
+    /// # impl Duration {
+    /// #     fn seconds(_: u64) -> Self { unimplemented!() }
+    /// # }
+    /// #
+    /// # impl Add<Duration> for Timestamp {
+    /// #     type Output = Timestamp;
+    /// #     fn add(self, _: Duration) -> Self::Output {
+    /// #         unimplemented!()
+    /// #     }
+    /// # }
+    /// #
+    /// use serde::de::{self, Deserialize, Deserializer};
+    ///
+    /// impl<'de> Deserialize<'de> for Timestamp {
+    ///     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    ///         where D: Deserializer<'de>
+    ///     {
+    ///         if deserializer.is_human_readable() {
+    ///             // Deserialize from a human-readable string like "2015-05-15T17:01:00Z".
+    ///             let s = String::deserialize(deserializer)?;
+    ///             Timestamp::from_str(&s).map_err(de::Error::custom)
+    ///         } else {
+    ///             // Deserialize from a compact binary representation, seconds since
+    ///             // the Unix epoch.
+    ///             let n = u64::deserialize(deserializer)?;
+    ///             Ok(Timestamp::EPOCH + Duration::seconds(n))
+    ///         }
+    ///     }
+    /// }
+    /// ```
+    ///
+    /// The default implementation of this method returns `true`. Data formats
+    /// may override this to `false` to request a compact form for types that
+    /// support one. Note that modifying this method to change a format from
+    /// human-readable to compact or vice versa should be regarded as a breaking
+    /// change, as a value serialized in human-readable mode is not required to
+    /// deserialize from the same data in compact mode.
+    #[inline]
+    fn is_human_readable(&self) -> bool { true }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 /// This trait represents a visitor that walks through a deserializer.
 ///
 /// ```rust
 /// # use std::fmt;
@@ -1114,17 +1212,17 @@ pub trait Visitor<'de>: Sized {
     /// [`visit_i64`]: #method.visit_i64
     fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
     where
         E: Error,
     {
         self.visit_i64(v as i64)
     }
 
-    /// The input contains an `i32`.
+    /// The input contains an `i64`.
     ///
     /// The default implementation fails with a type error.
     fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
     where
         E: Error,
     {
         Err(Error::invalid_type(Unexpected::Signed(v), &self))
     }
@@ -1257,17 +1355,17 @@ pub trait Visitor<'de>: Sized {
     /// will honor such a request.
     ///
     /// 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"))]
+    #[cfg(any(feature = "std", feature = "alloc"))]
     fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
     where
         E: Error,
     {
         self.visit_str(&v)
     }
 
     /// The input contains a byte array. The lifetime of the byte array is
@@ -1316,17 +1414,17 @@ pub trait Visitor<'de>: Sized {
     /// `Deserializer::deserialize_bytes`, although not every deserializer will
     /// honor such a request.
     ///
     /// 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"))]
+    #[cfg(any(feature = "std", feature = "alloc"))]
     fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
     where
         E: Error,
     {
         self.visit_bytes(&v)
     }
 
     /// The input contains an optional that is absent.
@@ -1418,17 +1516,17 @@ pub trait SeqAccess<'de> {
     /// The error type that can be returned if some error occurs during
     /// deserialization.
     type Error: Error;
 
     /// This returns `Ok(Some(value))` for the next value in the sequence, or
     /// `Ok(None)` if there are no more remaining items.
     ///
     /// `Deserialize` implementations should typically use
-    /// `SeqAcccess::next_element` instead.
+    /// `SeqAccess::next_element` instead.
     fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
     where
         T: DeserializeSeed<'de>;
 
     /// This returns `Ok(Some(value))` for the next value in the sequence, or
     /// `Ok(None)` if there are no more remaining items.
     ///
     /// This method exists as a convenience for `Deserialize` implementations.
--- a/third_party/rust/serde/src/de/value.rs
+++ b/third_party/rust/serde/src/de/value.rs
@@ -46,31 +46,31 @@ use self::private::{First, Second};
 
 /// A minimal representation of all possible errors that can occur using the
 /// `IntoDeserializer` trait.
 #[derive(Clone, Debug, PartialEq)]
 pub struct Error {
     err: ErrorImpl,
 }
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 type ErrorImpl = Box<str>;
-#[cfg(not(any(feature = "std", feature = "collections")))]
+#[cfg(not(any(feature = "std", feature = "alloc")))]
 type ErrorImpl = ();
 
 impl de::Error for Error {
-    #[cfg(any(feature = "std", feature = "collections"))]
+    #[cfg(any(feature = "std", feature = "alloc"))]
     fn custom<T>(msg: T) -> Self
     where
         T: Display,
     {
         Error { err: msg.to_string().into_boxed_str() }
     }
 
-    #[cfg(not(any(feature = "std", feature = "collections")))]
+    #[cfg(not(any(feature = "std", feature = "alloc")))]
     fn custom<T>(msg: T) -> Self
     where
         T: Display,
     {
         let _ = msg;
         Error { err: () }
     }
 }
@@ -80,22 +80,22 @@ impl ser::Error for Error {
     where
         T: Display,
     {
         de::Error::custom(msg)
     }
 }
 
 impl Display for Error {
-    #[cfg(any(feature = "std", feature = "collections"))]
+    #[cfg(any(feature = "std", feature = "alloc"))]
     fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
         formatter.write_str(&self.err)
     }
 
-    #[cfg(not(any(feature = "std", feature = "collections")))]
+    #[cfg(not(any(feature = "std", feature = "alloc")))]
     fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
         formatter.write_str("Serde deserialization error")
     }
 }
 
 #[cfg(feature = "std")]
 impl error::Error for Error {
     fn description(&self) -> &str {
@@ -420,39 +420,39 @@ where
     {
         seed.deserialize(self).map(private::unit_only)
     }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 /// A deserializer holding a `String`.
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 #[derive(Clone, Debug)]
 pub struct StringDeserializer<E> {
     value: String,
     marker: PhantomData<E>,
 }
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 impl<'de, E> IntoDeserializer<'de, E> for String
 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"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 impl<'de, E> de::Deserializer<'de> for StringDeserializer<E>
 where
     E: de::Error,
 {
     type Error = E;
 
     fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
     where
@@ -477,17 +477,17 @@ where
 
     forward_to_deserialize_any! {
         bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
         byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct
         map struct identifier ignored_any
     }
 }
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 impl<'de, 'a, E> de::EnumAccess<'de> for StringDeserializer<E>
 where
     E: de::Error,
 {
     type Error = E;
     type Variant = private::UnitOnly<E>;
 
     fn variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
@@ -496,39 +496,39 @@ where
     {
         seed.deserialize(self).map(private::unit_only)
     }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 /// A deserializer holding a `Cow<str>`.
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 #[derive(Clone, Debug)]
 pub struct CowStrDeserializer<'a, E> {
     value: Cow<'a, str>,
     marker: PhantomData<E>,
 }
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 impl<'de, 'a, E> IntoDeserializer<'de, E> for Cow<'a, str>
 where
     E: de::Error,
 {
     type Deserializer = CowStrDeserializer<'a, E>;
 
     fn into_deserializer(self) -> CowStrDeserializer<'a, E> {
         CowStrDeserializer {
             value: self,
             marker: PhantomData,
         }
     }
 }
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 impl<'de, 'a, E> de::Deserializer<'de> for CowStrDeserializer<'a, E>
 where
     E: de::Error,
 {
     type Error = E;
 
     fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
     where
@@ -556,17 +556,17 @@ where
 
     forward_to_deserialize_any! {
         bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
         byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct
         map struct identifier ignored_any
     }
 }
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 impl<'de, 'a, E> de::EnumAccess<'de> for CowStrDeserializer<'a, E>
 where
     E: de::Error,
 {
     type Error = E;
     type Variant = private::UnitOnly<E>;
 
     fn variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
@@ -722,49 +722,50 @@ impl Expected for ExpectedInSeq {
         } else {
             write!(formatter, "{} elements in sequence", self.0)
         }
     }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 impl<'de, T, E> IntoDeserializer<'de, E> for Vec<T>
 where
     T: IntoDeserializer<'de, E>,
     E: de::Error,
 {
-    type Deserializer = SeqDeserializer<<Vec<T> as IntoIterator>::IntoIter, E>;
+    type Deserializer = SeqDeserializer<<Self as IntoIterator>::IntoIter, E>;
 
     fn into_deserializer(self) -> Self::Deserializer {
         SeqDeserializer::new(self.into_iter())
     }
 }
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 impl<'de, T, E> IntoDeserializer<'de, E> for BTreeSet<T>
 where
     T: IntoDeserializer<'de, E> + Eq + Ord,
     E: de::Error,
 {
-    type Deserializer = SeqDeserializer<<BTreeSet<T> as IntoIterator>::IntoIter, E>;
+    type Deserializer = SeqDeserializer<<Self as IntoIterator>::IntoIter, E>;
 
     fn into_deserializer(self) -> Self::Deserializer {
         SeqDeserializer::new(self.into_iter())
     }
 }
 
 #[cfg(feature = "std")]
-impl<'de, T, E> IntoDeserializer<'de, E> for HashSet<T>
+impl<'de, T, S, E> IntoDeserializer<'de, E> for HashSet<T, S>
 where
     T: IntoDeserializer<'de, E> + Eq + Hash,
+    S: BuildHasher,
     E: de::Error,
 {
-    type Deserializer = SeqDeserializer<<HashSet<T> as IntoIterator>::IntoIter, E>;
+    type Deserializer = SeqDeserializer<<Self as IntoIterator>::IntoIter, E>;
 
     fn into_deserializer(self) -> Self::Deserializer {
         SeqDeserializer::new(self.into_iter())
     }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -1140,38 +1141,39 @@ impl Expected for ExpectedInMap {
         } else {
             write!(formatter, "{} elements in map", self.0)
         }
     }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 impl<'de, K, V, E> IntoDeserializer<'de, E> for BTreeMap<K, V>
 where
     K: IntoDeserializer<'de, E> + Eq + Ord,
     V: IntoDeserializer<'de, E>,
     E: de::Error,
 {
-    type Deserializer = MapDeserializer<'de, <BTreeMap<K, V> as IntoIterator>::IntoIter, E>;
+    type Deserializer = MapDeserializer<'de, <Self as IntoIterator>::IntoIter, E>;
 
     fn into_deserializer(self) -> Self::Deserializer {
         MapDeserializer::new(self.into_iter())
     }
 }
 
 #[cfg(feature = "std")]
-impl<'de, K, V, E> IntoDeserializer<'de, E> for HashMap<K, V>
+impl<'de, K, V, S, E> IntoDeserializer<'de, E> for HashMap<K, V, S>
 where
     K: IntoDeserializer<'de, E> + Eq + Hash,
     V: IntoDeserializer<'de, E>,
+    S: BuildHasher,
     E: de::Error,
 {
-    type Deserializer = MapDeserializer<'de, <HashMap<K, V> as IntoIterator>::IntoIter, E>;
+    type Deserializer = MapDeserializer<'de, <Self as IntoIterator>::IntoIter, E>;
 
     fn into_deserializer(self) -> Self::Deserializer {
         MapDeserializer::new(self.into_iter())
     }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
--- a/third_party/rust/serde/src/export.rs
+++ b/third_party/rust/serde/src/export.rs
@@ -14,28 +14,28 @@ pub use lib::marker::PhantomData;
 pub use lib::option::Option::{self, None, Some};
 pub use lib::result::Result::{self, Ok, Err};
 
 pub use self::string::from_utf8_lossy;
 
 mod string {
     use lib::*;
 
-    #[cfg(any(feature = "std", feature = "collections"))]
+    #[cfg(any(feature = "std", feature = "alloc"))]
     pub fn from_utf8_lossy(bytes: &[u8]) -> Cow<str> {
         String::from_utf8_lossy(bytes)
     }
 
     // The generated code calls this like:
     //
     //     let value = &_serde::export::from_utf8_lossy(bytes);
     //     Err(_serde::de::Error::unknown_variant(value, VARIANTS))
     //
     // so it is okay for the return type to be different from the std case as long
     // as the above works.
-    #[cfg(not(any(feature = "std", feature = "collections")))]
+    #[cfg(not(any(feature = "std", feature = "alloc")))]
     pub fn from_utf8_lossy(bytes: &[u8]) -> &str {
         // Three unicode replacement characters if it fails. They look like a
         // white-on-black question mark. The user will recognize it as invalid
         // UTF-8.
         str::from_utf8(bytes).unwrap_or("\u{fffd}\u{fffd}\u{fffd}")
     }
 }
--- a/third_party/rust/serde/src/lib.rs
+++ b/third_party/rust/serde/src/lib.rs
@@ -74,53 +74,77 @@
 //! [Envy]: https://github.com/softprops/envy
 //! [Redis]: https://github.com/OneSignal/serde-redis
 //! [Cargo]: http://doc.crates.io/manifest.html
 //! [redis-rs]: https://crates.io/crates/redis
 
 ////////////////////////////////////////////////////////////////////////////////
 
 // Serde types in rustdoc of other crates get linked to here.
-#![doc(html_root_url = "https://docs.rs/serde/1.0.8")]
+#![doc(html_root_url = "https://docs.rs/serde/1.0.23")]
 
 // Support using Serde without the standard library!
 #![cfg_attr(not(feature = "std"), no_std)]
 
 // Unstable functionality only if the user asks for it. For tracking and
 // discussion of these features please refer to this issue:
 //
 //    https://github.com/serde-rs/serde/issues/812
 #![cfg_attr(feature = "unstable", feature(nonzero, specialization))]
-#![cfg_attr(all(feature = "std", feature = "unstable"), feature(into_boxed_c_str))]
 #![cfg_attr(feature = "alloc", feature(alloc))]
-#![cfg_attr(feature = "collections", feature(collections))]
 
-// Whitelisted clippy lints.
-#![cfg_attr(feature = "cargo-clippy", allow(doc_markdown))]
-#![cfg_attr(feature = "cargo-clippy", allow(linkedlist))]
-#![cfg_attr(feature = "cargo-clippy", allow(type_complexity))]
-#![cfg_attr(feature = "cargo-clippy", allow(zero_prefixed_literal))]
+#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
+// Whitelisted clippy lints
+#![cfg_attr(feature = "cargo-clippy", allow(
+    cast_lossless,
+    const_static_lifetime,
+    doc_markdown,
+    linkedlist,
+    needless_pass_by_value,
+    type_complexity,
+    unreadable_literal,
+    zero_prefixed_literal,
+))]
+// Whitelisted clippy_pedantic lints
+#![cfg_attr(feature = "cargo-clippy", allow(
+// integer and float ser/de requires these sorts of casts
+    cast_possible_truncation,
+    cast_possible_wrap,
+    cast_precision_loss,
+    cast_sign_loss,
+// simplifies some macros
+    invalid_upcast_comparisons,
+// things are often more readable this way
+    option_unwrap_used,
+    result_unwrap_used,
+    shadow_reuse,
+    single_match_else,
+    stutter,
+    use_self,
+// not practical
+    missing_docs_in_private_items,
+// alternative is not stable
+    empty_enum,
+    use_debug,
+))]
 
 // Blacklisted Rust lints.
 #![deny(missing_docs, unused_imports)]
 
 ////////////////////////////////////////////////////////////////////////////////
 
-#[cfg(feature = "collections")]
-extern crate collections;
-
 #[cfg(feature = "alloc")]
 extern crate alloc;
 
 #[cfg(all(feature = "unstable", feature = "std"))]
 extern crate core;
 
-/// A facade around all the types we need from the `std`, `core`, `alloc`, and
-/// `collections` crates. This avoids elaborate import wrangling having to
-/// happen in every module.
+/// A facade around all the types we need from the `std`, `core`, and `alloc`
+/// crates. This avoids elaborate import wrangling having to happen in every
+/// module.
 mod lib {
     mod core {
         #[cfg(feature = "std")]
         pub use std::*;
         #[cfg(not(feature = "std"))]
         pub use core::*;
     }
 
@@ -135,28 +159,28 @@ mod lib {
     pub use self::core::default::{self, Default};
     pub use self::core::fmt::{self, Debug, Display};
     pub use self::core::marker::{self, PhantomData};
     pub use self::core::option::{self, Option};
     pub use self::core::result::{self, Result};
 
     #[cfg(feature = "std")]
     pub use std::borrow::{Cow, ToOwned};
-    #[cfg(all(feature = "collections", not(feature = "std")))]
-    pub use collections::borrow::{Cow, ToOwned};
+    #[cfg(all(feature = "alloc", not(feature = "std")))]
+    pub use alloc::borrow::{Cow, ToOwned};
 
     #[cfg(feature = "std")]
     pub use std::string::String;
-    #[cfg(all(feature = "collections", not(feature = "std")))]
-    pub use collections::string::{String, ToString};
+    #[cfg(all(feature = "alloc", not(feature = "std")))]
+    pub use alloc::string::{String, ToString};
 
     #[cfg(feature = "std")]
     pub use std::vec::Vec;
-    #[cfg(all(feature = "collections", not(feature = "std")))]
-    pub use collections::vec::Vec;
+    #[cfg(all(feature = "alloc", not(feature = "std")))]
+    pub use alloc::vec::Vec;
 
     #[cfg(feature = "std")]
     pub use std::boxed::Box;
     #[cfg(all(feature = "alloc", not(feature = "std")))]
     pub use alloc::boxed::Box;
 
     #[cfg(all(feature = "rc", feature = "std"))]
     pub use std::rc::Rc;
@@ -165,34 +189,36 @@ mod lib {
 
     #[cfg(all(feature = "rc", feature = "std"))]
     pub use std::sync::Arc;
     #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
     pub use alloc::arc::Arc;
 
     #[cfg(feature = "std")]
     pub use std::collections::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque};
-    #[cfg(all(feature = "collections", not(feature = "std")))]
-    pub use collections::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque};
+    #[cfg(all(feature = "alloc", not(feature = "std")))]
+    pub use alloc::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque};
 
     #[cfg(feature = "std")]
     pub use std::{error, net};
 
     #[cfg(feature = "std")]
     pub use std::collections::{HashMap, HashSet};
     #[cfg(feature = "std")]
     pub use std::ffi::{CString, CStr, OsString, OsStr};
     #[cfg(feature = "std")]
     pub use std::hash::{Hash, BuildHasher};
     #[cfg(feature = "std")]
     pub use std::io::Write;
     #[cfg(feature = "std")]
+    pub use std::num::Wrapping;
+    #[cfg(feature = "std")]
     pub use std::path::{Path, PathBuf};
     #[cfg(feature = "std")]
-    pub use std::time::Duration;
+    pub use std::time::{Duration, SystemTime, UNIX_EPOCH};
     #[cfg(feature = "std")]
     pub use std::sync::{Mutex, RwLock};
 
     #[cfg(feature = "unstable")]
     pub use core::nonzero::{NonZero, Zeroable};
 }
 
 ////////////////////////////////////////////////////////////////////////////////
--- a/third_party/rust/serde/src/private/de.rs
+++ b/third_party/rust/serde/src/private/de.rs
@@ -3,22 +3,22 @@
 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
 use lib::*;
 
-use de::{Deserialize, Deserializer, IntoDeserializer, Error, Visitor};
+use de::{Deserialize, Deserializer, DeserializeSeed, IntoDeserializer, Error, Visitor};
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 use de::Unexpected;
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 pub use self::content::{Content, ContentRefDeserializer, ContentDeserializer,
                         TaggedContentVisitor, TagOrContentField, TagOrContentFieldVisitor,
                         TagContentOtherField, TagContentOtherFieldVisitor,
                         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<'de, V, E>(field: &'static str) -> Result<V, E>
@@ -54,17 +54,17 @@ where
             struct enum identifier ignored_any
         }
     }
 
     let deserializer = MissingFieldDeserializer(field, PhantomData);
     Deserialize::deserialize(deserializer)
 }
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 pub fn borrow_cow_str<'de: 'a, 'a, D>(deserializer: D) -> Result<Cow<'a, str>, D::Error>
 where
     D: Deserializer<'de>,
 {
     struct CowStrVisitor;
 
     impl<'a> Visitor<'a> for CowStrVisitor {
         type Value = Cow<'a, str>;
@@ -123,17 +123,17 @@ where
                 Err(e) => Err(Error::invalid_value(Unexpected::Bytes(&e.into_bytes()), &self),),
             }
         }
     }
 
     deserializer.deserialize_str(CowStrVisitor)
 }
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 pub fn borrow_cow_bytes<'de: 'a, 'a, D>(deserializer: D) -> Result<Cow<'a, [u8]>, D::Error>
 where
     D: Deserializer<'de>,
 {
     struct CowBytesVisitor;
 
     impl<'a> Visitor<'a> for CowBytesVisitor {
         type Value = Cow<'a, [u8]>;
@@ -193,29 +193,30 @@ pub mod size_hint {
 
     pub fn from_bounds<I>(iter: &I) -> Option<usize>
     where
         I: Iterator,
     {
         helper(iter.size_hint())
     }
 
+    #[inline]
     pub fn cautious(hint: Option<usize>) -> usize {
         cmp::min(hint.unwrap_or(0), 4096)
     }
 
     fn helper(bounds: (usize, Option<usize>)) -> Option<usize> {
         match bounds {
             (lower, Some(upper)) if lower == upper => Some(upper),
             _ => None,
         }
     }
 }
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 mod content {
     // This module is private and nothing here should be used outside of
     // generated code.
     //
     // We will iterate on the implementation for a few releases and only have to
     // worry about backward compatibility for the `untagged` and `tag` attributes
     // rather than for this entire mechanism.
     //
@@ -829,36 +830,53 @@ mod content {
 
     impl<'de, T> Visitor<'de> for TaggedContentVisitor<'de, T>
     where
         T: Deserialize<'de>,
     {
         type Value = TaggedContent<'de, T>;
 
         fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-            fmt.write_str("any value")
+            fmt.write_str("internally tagged enum")
         }
 
-        fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
+        fn visit_seq<S>(self, mut seq: S) -> Result<Self::Value, S::Error>
         where
-            V: MapAccess<'de>,
+            S: SeqAccess<'de>,
+        {
+            let tag = match try!(seq.next_element()) {
+                Some(tag) => tag,
+                None => {
+                    return Err(de::Error::missing_field(self.tag_name));
+                }
+            };
+            let rest = de::value::SeqAccessDeserializer::new(seq);
+            Ok(TaggedContent {
+                tag: tag,
+                content: try!(Content::deserialize(rest)),
+            })
+        }
+
+        fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
+        where
+            M: MapAccess<'de>,
         {
             let mut tag = None;
-            let mut vec = Vec::with_capacity(size_hint::cautious(visitor.size_hint()));
+            let mut vec = Vec::with_capacity(size_hint::cautious(map.size_hint()));
             while let Some(k) =
-                try!(visitor.next_key_seed(TagOrContentVisitor::new(self.tag_name))) {
+                try!(map.next_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.next_value()));
+                        tag = Some(try!(map.next_value()));
                     }
                     TagOrContent::Content(k) => {
-                        let v = try!(visitor.next_value());
+                        let v = try!(map.next_value());
                         vec.push((k, v));
                     }
                 }
             }
             match tag {
                 None => Err(de::Error::missing_field(self.tag_name)),
                 Some(tag) => {
                     Ok(
@@ -1092,20 +1110,48 @@ mod content {
                 EnumDeserializer {
                     variant: variant,
                     value: value,
                     err: PhantomData,
                 },
             )
         }
 
+        fn deserialize_unit_struct<V>(
+            self,
+            _name: &'static str,
+            visitor: V
+        ) -> Result<V::Value, Self::Error>
+        where
+            V: Visitor<'de>,
+        {
+            match self.content {
+                // As a special case, allow deserializing untagged newtype
+                // variant containing unit struct.
+                //
+                //     #[derive(Deserialize)]
+                //     struct Info;
+                //
+                //     #[derive(Deserialize)]
+                //     #[serde(tag = "topic")]
+                //     enum Message {
+                //         Info(Info),
+                //     }
+                //
+                // We want {"topic":"Info"} to deserialize even though
+                // ordinarily unit structs do not deserialize from empty map.
+                Content::Map(ref v) if v.is_empty() => visitor.visit_unit(),
+                _ => self.deserialize_any(visitor),
+            }
+        }
+
         forward_to_deserialize_any! {
             bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
-            byte_buf unit unit_struct seq tuple tuple_struct map struct
-            identifier ignored_any
+            byte_buf unit seq tuple tuple_struct map struct identifier
+            ignored_any
         }
     }
 
     impl<'de, E> ContentDeserializer<'de, E> {
         /// private API, don't use
         pub fn new(content: Content<'de>) -> Self {
             ContentDeserializer {
                 content: content,
@@ -1196,16 +1242,19 @@ mod content {
         ) -> Result<V::Value, Self::Error>
         where
             V: de::Visitor<'de>,
         {
             match self.value {
                 Some(Content::Map(v)) => {
                     de::Deserializer::deserialize_any(MapDeserializer::new(v), visitor)
                 }
+                Some(Content::Seq(v)) => {
+                    de::Deserializer::deserialize_any(SeqDeserializer::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<'de, E>
     where
@@ -1590,16 +1639,19 @@ mod content {
         ) -> Result<V::Value, Self::Error>
         where
             V: de::Visitor<'de>,
         {
             match self.value {
                 Some(&Content::Map(ref v)) => {
                     de::Deserializer::deserialize_any(MapRefDeserializer::new(v), visitor)
                 }
+                Some(&Content::Seq(ref v)) => {
+                    de::Deserializer::deserialize_any(SeqRefDeserializer::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, 'de: 'a, E>
     where
@@ -1797,19 +1849,26 @@ mod content {
 
     impl<'de, 'a> Visitor<'de> for InternallyTaggedUnitVisitor<'a> {
         type Value = ();
 
         fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
             write!(formatter, "unit variant {}::{}", self.type_name, self.variant_name)
         }
 
-        fn visit_map<V>(self, _: V) -> Result<(), V::Error>
+        fn visit_seq<S>(self, _: S) -> Result<(), S::Error>
         where
-            V: MapAccess<'de>,
+            S: SeqAccess<'de>,
+        {
+            Ok(())
+        }
+
+        fn visit_map<M>(self, _: M) -> Result<(), M::Error>
+        where
+            M: MapAccess<'de>,
         {
             Ok(())
         }
     }
 
     /// Visitor for deserializing an untagged unit variant.
     ///
     /// Not public API.
@@ -1945,8 +2004,25 @@ where
     }
 
     forward_to_deserialize_any! {
         bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
         byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct
         map struct enum identifier ignored_any
     }
 }
+
+/// A DeserializeSeed helper for implementing deserialize_from Visitors.
+///
+/// Wraps a mutable reference and calls deserialize_from on it.
+pub struct DeserializeFromSeed<'a, T: 'a>(pub &'a mut T);
+
+impl<'a, 'de, T> DeserializeSeed<'de> for DeserializeFromSeed<'a, T>
+    where T: Deserialize<'de>,
+{
+    type Value = ();
+    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+       self.0.deserialize_from(deserializer)
+    }
+}
--- a/third_party/rust/serde/src/private/ser.rs
+++ b/third_party/rust/serde/src/private/ser.rs
@@ -5,17 +5,17 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
 use lib::*;
 
 use ser::{self, Serialize, Serializer, SerializeMap, SerializeStruct, Impossible};
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 use self::content::{SerializeTupleVariantAsMapValue, SerializeStructVariantAsMapValue};
 
 /// Used to check that serde(getter) attributes return the expected type.
 /// Not public API.
 pub fn constrain<T: ?Sized>(t: &T) -> &T {
     t
 }
 
@@ -55,40 +55,38 @@ enum Unsupported {
     Boolean,
     Integer,
     Float,
     Char,
     String,
     ByteArray,
     Optional,
     Unit,
-    UnitStruct,
     Sequence,
     Tuple,
     TupleStruct,
-    #[cfg(not(any(feature = "std", feature = "collections")))]
+    #[cfg(not(any(feature = "std", feature = "alloc")))]
     Enum,
 }
 
 impl Display for Unsupported {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match *self {
             Unsupported::Boolean => formatter.write_str("a boolean"),
             Unsupported::Integer => formatter.write_str("an integer"),
             Unsupported::Float => formatter.write_str("a float"),
             Unsupported::Char => formatter.write_str("a char"),
             Unsupported::String => formatter.write_str("a string"),
             Unsupported::ByteArray => formatter.write_str("a byte array"),
             Unsupported::Optional => formatter.write_str("an optional"),
             Unsupported::Unit => formatter.write_str("unit"),
-            Unsupported::UnitStruct => formatter.write_str("a unit struct"),
             Unsupported::Sequence => formatter.write_str("a sequence"),
             Unsupported::Tuple => formatter.write_str("a tuple"),
             Unsupported::TupleStruct => formatter.write_str("a tuple struct"),
-            #[cfg(not(any(feature = "std", feature = "collections")))]
+            #[cfg(not(any(feature = "std", feature = "alloc")))]
             Unsupported::Enum => formatter.write_str("an enum"),
         }
     }
 }
 
 impl<S> TaggedSerializer<S>
 where
     S: Serializer,
@@ -112,24 +110,24 @@ where
     type Error = S::Error;
 
     type SerializeSeq = Impossible<S::Ok, S::Error>;
     type SerializeTuple = Impossible<S::Ok, S::Error>;
     type SerializeTupleStruct = Impossible<S::Ok, S::Error>;
     type SerializeMap = S::SerializeMap;
     type SerializeStruct = S::SerializeStruct;
 
-    #[cfg(not(any(feature = "std", feature = "collections")))]
+    #[cfg(not(any(feature = "std", feature = "alloc")))]
     type SerializeTupleVariant = Impossible<S::Ok, S::Error>;
-    #[cfg(any(feature = "std", feature = "collections"))]
+    #[cfg(any(feature = "std", feature = "alloc"))]
     type SerializeTupleVariant = SerializeTupleVariantAsMapValue<S::SerializeMap>;
 
-    #[cfg(not(any(feature = "std", feature = "collections")))]
+    #[cfg(not(any(feature = "std", feature = "alloc")))]
     type SerializeStructVariant = Impossible<S::Ok, S::Error>;
-    #[cfg(any(feature = "std", feature = "collections"))]
+    #[cfg(any(feature = "std", feature = "alloc"))]
     type SerializeStructVariant = SerializeStructVariantAsMapValue<S::SerializeMap>;
 
     fn serialize_bool(self, _: bool) -> Result<Self::Ok, Self::Error> {
         Err(self.bad_type(Unsupported::Boolean))
     }
 
     fn serialize_i8(self, _: i8) -> Result<Self::Ok, Self::Error> {
         Err(self.bad_type(Unsupported::Integer))
@@ -194,17 +192,19 @@ where
         Err(self.bad_type(Unsupported::Optional))
     }
 
     fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
         Err(self.bad_type(Unsupported::Unit))
     }
 
     fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok, Self::Error> {
-        Err(self.bad_type(Unsupported::UnitStruct))
+        let mut map = try!(self.delegate.serialize_map(Some(1)));
+        try!(map.serialize_entry(self.tag, self.variant_name));
+        map.end()
     }
 
     fn serialize_unit_variant(
         self,
         _: &'static str,
         _: u32,
         inner_variant: &'static str,
     ) -> Result<Self::Ok, Self::Error> {
@@ -252,30 +252,30 @@ where
     fn serialize_tuple_struct(
         self,
         _: &'static str,
         _: usize,
     ) -> Result<Self::SerializeTupleStruct, Self::Error> {
         Err(self.bad_type(Unsupported::TupleStruct))
     }
 
-    #[cfg(not(any(feature = "std", feature = "collections")))]
+    #[cfg(not(any(feature = "std", feature = "alloc")))]
     fn serialize_tuple_variant(
         self,
         _: &'static str,
         _: u32,
         _: &'static str,
         _: usize,
     ) -> Result<Self::SerializeTupleVariant, Self::Error> {
         // Lack of push-based serialization means we need to buffer the content
         // of the tuple variant, so it requires std.
         Err(self.bad_type(Unsupported::Enum))
     }
 
-    #[cfg(any(feature = "std", feature = "collections"))]
+    #[cfg(any(feature = "std", feature = "alloc"))]
     fn serialize_tuple_variant(
         self,
         _: &'static str,
         _: u32,
         inner_variant: &'static str,
         len: usize,
     ) -> Result<Self::SerializeTupleVariant, Self::Error> {
         let mut map = try!(self.delegate.serialize_map(Some(2)));
@@ -295,44 +295,44 @@ where
         name: &'static str,
         len: usize,
     ) -> Result<Self::SerializeStruct, Self::Error> {
         let mut state = try!(self.delegate.serialize_struct(name, len + 1));
         try!(state.serialize_field(self.tag, self.variant_name));
         Ok(state)
     }
 
-    #[cfg(not(any(feature = "std", feature = "collections")))]
+    #[cfg(not(any(feature = "std", feature = "alloc")))]
     fn serialize_struct_variant(
         self,
         _: &'static str,
         _: u32,
         _: &'static str,
         _: usize,
     ) -> Result<Self::SerializeStructVariant, Self::Error> {
         // Lack of push-based serialization means we need to buffer the content
         // of the struct variant, so it requires std.
         Err(self.bad_type(Unsupported::Enum))
     }
 
-    #[cfg(any(feature = "std", feature = "collections"))]
+    #[cfg(any(feature = "std", feature = "alloc"))]
     fn serialize_struct_variant(
         self,
         _: &'static str,
         _: u32,
         inner_variant: &'static str,
         len: usize,
     ) -> Result<Self::SerializeStructVariant, Self::Error> {
         let mut map = try!(self.delegate.serialize_map(Some(2)));
         try!(map.serialize_entry(self.tag, self.variant_name));
         try!(map.serialize_key(inner_variant));
         Ok(SerializeStructVariantAsMapValue::new(map, inner_variant, len),)
     }
 
-    #[cfg(not(any(feature = "std", feature = "collections")))]
+    #[cfg(not(any(feature = "std", feature = "alloc")))]
     fn collect_str<T: ?Sized>(self, _: &T) -> Result<Self::Ok, Self::Error>
     where
         T: Display,
     {
         Err(self.bad_type(Unsupported::String))
     }
 }
 
@@ -358,17 +358,17 @@ impl error::Error for Error {
 }
 
 impl Display for Error {
     fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
         unimplemented!()
     }
 }
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 mod content {
     use lib::*;
 
     use ser::{self, Serialize, Serializer};
 
     pub struct SerializeTupleVariantAsMapValue<M> {
         map: M,
         name: &'static str,
--- a/third_party/rust/serde/src/ser/impls.rs
+++ b/third_party/rust/serde/src/ser/impls.rs
@@ -51,17 +51,17 @@ impl Serialize for str {
     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
     where
         S: Serializer,
     {
         serializer.serialize_str(self)
     }
 }
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 impl Serialize for String {
     #[inline]
     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
     where
         S: Serializer,
     {
         serializer.serialize_str(self)
     }
@@ -172,16 +172,17 @@ where
     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
     where
         S: Serializer,
     {
         serializer.collect_seq(self)
     }
 }
 
+#[cfg(any(feature = "std", feature = "alloc"))]
 macro_rules! seq_impl {
     ($ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound:ident)* >) => {
         impl<T $(, $typaram)*> Serialize for $ty<T $(, $typaram)*>
         where
             T: Serialize $(+ $tbound1 $(+ $tbound2)*)*,
             $($typaram: $bound,)*
         {
             #[inline]
@@ -190,32 +191,32 @@ macro_rules! seq_impl {
                 S: Serializer,
             {
                 serializer.collect_seq(self)
             }
         }
     }
 }
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 seq_impl!(BinaryHeap<T: Ord>);
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 seq_impl!(BTreeSet<T: Ord>);
 
 #[cfg(feature = "std")]
 seq_impl!(HashSet<T: Eq + Hash, H: BuildHasher>);
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 seq_impl!(LinkedList<T>);
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 seq_impl!(Vec<T>);
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 seq_impl!(VecDeque<T>);
 
 ////////////////////////////////////////////////////////////////////////////////
 
 #[cfg(feature = "std")]
 impl<Idx> Serialize for ops::Range<Idx>
 where
     Idx: Serialize,
@@ -285,16 +286,17 @@ tuple_impls! {
     13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12)
     14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13)
     15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14)
     16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15)
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
+#[cfg(any(feature = "std", feature = "alloc"))]
 macro_rules! map_impl {
     ($ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound:ident)* >) => {
         impl<K, V $(, $typaram)*> Serialize for $ty<K, V $(, $typaram)*>
         where
             K: Serialize $(+ $kbound1 $(+ $kbound2)*)*,
             V: Serialize,
             $($typaram: $bound,)*
         {
@@ -304,17 +306,17 @@ macro_rules! map_impl {
                 S: Serializer,
             {
                 serializer.collect_map(self)
             }
         }
     }
 }
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 map_impl!(BTreeMap<K: Ord, V>);
 
 #[cfg(feature = "std")]
 map_impl!(HashMap<K: Eq + Hash, V, H: BuildHasher>);
 
 ////////////////////////////////////////////////////////////////////////////////
 
 macro_rules! deref_impl {
@@ -333,22 +335,22 @@ macro_rules! deref_impl {
 
 deref_impl!(<'a, T: ?Sized> Serialize for &'a T where T: Serialize);
 deref_impl!(<'a, T: ?Sized> Serialize for &'a mut T where T: Serialize);
 
 #[cfg(any(feature = "std", feature = "alloc"))]
 deref_impl!(<T: ?Sized> Serialize for Box<T> where T: Serialize);
 
 #[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
-deref_impl!(<T> Serialize for Rc<T> where T: Serialize);
+deref_impl!(<T: ?Sized> Serialize for Rc<T> where T: Serialize);
 
 #[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
-deref_impl!(<T> Serialize for Arc<T> where T: Serialize);
+deref_impl!(<T: ?Sized> Serialize for Arc<T> where T: Serialize);
 
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
 deref_impl!(<'a, T: ?Sized> Serialize for Cow<'a, T> where T: Serialize + ToOwned);
 
 ////////////////////////////////////////////////////////////////////////////////
 
 #[cfg(feature = "unstable")]
 impl<T> Serialize for NonZero<T>
 where
     T: Serialize + Zeroable + Clone,
@@ -450,16 +452,33 @@ impl Serialize for Duration {
         try!(state.serialize_field("secs", &self.as_secs()));
         try!(state.serialize_field("nanos", &self.subsec_nanos()));
         state.end()
     }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
+#[cfg(feature = "std")]
+impl Serialize for SystemTime {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        use super::SerializeStruct;
+        let duration_since_epoch = self.duration_since(UNIX_EPOCH).expect("SystemTime must be later than UNIX_EPOCH");
+        let mut state = try!(serializer.serialize_struct("SystemTime", 2));
+        try!(state.serialize_field("secs_since_epoch", &duration_since_epoch.as_secs()));
+        try!(state.serialize_field("nanos_since_epoch", &duration_since_epoch.subsec_nanos()));
+        state.end()
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
 /// Serialize a value that implements `Display` as a string, when that string is
 /// statically known to never have more than a constant `MAX_LEN` bytes.
 ///
 /// Panics if the `Display` impl tries to write more than `MAX_LEN` bytes.
 #[cfg(feature = "std")]
 macro_rules! serialize_display_bounded_length {
     ($value:expr, $max:expr, $serializer:expr) => {{
         let mut buffer: [u8; $max] = unsafe { mem::uninitialized() };
@@ -482,81 +501,115 @@ macro_rules! serialize_display_bounded_l
 }
 
 #[cfg(feature = "std")]
 impl Serialize for net::IpAddr {
     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
     where
         S: Serializer,
     {
-        match *self {
-            net::IpAddr::V4(ref a) => a.serialize(serializer),
-            net::IpAddr::V6(ref a) => a.serialize(serializer),
+        if serializer.is_human_readable() {
+            match *self {
+                net::IpAddr::V4(ref a) => a.serialize(serializer),
+                net::IpAddr::V6(ref a) => a.serialize(serializer),
+            }
+        } else {
+            match *self {
+                net::IpAddr::V4(ref a) =>
+                    serializer.serialize_newtype_variant("IpAddr", 0, "V4", a),
+                net::IpAddr::V6(ref a) =>
+                    serializer.serialize_newtype_variant("IpAddr", 1, "V6", a),
+            }
         }
     }
 }
 
 #[cfg(feature = "std")]
 impl Serialize for net::Ipv4Addr {
     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
     where
         S: Serializer,
     {
-        /// "101.102.103.104".len()
-        const MAX_LEN: usize = 15;
-        serialize_display_bounded_length!(self, MAX_LEN, serializer)
+        if serializer.is_human_readable() {
+            const MAX_LEN: usize = 15;
+            debug_assert_eq!(MAX_LEN, "101.102.103.104".len());
+            serialize_display_bounded_length!(self, MAX_LEN, serializer)
+        } else {
+            self.octets().serialize(serializer)
+        }
     }
 }
 
 #[cfg(feature = "std")]
 impl Serialize for net::Ipv6Addr {
     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
     where
         S: Serializer,
     {
-        /// "1000:1002:1003:1004:1005:1006:1007:1008".len()
-        const MAX_LEN: usize = 39;
-        serialize_display_bounded_length!(self, MAX_LEN, serializer)
+        if serializer.is_human_readable() {
+            const MAX_LEN: usize = 39;
+            debug_assert_eq!(MAX_LEN, "1001:1002:1003:1004:1005:1006:1007:1008".len());
+            serialize_display_bounded_length!(self, MAX_LEN, serializer)
+        } else {
+            self.octets().serialize(serializer)
+        }
     }
 }
 
 #[cfg(feature = "std")]
 impl Serialize for net::SocketAddr {
     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
     where
         S: Serializer,
     {
-        match *self {
-            net::SocketAddr::V4(ref addr) => addr.serialize(serializer),
-            net::SocketAddr::V6(ref addr) => addr.serialize(serializer),
+        if serializer.is_human_readable() {
+            match *self {
+                net::SocketAddr::V4(ref addr) => addr.serialize(serializer),
+                net::SocketAddr::V6(ref addr) => addr.serialize(serializer),
+            }
+        } else {
+            match *self {
+                net::SocketAddr::V4(ref addr) =>
+                    serializer.serialize_newtype_variant("SocketAddr", 0, "V4", addr),
+                net::SocketAddr::V6(ref addr) =>
+                    serializer.serialize_newtype_variant("SocketAddr", 1, "V6", addr),
+            }
         }
     }
 }
 
 #[cfg(feature = "std")]
 impl Serialize for net::SocketAddrV4 {
     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
     where
         S: Serializer,
     {
-        /// "101.102.103.104:65000".len()
-        const MAX_LEN: usize = 21;
-        serialize_display_bounded_length!(self, MAX_LEN, serializer)
+        if serializer.is_human_readable() {
+            const MAX_LEN: usize = 21;
+            debug_assert_eq!(MAX_LEN, "101.102.103.104:65000".len());
+            serialize_display_bounded_length!(self, MAX_LEN, serializer)
+        } else {
+            (self.ip(), self.port()).serialize(serializer)
+        }
     }
 }
 
 #[cfg(feature = "std")]
 impl Serialize for net::SocketAddrV6 {
     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
     where
         S: Serializer,
     {
-        /// "[1000:1002:1003:1004:1005:1006:1007:1008]:65000".len()
-        const MAX_LEN: usize = 47;
-        serialize_display_bounded_length!(self, MAX_LEN, serializer)
+        if serializer.is_human_readable() {
+            const MAX_LEN: usize = 47;
+            debug_assert_eq!(MAX_LEN, "[1001:1002:1003:1004:1005:1006:1007:1008]:65000".len());
+            serialize_display_bounded_length!(self, MAX_LEN, serializer)
+        } else {
+            (self.ip(), self.port()).serialize(serializer)
+        }
     }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 #[cfg(feature = "std")]
 impl Serialize for Path {
     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -606,8 +659,24 @@ impl Serialize for OsStr {
 impl Serialize for OsString {
     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
     where
         S: Serializer,
     {
         self.as_os_str().serialize(serializer)
     }
 }
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(feature = "std")]
+impl<T> Serialize for Wrapping<T>
+where
+    T: Serialize,
+{
+    #[inline]
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        self.0.serialize(serializer)
+    }
+}
--- a/third_party/rust/serde/src/ser/mod.rs
+++ b/third_party/rust/serde/src/ser/mod.rs
@@ -84,16 +84,17 @@
 //!    - EnumSet\<T\> (unstable)
 //!  - **FFI types**:
 //!    - CStr
 //!    - CString
 //!    - OsStr
 //!    - OsString
 //!  - **Miscellaneous standard library types**:
 //!    - Duration
+//!    - SystemTime
 //!    - Path
 //!    - PathBuf
 //!    - Range\<T\>
 //!    - NonZero\<T\> (unstable)
 //!  - **Net types**:
 //!    - IpAddr
 //!    - Ipv4Addr
 //!    - Ipv6Addr
@@ -1316,17 +1317,17 @@ pub trait Serializer: Sized {
     ///                                              self.naive_local(),
     ///                                              self.offset()))
     ///     }
     /// }
     /// ```
     ///
     /// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html
     /// [`serialize_str`]: #tymethod.serialize_str
-    #[cfg(any(feature = "std", feature = "collections"))]
+    #[cfg(any(feature = "std", feature = "alloc"))]
     fn collect_str<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
     where
         T: Display,
     {
         use lib::fmt::Write;
         let mut string = String::new();
         write!(string, "{}", value).unwrap();
         self.serialize_str(&string)
@@ -1353,20 +1354,70 @@ pub trait Serializer: Sized {
     ///         where S: Serializer
     ///     {
     ///         serializer.collect_str(&format_args!("{:?}{:?}",
     ///                                              self.naive_local(),
     ///                                              self.offset()))
     ///     }
     /// }
     /// ```
-    #[cfg(not(any(feature = "std", feature = "collections")))]
+    #[cfg(not(any(feature = "std", feature = "alloc")))]
     fn collect_str<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
     where
         T: Display;
+
+    /// Determine whether `Serialize` implementations should serialize in
+    /// human-readable form.
+    ///
+    /// Some types have a human-readable form that may be somewhat expensive to
+    /// construct, as well as a binary form that is compact and efficient.
+    /// Generally text-based formats like JSON and YAML will prefer to use the
+    /// human-readable one and binary formats like Bincode will prefer the
+    /// compact one.
+    ///
+    /// ```
+    /// # use std::fmt::{self, Display};
+    /// #
+    /// # struct Timestamp;
+    /// #
+    /// # impl Timestamp {
+    /// #     fn seconds_since_epoch(&self) -> u64 { unimplemented!() }
+    /// # }
+    /// #
+    /// # impl Display for Timestamp {
+    /// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+    /// #         unimplemented!()
+    /// #     }
+    /// # }
+    /// #
+    /// use serde::{Serialize, Serializer};
+    ///
+    /// impl Serialize for Timestamp {
+    ///     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    ///         where S: Serializer
+    ///     {
+    ///         if serializer.is_human_readable() {
+    ///             // Serialize to a human-readable string "2015-05-15T17:01:00Z".
+    ///             self.to_string().serialize(serializer)
+    ///         } else {
+    ///             // Serialize to a compact binary representation.
+    ///             self.seconds_since_epoch().serialize(serializer)
+    ///         }
+    ///     }
+    /// }
+    /// ```
+    ///
+    /// The default implementation of this method returns `true`. Data formats
+    /// may override this to `false` to request a compact form for types that
+    /// support one. Note that modifying this method to change a format from
+    /// human-readable to compact or vice versa should be regarded as a breaking
+    /// change, as a value serialized in human-readable mode is not required to
+    /// deserialize from the same data in compact mode.
+    #[inline]
+    fn is_human_readable(&self) -> bool { true }
 }
 
 /// Returned from `Serializer::serialize_seq`.
 ///
 /// ```rust
 /// # use std::marker::PhantomData;
 /// #
 /// # struct Vec<T>(PhantomData<T>);
@@ -1721,16 +1772,23 @@ pub trait SerializeStruct {
     fn serialize_field<T: ?Sized>(
         &mut self,
         key: &'static str,
         value: &T,
     ) -> Result<(), Self::Error>
     where
         T: Serialize;
 
+    /// Indicate that a struct field has been skipped.
+    #[inline]
+    fn skip_field(&mut self, key: &'static str) -> Result<(), Self::Error> {
+        let _ = key;
+        Ok(())
+    }
+
     /// Finish serializing a struct.
     fn end(self) -> Result<Self::Ok, Self::Error>;
 }
 
 /// Returned from `Serializer::serialize_struct_variant`.
 ///
 /// ```rust
 /// use serde::ser::{Serialize, Serializer, SerializeStructVariant};
@@ -1766,16 +1824,23 @@ pub trait SerializeStructVariant {
     fn serialize_field<T: ?Sized>(
         &mut self,
         key: &'static str,
         value: &T,
     ) -> Result<(), Self::Error>
     where
         T: Serialize;
 
+    /// Indicate that a struct variant field has been skipped.
+    #[inline]
+    fn skip_field(&mut self, key: &'static str) -> Result<(), Self::Error> {
+        let _ = key;
+        Ok(())
+    }
+
     /// Finish serializing a struct variant.
     fn end(self) -> Result<Self::Ok, Self::Error>;
 }
 
 trait LenHint: Iterator {
     fn len_hint(&self) -> Option<usize>;
 }
 
--- a/third_party/rust/serde_derive/.cargo-checksum.json
+++ b/third_party/rust/serde_derive/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"fc1c90305d1d8d6debda370913068486b2465b4ac548651f9122169def6da94c","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"eedee04bddb61e99bc816656bb3b8ae2fa50ff00045ecdb5212682f3592d9ab2","src/bound.rs":"c01b1ec82b830b01a840d27654f2b1d3354e62a2b404227fccbb84d80cc6a593","src/de.rs":"518d74b38a7c254383fa6b2e5bfd71137e3abfbeda8b2577d25b7d8acdb03df5","src/fragment.rs":"f1642a1c2abbc36191206a5ec8077e314bdc20a420d7649e4bec3a69d555f78d","src/lib.rs":"fda8bd7ae031370f004d2672c12bfb9a5ae4314f499b5c7cbf9947e810d1d255","src/ser.rs":"b573af63ecfc51849b1157e2c3ae55b3bc256c3ce4b2712a639c5750e42eddfa"},"package":"10552fad5500771f3902d0c5ba187c5881942b811b7ba0d8fbbfbf84d80806d3"}
\ No newline at end of file
+{"files":{"Cargo.toml":"972517c9f00568bfc6806f09dad62aa94ed9f86afe35b4ab0e8d30f1600a04c5","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"7dc6376a88195594cd6b43cb891aad10f57144ff737178b55d046aa04739b43a","src/bound.rs":"4999df0c898ae4d5f0fdcd7a6365edabd5101027d67224ce54901c1653060f15","src/de.rs":"6783ba15e53f5d494c9af609474fa15d99d5e76bb0fea71e4d85829f3eeec2d0","src/fragment.rs":"f1642a1c2abbc36191206a5ec8077e314bdc20a420d7649e4bec3a69d555f78d","src/lib.rs":"49832577d7d7451cb6aedab7fdb1c9013e4ad0b8962d0d5d0936e69c9c9fc7ce","src/ser.rs":"e10042683c58f5eb833d9811ed3c2115e93f412188ac6f116c063851584fbec5"},"package":null}
\ No newline at end of file
--- a/third_party/rust/serde_derive/Cargo.toml
+++ b/third_party/rust/serde_derive/Cargo.toml
@@ -1,41 +1,31 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g. crates.io) dependencies
-#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
 [package]
 name = "serde_derive"
-version = "1.0.8"
+version = "1.0.23" # remember to update html_root_url
 authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
-include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
+license = "MIT/Apache-2.0"
 description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
 homepage = "https://serde.rs"
+repository = "https://github.com/serde-rs/serde"
 documentation = "https://serde.rs/codegen.html"
-readme = "README.md"
 keywords = ["serde", "serialization", "no_std"]
-license = "MIT/Apache-2.0"
-repository = "https://github.com/serde-rs/serde"
+readme = "README.md"
+include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
+
+[badges]
+travis-ci = { repository = "serde-rs/serde" }
+
+[features]
+default = []
+deserialize_from = []
 
 [lib]
 name = "serde_derive"
 proc-macro = true
 
 [dependencies]
 quote = "0.3.8"
-
-[dependencies.syn]
-version = "0.11"
-features = ["visit"]
+serde_derive_internals = { version = "=0.17.0", default-features = false, path = "../serde_derive_internals" }
+syn = { version = "0.11", features = ["visit"] }
 
-[dependencies.serde_derive_internals]
-version = "=0.15.1"
-default-features = false
-[badges.travis-ci]
-repository = "serde-rs/serde"
+[dev-dependencies]
+serde = { version = "1.0", path = "../serde" }
--- a/third_party/rust/serde_derive/README.md
+++ b/third_party/rust/serde_derive/README.md
@@ -15,19 +15,40 @@ You may be looking for:
 - [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
 
-<a href="http://play.integer32.com/?gist=9003c5b88c1f4989941925d7190c6eec" target="_blank">
-<img align="right" width="50" src="https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/run.png">
-</a>
+<details>
+<summary>
+Click to show Cargo.toml.
+<a href="http://play.integer32.com/?gist=9003c5b88c1f4989941925d7190c6eec" target="_blank">Run this code in the playground.</a>
+</summary>
+
+```toml
+[dependencies]
+
+# The core APIs, including the Serialize and Deserialize traits. Always
+# required when using Serde.
+serde = "1.0"
+
+# Support for #[derive(Serialize, Deserialize)]. Required if you want Serde
+# to work for structs and enums defined in your crate.
+serde_derive = "1.0"
+
+# Each data format lives in its own crate; the sample code below uses JSON
+# but you may be using a different one.
+serde_json = "1.0"
+```
+
+</details>
+<p></p>
 
 ```rust
 #[macro_use]
 extern crate serde_derive;
 
 extern crate serde;
 extern crate serde_json;
 
--- a/third_party/rust/serde_derive/src/bound.rs
+++ b/third_party/rust/serde_derive/src/bound.rs
@@ -5,22 +5,22 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
 use std::collections::HashSet;
 
 use syn::{self, visit};
 
-use internals::ast::Container;
+use internals::ast::{Body, Container};
 use internals::attr;
 
 macro_rules! path {
     ($($path:tt)+) => {
-        syn::parse_path(stringify!($($path)+)).unwrap()
+        syn::parse_path(quote!($($path)+).as_str()).unwrap()
     };
 }
 
 // Remove the default from every type parameter because in the generated impls
 // they look like associated types: "error: associated type bindings are not
 // allowed here".
 pub fn without_defaults(generics: &syn::Generics) -> syn::Generics {
     syn::Generics {
@@ -83,17 +83,17 @@ where
 //     }
 pub fn with_bound<F>(
     cont: &Container,
     generics: &syn::Generics,
     filter: F,
     bound: &syn::Path,
 ) -> syn::Generics
 where
-    F: Fn(&attr::Field) -> bool,
+    F: Fn(&attr::Field, Option<&attr::Variant>) -> bool,
 {
     struct FindTyParams {
         // Set of all generic type parameters on the current struct (A, B, C in
         // the example). Initialized up front.
         all_ty_params: HashSet<syn::Ident>,
         // Set of generic type parameters used in fields for which filter
         // returns true (A and B in the example). Filled in as the visitor sees
         // them.
@@ -111,35 +111,53 @@ where
             if !path.global && path.segments.len() == 1 {
                 let id = path.segments[0].ident.clone();
                 if self.all_ty_params.contains(&id) {
                     self.relevant_ty_params.insert(id);
                 }
             }
             visit::walk_path(self, path);
         }
+
+        // Type parameter should not be considered used by a macro path.
+        //
+        //     struct TypeMacro<T> {
+        //         mac: T!(),
+        //         marker: PhantomData<T>,
+        //     }
+        fn visit_mac(&mut self, _mac: &syn::Mac) {}
     }
 
     let all_ty_params: HashSet<_> = generics
         .ty_params
         .iter()
         .map(|ty_param| ty_param.ident.clone())
         .collect();
 
-    let relevant_tys = cont.body
-        .all_fields()
-        .filter(|&field| filter(&field.attrs))
-        .map(|field| &field.ty);
-
     let mut visitor = FindTyParams {
         all_ty_params: all_ty_params,
         relevant_ty_params: HashSet::new(),
     };
-    for ty in relevant_tys {
-        visit::walk_ty(&mut visitor, ty);
+    match cont.body {
+        Body::Enum(_, ref variants) => {
+            for variant in variants.iter() {
+                let relevant_fields = variant
+                    .fields
+                    .iter()
+                    .filter(|field| filter(&field.attrs, Some(&variant.attrs)));
+                for field in relevant_fields {
+                    visit::walk_ty(&mut visitor, field.ty);
+                }
+            }
+        }
+        Body::Struct(_, ref fields) => {
+            for field in fields.iter().filter(|field| filter(&field.attrs, None)) {
+                visit::walk_ty(&mut visitor, field.ty);
+            }
+        }
     }
 
     let new_predicates = generics
         .ty_params
         .iter()
         .map(|ty_param| ty_param.ident.clone())
         .filter(|id| visitor.relevant_ty_params.contains(id))
         .map(
--- a/third_party/rust/serde_derive/src/de.rs
+++ b/third_party/rust/serde_derive/src/de.rs
@@ -6,218 +6,291 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
 use syn::{self, Ident};
 use quote::{self, Tokens, ToTokens};
 
 use bound;
 use fragment::{Fragment, Expr, Stmts, Match};
-use internals::ast::{Body, Container, Field, Style, Variant};
+use internals::ast::{Body, Container, Field, Repr, Style, Variant};
 use internals::{self, attr};
 
 use std::collections::BTreeSet;
 
 pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<Tokens, String> {
     let ctxt = internals::Ctxt::new();
     let cont = Container::from_ast(&ctxt, input);
     try!(ctxt.check());
 
     let ident = &cont.ident;
     let params = Parameters::new(&cont);
+    let (de_impl_generics, _, ty_generics, where_clause) = split_with_de_lifetime(&params);
     let dummy_const = Ident::new(format!("_IMPL_DESERIALIZE_FOR_{}", ident));
-    let body = Stmts(deserialize_body(&cont, &params));
+    let main_body = Stmts(deserialize_body(&cont, &params));
+    let delife = params.borrowed.de_lifetime();
 
     let impl_block = if let Some(remote) = cont.attrs.remote() {
-        let (impl_generics, ty_generics, where_clause) = cont.generics.split_for_impl();
-        let de_lifetime = params.de_lifetime_def();
+        let vis = &input.vis;
         quote! {
-            impl #impl_generics #ident #ty_generics #where_clause {
-                fn deserialize<#de_lifetime, __D>(__deserializer: __D) -> _serde::export::Result<#remote #ty_generics, __D::Error>
-                    where __D: _serde::Deserializer<'de>
+            impl #de_impl_generics #ident #ty_generics #where_clause {
+                #vis fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<#remote #ty_generics, __D::Error>
+                    where __D: _serde::Deserializer<#delife>
                 {
-                    #body
+                    #main_body
                 }
             }
         }
     } else {
-        let (de_impl_generics, _, ty_generics, where_clause) = split_with_de_lifetime(&params);
+        let from_body = deserialize_from_body(&cont, &params);
+        let from_impl = from_body.map(|from_body| {
+            let from_body = Stmts(from_body);
+
+            quote! {
+                fn deserialize_from<__D>(&mut self, __deserializer: __D) -> _serde::export::Result<(), __D::Error>
+                    where __D: _serde::Deserializer<#delife>
+                {
+                    #from_body
+                }
+            }
+        });
+
         quote! {
             #[automatically_derived]
-            impl #de_impl_generics _serde::Deserialize<'de> for #ident #ty_generics #where_clause {
+            impl #de_impl_generics _serde::Deserialize<#delife> for #ident #ty_generics #where_clause {
                 fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<Self, __D::Error>
-                    where __D: _serde::Deserializer<'de>
+                    where __D: _serde::Deserializer<#delife>
                 {
-                    #body
+                    #main_body
                 }
+
+                #from_impl
             }
         }
     };
 
     let generated = quote! {
         #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
         const #dummy_const: () = {
             extern crate serde as _serde;
             #impl_block
         };
     };
     Ok(generated)
 }
 
+#[derive(Clone)]
 struct Parameters {
     /// Name of the type the `derive` is on.
     local: syn::Ident,
 
     /// Path to the type the impl is for. Either a single `Ident` for local
     /// types or `some::remote::Ident` for remote types. Does not include
     /// generic parameters.
     this: syn::Path,
 
     /// Generics including any explicit and inferred bounds for the impl.
     generics: syn::Generics,
 
     /// Lifetimes borrowed from the deserializer. These will become bounds on
     /// the `'de` lifetime of the deserializer.
-    borrowed: BTreeSet<syn::Lifetime>,
+    borrowed: BorrowedLifetimes,
 
     /// At least one field has a serde(getter) attribute, implying that the
     /// remote type has a private field.
     has_getter: bool,
 }
 
 impl Parameters {
     fn new(cont: &Container) -> Self {
         let local = cont.ident.clone();
         let this = match cont.attrs.remote() {
             Some(remote) => remote.clone(),
             None => cont.ident.clone().into(),
         };
-        let generics = build_generics(cont);
         let borrowed = borrowed_lifetimes(cont);
+        let generics = build_generics(cont, &borrowed);
         let has_getter = cont.body.has_getter();
 
         Parameters {
             local: local,
             this: this,
             generics: generics,
             borrowed: borrowed,
             has_getter: has_getter,
         }
     }
 
     /// Type name to use in error messages and `&'static str` arguments to
     /// various Deserializer methods.
     fn type_name(&self) -> &str {
         self.this.segments.last().unwrap().ident.as_ref()
     }
-
-    fn de_lifetime_def(&self) -> syn::LifetimeDef {
-        syn::LifetimeDef {
-            attrs: Vec::new(),
-            lifetime: syn::Lifetime::new("'de"),
-            bounds: self.borrowed.iter().cloned().collect(),
-        }
-    }
 }
 
 // All the generics in the input, plus a bound `T: Deserialize` for each generic
 // field type that will be deserialized by us, plus a bound `T: Default` for
 // each generic field type that will be set to a default value.
-fn build_generics(cont: &Container) -> syn::Generics {
+fn build_generics(cont: &Container, borrowed: &BorrowedLifetimes) -> syn::Generics {
     let generics = bound::without_defaults(cont.generics);
 
     let generics = bound::with_where_predicates_from_fields(cont, &generics, attr::Field::de_bound);
 
     match cont.attrs.de_bound() {
         Some(predicates) => bound::with_where_predicates(&generics, predicates),
         None => {
             let generics = match *cont.attrs.default() {
                 attr::Default::Default => {
                     bound::with_self_bound(cont, &generics, &path!(_serde::export::Default))
                 }
                 attr::Default::None |
                 attr::Default::Path(_) => generics,
             };
 
+            let delife = borrowed.de_lifetime();
             let generics = bound::with_bound(
                 cont,
                 &generics,
                 needs_deserialize_bound,
-                &path!(_serde::Deserialize<'de>),
+                &path!(_serde::Deserialize<#delife>),
             );
 
             bound::with_bound(
                 cont,
                 &generics,
                 requires_default,
                 &path!(_serde::export::Default),
             )
         }
     }
 }
 
 // Fields with a `skip_deserializing` or `deserialize_with` attribute are not
 // deserialized by us so we do not generate a bound. Fields with a `bound`
 // attribute specify their own bound so we do not generate one. All other fields
 // may need a `T: Deserialize` bound where T is the type of the field.
-fn needs_deserialize_bound(attrs: &attr::Field) -> bool {
-    !attrs.skip_deserializing() && attrs.deserialize_with().is_none() && attrs.de_bound().is_none()
+fn needs_deserialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool {
+    !field.skip_deserializing() &&
+    field.deserialize_with().is_none() &&
+    field.de_bound().is_none() &&
+    variant.map_or(true, |variant| variant.deserialize_with().is_none())
 }
 
 // Fields with a `default` attribute (not `default=...`), and fields with a
 // `skip_deserializing` attribute that do not also have `default=...`.
-fn requires_default(attrs: &attr::Field) -> bool {
-    attrs.default() == &attr::Default::Default
+fn requires_default(field: &attr::Field, _variant: Option<&attr::Variant>) -> bool {
+    field.default() == &attr::Default::Default
+}
+
+#[derive(Clone)]
+enum BorrowedLifetimes {
+    Borrowed(BTreeSet<syn::Lifetime>),
+    Static,
+}
+
+impl BorrowedLifetimes {
+    fn de_lifetime(&self) -> syn::Lifetime {
+        match *self {
+            BorrowedLifetimes::Borrowed(_) => syn::Lifetime::new("'de"),
+            BorrowedLifetimes::Static => syn::Lifetime::new("'static"),
+        }
+    }
+
+    fn de_lifetime_def(&self) -> Option<syn::LifetimeDef> {
+        match *self {
+            BorrowedLifetimes::Borrowed(ref bounds) => {
+                Some(syn::LifetimeDef {
+                    attrs: Vec::new(),
+                    lifetime: syn::Lifetime::new("'de"),
+                    bounds: bounds.iter().cloned().collect(),
+                })
+            }
+            BorrowedLifetimes::Static => None,
+        }
+    }
 }
 
 // The union of lifetimes borrowed by each field of the container.
 //
 // These turn into bounds on the `'de` lifetime of the Deserialize impl. If
 // lifetimes `'a` and `'b` are borrowed but `'c` is not, the impl is:
 //
 //     impl<'de: 'a + 'b, 'a, 'b, 'c> Deserialize<'de> for S<'a, 'b, 'c>
-fn borrowed_lifetimes(cont: &Container) -> BTreeSet<syn::Lifetime> {
+//
+// If any borrowed lifetime is `'static`, then `'de: 'static` would be redundant
+// and we use plain `'static` instead of `'de`.
+fn borrowed_lifetimes(cont: &Container) -> BorrowedLifetimes {
     let mut lifetimes = BTreeSet::new();
     for field in cont.body.all_fields() {
-        lifetimes.extend(field.attrs.borrowed_lifetimes().iter().cloned());
+        if !field.attrs.skip_deserializing() {
+            lifetimes.extend(field.attrs.borrowed_lifetimes().iter().cloned());
+        }
     }
-    lifetimes
+    if lifetimes.iter().any(|b| b.ident == "'static") {
+        BorrowedLifetimes::Static
+    } else {
+        BorrowedLifetimes::Borrowed(lifetimes)
+    }
 }
 
 fn deserialize_body(cont: &Container, params: &Parameters) -> Fragment {
     if let Some(from_type) = cont.attrs.from_type() {
         deserialize_from(from_type)
     } else if let attr::Identifier::No = cont.attrs.identifier() {
         match cont.body {
-            Body::Enum(ref variants) => deserialize_enum(params, variants, &cont.attrs),
+            Body::Enum(_, ref variants) => deserialize_enum(params, variants, &cont.attrs),
             Body::Struct(Style::Struct, ref fields) => {
                 if fields.iter().any(|field| field.ident.is_none()) {
                     panic!("struct has unnamed fields");
                 }
-                deserialize_struct(None, params, fields, &cont.attrs, None)
+                deserialize_struct(None, params, fields, &cont.attrs, None, Untagged::No)
             }
             Body::Struct(Style::Tuple, ref fields) |
             Body::Struct(Style::Newtype, ref fields) => {
                 if fields.iter().any(|field| field.ident.is_some()) {
                     panic!("tuple struct has named fields");
                 }
                 deserialize_tuple(None, params, fields, &cont.attrs, None)
             }
             Body::Struct(Style::Unit, _) => deserialize_unit_struct(params, &cont.attrs),
         }
     } else {
         match cont.body {
-            Body::Enum(ref variants) => {
+            Body::Enum(_, ref variants) => {
                 deserialize_custom_identifier(params, variants, &cont.attrs)
             }
             Body::Struct(_, _) => unreachable!("checked in serde_derive_internals"),
         }
     }
 }
 
+#[cfg(feature = "deserialize_from")]
+fn deserialize_from_body(cont: &Container, params: &Parameters) -> Option<Fragment> {
+    if let (None, attr::Identifier::No) = (cont.attrs.from_type(), cont.attrs.identifier()) {
+        match cont.body {
+            Body::Enum(ref repr, ref variants) => deserialize_from_enum(params, repr, variants, &cont.attrs),
+            Body::Struct(Style::Struct, ref fields) => {
+                deserialize_from_struct(None, params, fields, &cont.attrs, None, Untagged::No)
+            }
+            Body::Struct(Style::Tuple, ref fields) |
+            Body::Struct(Style::Newtype, ref fields) => {
+                deserialize_from_tuple(None, params, fields, &cont.attrs, None)
+            }
+            Body::Struct(Style::Unit, _) => None,
+        }
+    }  else {
+        None
+    }
+}
+
+#[cfg(not(feature = "deserialize_from"))]
+fn deserialize_from_body(_cont: &Container, _params: &Parameters) -> Option<Fragment> {
+    None
+}
+
 fn deserialize_from(from_type: &syn::Ty) -> Fragment {
     quote_block! {
         _serde::export::Result::map(
             <#from_type as _serde::Deserialize>::deserialize(__deserializer),
             _serde::export::From::from)
     }
 }
 
@@ -253,16 +326,17 @@ fn deserialize_tuple(
     variant_ident: Option<&syn::Ident>,
     params: &Parameters,
     fields: &[Field],
     cattrs: &attr::Container,
     deserializer: Option<Tokens>,
 ) -> Fragment {
     let this = &params.this;
     let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,);
+    let delife = params.borrowed.de_lifetime();
 
     // If there are getters (implying private fields), construct the local type
     // and use an `Into` conversion to get the remote type. If there are no
     // getters then construct the target type directly.
     let construct = if params.has_getter {
         let local = &params.local;
         quote!(#local)
     } else {
@@ -314,40 +388,153 @@ fn deserialize_tuple(
         quote!(_)
     } else {
         quote!(mut __seq)
     };
 
     quote_block! {
         struct __Visitor #de_impl_generics #where_clause {
             marker: _serde::export::PhantomData<#this #ty_generics>,
-            lifetime: _serde::export::PhantomData<&'de ()>,
+            lifetime: _serde::export::PhantomData<&#delife ()>,
         }
 
-        impl #de_impl_generics _serde::de::Visitor<'de> for __Visitor #de_ty_generics #where_clause {
+        impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
             type Value = #this #ty_generics;
 
             fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
                 _serde::export::Formatter::write_str(formatter, #expecting)
             }
 
             #visit_newtype_struct
 
             #[inline]
             fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error>
-                where __A: _serde::de::SeqAccess<'de>
+                where __A: _serde::de::SeqAccess<#delife>
             {
                 #visit_seq
             }
         }
 
         #dispatch
     }
 }
 
+#[cfg(feature = "deserialize_from")]
+fn deserialize_from_tuple(
+    variant_ident: Option<&syn::Ident>,
+    params: &Parameters,
+    fields: &[Field],
+    cattrs: &attr::Container,
+    deserializer: Option<Tokens>,
+) -> Option<Fragment> {
+    let this = &params.this;
+    let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,);
+    let delife = params.borrowed.de_lifetime();
+
+    // If there are getters (implying private fields), construct the local type
+    // and use an `Into` conversion to get the remote type. If there are no
+    // getters then construct the target type directly.
+    let construct = if params.has_getter {
+        let local = &params.local;
+        quote!(#local)
+    } else {
+        quote!(#this)
+    };
+
+    let is_enum = variant_ident.is_some();
+    let type_path = match variant_ident {
+        Some(variant_ident) => quote!(#construct::#variant_ident),
+        None => construct,
+    };
+    let expecting = match variant_ident {
+        Some(variant_ident) => format!("tuple variant {}::{}", params.type_name(), variant_ident),
+        None => format!("tuple struct {}", params.type_name()),
+    };
+
+    let nfields = fields.len();
+
+    let visit_newtype_struct = if !is_enum && nfields == 1 {
+        Some(deserialize_from_newtype_struct(&type_path, params, &fields[0]))
+    } else {
+        None
+    };
+
+    let visit_seq = Stmts(deserialize_from_seq(params, fields, is_enum, cattrs));
+
+    let visitor_expr = if is_enum {
+        quote! {
+            __Visitor {
+                dest: this,
+                lifetime: _serde::export::PhantomData,
+            }
+        }
+    } else {
+        quote! {
+            __Visitor {
+                dest: self,
+                lifetime: _serde::export::PhantomData,
+            }
+        }
+    };
+
+    let dispatch = if let Some(deserializer) = deserializer {
+        quote!(_serde::Deserializer::deserialize_tuple(#deserializer, #nfields, #visitor_expr))
+    } else if is_enum {
+        quote!(try!(_serde::de::VariantAccess::tuple_variant(__variant, #nfields, #visitor_expr)))
+    } else if nfields == 1 {
+        let type_name = cattrs.name().deserialize_name();
+        quote!(_serde::Deserializer::deserialize_newtype_struct(__deserializer, #type_name, #visitor_expr))
+    } else {
+        let type_name = cattrs.name().deserialize_name();
+        quote!(_serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #nfields, #visitor_expr))
+    };
+
+    let all_skipped = fields
+        .iter()
+        .all(|field| field.attrs.skip_deserializing());
+    let visitor_var = if all_skipped {
+        quote!(_)
+    } else {
+        quote!(mut __seq)
+    };
+
+    if params.has_getter {
+        None
+    } else {
+        let de_from_impl_generics = de_impl_generics.with_dest();
+        let de_from_ty_generics = de_ty_generics.with_dest();
+        let dest_life = dest_lifetime();
+        Some(quote_block! {
+            struct __Visitor #de_from_impl_generics #where_clause {
+                dest: &#dest_life mut #this #ty_generics,
+                lifetime: _serde::export::PhantomData<&#delife ()>,
+            }
+
+            impl #de_from_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_from_ty_generics #where_clause {
+                type Value = ();
+
+                fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
+                    _serde::export::Formatter::write_str(formatter, #expecting)
+                }
+
+                #visit_newtype_struct
+
+                #[inline]
+                fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error>
+                    where __A: _serde::de::SeqAccess<#delife>
+                {
+                    #visit_seq
+                }
+            }
+
+            #dispatch
+        })
+    }
+}
+
 fn deserialize_seq(
     type_path: &Tokens,
     params: &Parameters,
     fields: &[Field],
     is_struct: bool,
     cattrs: &attr::Container,
 ) -> Fragment {
     let vars = (0..fields.len()).map(field_i as fn(_) -> _);
@@ -368,30 +555,30 @@ fn deserialize_seq(
                 }
             } else {
                 let visit = match field.attrs.deserialize_with() {
                     None => {
                         let field_ty = &field.ty;
                         quote!(try!(_serde::de::SeqAccess::next_element::<#field_ty>(&mut __seq)))
                     }
                     Some(path) => {
-                        let (wrapper, wrapper_ty) = wrap_deserialize_with(
+                        let (wrapper, wrapper_ty) = wrap_deserialize_field_with(
                             params, field.ty, path);
                         quote!({
                             #wrapper
                             _serde::export::Option::map(
                                 try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)),
                                 |__wrap| __wrap.value)
                         })
                     }
                 };
                 let assign = quote! {
                     let #var = match #visit {
-                        Some(__value) => __value,
-                        None => {
+                        _serde::export::Some(__value) => __value,
+                        _serde::export::None => {
                             return _serde::export::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting));
                         }
                     };
                 };
                 index_in_seq += 1;
                 assign
             }
         });
@@ -415,26 +602,100 @@ fn deserialize_seq(
     }
 
     quote_block! {
         #(#let_values)*
         _serde::export::Ok(#result)
     }
 }
 
+#[cfg(feature = "deserialize_from")]
+fn deserialize_from_seq(
+    params: &Parameters,
+    fields: &[Field],
+    increment_fields: bool,
+    cattrs: &attr::Container,
+) -> Fragment {
+    // For enums there's a secret `tag` field at the start which we shouldn't touch, 
+    // so we need to bump all the indices up by 1.
+    let index_names = if increment_fields {
+        (0..fields.len())
+    } else {
+        (1..fields.len() + 1)
+    };
+    let vars = index_names.map(field_i as fn(_) -> _);
+
+    let deserialized_count = fields
+        .iter()
+        .filter(|field| !field.attrs.skip_deserializing())
+        .count();
+    let expecting = format!("tuple of {} elements", deserialized_count);
+
+    let mut index_in_seq = 0usize;
+    let write_values = vars.clone().zip(fields).enumerate()
+        .map(|(field_index, (_, field))| {
+            // If there's no field name, assume we're a tuple-struct and use a numeric index
+            let field_name = field.ident.clone()
+                .unwrap_or_else(|| Ident::new(field_index.to_string()));
+
+            if field.attrs.skip_deserializing() {
+                let default = Expr(expr_is_missing(&field, cattrs));
+                quote! {
+                    self.dest.#field_name = #default;
+                }
+            } else {
+                let handle_none = quote! {
+                    if visit.is_none() {
+                        return _serde::export::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting));
+                    }
+                };
+                let write = match field.attrs.deserialize_with() {
+                    None => {
+                        quote! {
+                            let visit = try!(_serde::de::SeqAccess::next_element_seed(&mut __seq,
+                                _serde::private::de::DeserializeFromSeed(&mut self.dest.#field_name)));
+                            #handle_none
+                        }
+                    }
+                    Some(path) => {
+                        let (wrapper, wrapper_ty) = wrap_deserialize_field_with(
+                            params, field.ty, path);
+                        quote!({
+                            #wrapper
+                            let visit = _serde::export::Option::map(
+                                try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)),
+                                |__wrap| __wrap.value);
+                            #handle_none
+                            self.dest.#field_name = visit.unwrap();
+                        })
+                    }
+                };
+                index_in_seq += 1;
+                write
+            }
+        });
+
+    quote_block! {
+        #(#write_values)*
+        _serde::export::Ok(())
+    }
+}
+
 fn deserialize_newtype_struct(type_path: &Tokens, params: &Parameters, field: &Field) -> Tokens {
+    let delife = params.borrowed.de_lifetime();
+
     let value = match field.attrs.deserialize_with() {
         None => {
             let field_ty = &field.ty;
             quote! {
                 try!(<#field_ty as _serde::Deserialize>::deserialize(__e))
             }
         }
         Some(path) => {
-            let (wrapper, wrapper_ty) = wrap_deserialize_with(params, field.ty, path);
+            let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
             quote!({
                 #wrapper
                 try!(<#wrapper_ty as _serde::Deserialize>::deserialize(__e)).value
             })
         }
     };
 
     let mut result = quote!(#type_path(#value));
@@ -443,35 +704,98 @@ fn deserialize_newtype_struct(type_path:
         result = quote! {
             _serde::export::Into::<#this>::into(#result)
         };
     }
 
     quote! {
         #[inline]
         fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error>
-            where __E: _serde::Deserializer<'de>
+            where __E: _serde::Deserializer<#delife>
         {
             _serde::export::Ok(#result)
         }
     }
 }
 
+#[cfg(feature = "deserialize_from")]
+fn deserialize_from_newtype_struct(
+    type_path: &Tokens,
+    params: &Parameters,
+    field: &Field
+) -> Tokens {
+    let delife = params.borrowed.de_lifetime();
+
+    // FIXME: can we reject this condition earlier so we don't have to handle it?
+    // If there's conversions that we need to do, we can't do this properly.
+    if field.attrs.deserialize_with().is_some() || params.has_getter {
+        let value = match field.attrs.deserialize_with() {
+            None => {
+                let field_ty = &field.ty;
+                quote! {
+                    try!(<#field_ty as _serde::Deserialize>::deserialize(__e))
+                }
+            }
+            Some(path) => {
+                let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
+                quote!({
+                    #wrapper
+                    try!(<#wrapper_ty as _serde::Deserialize>::deserialize(__e)).value
+                })
+            }
+        };
+
+        let mut result = quote!(#type_path(#value));
+        if params.has_getter {
+            let this = &params.this;
+            result = quote! {
+                _serde::export::Into::<#this>::into(#result)
+            };
+        }
+
+        quote! {
+            #[inline]
+            fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error>
+                where __E: _serde::Deserializer<#delife>
+            {
+                *self.dest = #result;
+                _serde::export::Ok(())
+            }
+        }
+    } else {
+        // No conversions, just recurse on the field.
+        quote! {
+            #[inline]
+            fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error>
+                where __E: _serde::Deserializer<#delife>
+            {
+                _serde::Deserialize::deserialize_from(&mut self.dest.0, __e)
+            }
+        }
+    }
+}
+
+enum Untagged {
+    Yes,
+    No,
+}
+
 fn deserialize_struct(
     variant_ident: Option<&syn::Ident>,
     params: &Parameters,
     fields: &[Field],
     cattrs: &attr::Container,
     deserializer: Option<Tokens>,
+    untagged: Untagged,
 ) -> Fragment {
     let is_enum = variant_ident.is_some();
-    let is_untagged = deserializer.is_some();
 
     let this = &params.this;
     let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,);
+    let delife = params.borrowed.de_lifetime();
 
     // If there are getters (implying private fields), construct the local type
     // and use an `Into` conversion to get the remote type. If there are no
     // getters then construct the target type directly.
     let construct = if params.has_getter {
         let local = &params.local;
         quote!(#local)
     } else {
@@ -520,61 +844,177 @@ fn deserialize_struct(
         .iter()
         .all(|field| field.attrs.skip_deserializing());
     let visitor_var = if all_skipped {
         quote!(_)
     } else {
         quote!(mut __seq)
     };
 
-    let visit_seq = if is_untagged {
-        // untagged struct variants do not get a visit_seq method
-        None
-    } else {
-        Some(quote! {
-            #[inline]
-            fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error>
-                where __A: _serde::de::SeqAccess<'de>
-            {
-                #visit_seq
-            }
-        })
+    // untagged struct variants do not get a visit_seq method
+    let visit_seq = match untagged {
+        Untagged::Yes => None,
+        Untagged::No => {
+            Some(quote! {
+                #[inline]
+                fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error>
+                    where __A: _serde::de::SeqAccess<#delife>
+                {
+                    #visit_seq
+                }
+            })
+        }
     };
 
     quote_block! {
         #field_visitor
 
         struct __Visitor #de_impl_generics #where_clause {
             marker: _serde::export::PhantomData<#this #ty_generics>,
-            lifetime: _serde::export::PhantomData<&'de ()>,
+            lifetime: _serde::export::PhantomData<&#delife ()>,
         }
 
-        impl #de_impl_generics _serde::de::Visitor<'de> for __Visitor #de_ty_generics #where_clause {
+        impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
             type Value = #this #ty_generics;
 
             fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
                 _serde::export::Formatter::write_str(formatter, #expecting)
             }
 
             #visit_seq
 
             #[inline]
             fn visit_map<__A>(self, mut __map: __A) -> _serde::export::Result<Self::Value, __A::Error>
-                where __A: _serde::de::MapAccess<'de>
+                where __A: _serde::de::MapAccess<#delife>
             {
                 #visit_map
             }
         }
 
         #fields_stmt
 
         #dispatch
     }
 }
 
+#[cfg(feature = "deserialize_from")]
+fn deserialize_from_struct(
+    variant_ident: Option<&syn::Ident>,
+    params: &Parameters,
+    fields: &[Field],
+    cattrs: &attr::Container,
+    deserializer: Option<Tokens>,
+    untagged: Untagged,
+) -> Option<Fragment> {
+    let is_enum = variant_ident.is_some();
+
+    let this = &params.this;
+    let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,);
+    let delife = params.borrowed.de_lifetime();
+
+    let expecting = match variant_ident {
+        Some(variant_ident) => format!("struct variant {}::{}", params.type_name(), variant_ident),
+        None => format!("struct {}", params.type_name()),
+    };
+
+    let visit_seq = Stmts(deserialize_from_seq(params, fields, false, cattrs));
+
+    let (field_visitor, fields_stmt, visit_map) =
+        deserialize_from_struct_visitor(params, fields, cattrs);
+    let field_visitor = Stmts(field_visitor);
+    let fields_stmt = Stmts(fields_stmt);
+    let visit_map = Stmts(visit_map);
+
+    let visitor_expr = quote! {
+        __Visitor {
+            dest: self,
+            lifetime: _serde::export::PhantomData,
+        }
+    };
+    let dispatch = if let Some(deserializer) = deserializer {
+        quote! {
+            _serde::Deserializer::deserialize_any(#deserializer, #visitor_expr)
+        }
+    } else if is_enum {
+        quote! {
+            _serde::de::VariantAccess::struct_variant(__variant, FIELDS, #visitor_expr)
+        }
+    } else {
+        let type_name = cattrs.name().deserialize_name();
+        quote! {
+            _serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, #visitor_expr)
+        }
+    };
+
+
+    let all_skipped = fields
+        .iter()
+        .all(|field| field.attrs.skip_deserializing());
+    let visitor_var = if all_skipped {
+        quote!(_)
+    } else {
+        quote!(mut __seq)
+    };
+
+    // untagged struct variants do not get a visit_seq method
+    let visit_seq = match untagged {
+        Untagged::Yes => None,
+        Untagged::No => {
+            Some(quote! {
+                #[inline]
+                fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error>
+                    where __A: _serde::de::SeqAccess<#delife>
+                {
+                    #visit_seq
+                }
+            })
+
+        }
+    };
+
+    if params.has_getter {
+        None
+    } else {
+        let de_from_impl_generics = de_impl_generics.with_dest();
+        let de_from_ty_generics = de_ty_generics.with_dest();
+        let dest_life = dest_lifetime();
+
+        Some(quote_block! {
+            #field_visitor
+
+            struct __Visitor #de_from_impl_generics #where_clause {
+                dest: &#dest_life mut #this #ty_generics,
+                lifetime: _serde::export::PhantomData<&#delife ()>,
+            }
+
+            impl #de_from_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_from_ty_generics #where_clause {
+                type Value = ();
+
+                fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
+                    _serde::export::Formatter::write_str(formatter, #expecting)
+                }
+
+                #visit_seq
+
+                #[inline]
+                #[allow(unreachable_code)]
+                fn visit_map<__A>(self, mut __map: __A) -> _serde::export::Result<Self::Value, __A::Error>
+                    where __A: _serde::de::MapAccess<#delife>
+                {
+                    #visit_map
+                }
+            }
+
+            #fields_stmt
+
+            #dispatch
+        })
+    }
+}
+
 fn deserialize_enum(
     params: &Parameters,
     variants: &[Variant],
     cattrs: &attr::Container,
 ) -> Fragment {
     match *cattrs.tag() {
         attr::EnumTag::External => deserialize_externally_tagged_enum(params, variants, cattrs),
         attr::EnumTag::Internal { ref tag } => {
@@ -583,23 +1023,37 @@ fn deserialize_enum(
         attr::EnumTag::Adjacent {
             ref tag,
             ref content,
         } => deserialize_adjacently_tagged_enum(params, variants, cattrs, tag, content),
         attr::EnumTag::None => deserialize_untagged_enum(params, variants, cattrs),
     }
 }
 
+#[cfg(feature = "deserialize_from")]
+fn deserialize_from_enum(
+    params: &Parameters,
+    repr: &Repr,
+    variants: &[Variant],
+    cattrs: &attr::Container,
+) -> Option<Fragment> {
+    match *cattrs.tag() {
+        attr::EnumTag::External => deserialize_from_externally_tagged_enum(params, repr, variants, cattrs),
+        _ => None,
+    }
+}
+
 fn deserialize_externally_tagged_enum(
     params: &Parameters,
     variants: &[Variant],
     cattrs: &attr::Container,
 ) -> Fragment {
     let this = &params.this;
     let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,);
+    let delife = params.borrowed.de_lifetime();
 
     let type_name = cattrs.name().deserialize_name();
 
     let expecting = format!("enum {}", params.type_name());
 
     let variant_names_idents: Vec<_> = variants
         .iter()
         .enumerate()
@@ -655,43 +1109,290 @@ fn deserialize_externally_tagged_enum(
         }
     };
 
     quote_block! {
         #variant_visitor
 
         struct __Visitor #de_impl_generics #where_clause {
             marker: _serde::export::PhantomData<#this #ty_generics>,
-            lifetime: _serde::export::PhantomData<&'de ()>,
+            lifetime: _serde::export::PhantomData<&#delife ()>,
         }
 
-        impl #de_impl_generics _serde::de::Visitor<'de> for __Visitor #de_ty_generics #where_clause {
+        impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
             type Value = #this #ty_generics;
 
             fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
                 _serde::export::Formatter::write_str(formatter, #expecting)
             }
 
             fn visit_enum<__A>(self, __data: __A) -> _serde::export::Result<Self::Value, __A::Error>
-                where __A: _serde::de::EnumAccess<'de>
+                where __A: _serde::de::EnumAccess<#delife>
             {
                 #match_variant
             }
         }
 
         #variants_stmt
 
         _serde::Deserializer::deserialize_enum(__deserializer, #type_name, VARIANTS,
                                                __Visitor {
                                                    marker: _serde::export::PhantomData::<#this #ty_generics>,
                                                    lifetime: _serde::export::PhantomData,
                                                })
     }
 }
 
+#[cfg(feature = "deserialize_from")]
+fn deserialize_from_externally_tagged_enum(
+    params: &Parameters,
+    repr: &Repr,
+    variants: &[Variant],
+    cattrs: &attr::Container,
+) -> Option<Fragment> {
+    let int_repr = repr.get_stable_rust_enum_layout().map(|int_repr| {
+        let int_repr = Ident::new(int_repr);
+        quote!(#[repr(#int_repr)])
+    });
+    
+    let unit_variant = variants.iter().position(|variant| is_unit(variant));
+    let non_unit_variant = variants.iter().enumerate().find(|&(_, variant)| !is_unit(variant));
+    
+    // We need an int_repr, unit variant, and a non-unit variant to proceed
+    if int_repr.is_none() || unit_variant.is_none() || non_unit_variant.is_none() { 
+        return None;
+    }
+
+    let unit_index = unit_variant.unwrap();
+    let (non_unit_index, non_unit_variant) = non_unit_variant.unwrap();
+    let int_repr = int_repr.unwrap();
+
+    let this = &params.this;
+    let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,);
+    let delife = params.borrowed.de_lifetime();
+
+    let type_name = cattrs.name().deserialize_name();
+
+    let expecting = format!("enum {}", params.type_name());
+
+    let variant_names_idents: Vec<_> = variants
+        .iter()
+        .enumerate()
+        .filter(|&(_, variant)| !variant.attrs.skip_deserializing())
+        .map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)),)
+        .collect();
+
+    let variants_stmt = {
+        let variant_names = variant_names_idents.iter().map(|&(ref name, _)| name);
+        quote! {
+            const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ];
+        }
+    };
+
+    let variant_visitor = Stmts(deserialize_generated_identifier(variant_names_idents, cattrs, true),);
+
+    let non_unit_field = field_i(non_unit_index);
+    let tag_access = match non_unit_variant.style {
+        Style::Struct => {
+            quote!(repr.#non_unit_field.tag)
+        }
+        Style::Tuple | Style::Newtype => {
+            quote!(repr.#non_unit_field.0)
+        }
+        _ => unreachable!()
+    };
+
+    let mut sub_params = params.clone();
+    let variant_arms_from = variants
+        .iter()
+        .enumerate()
+        .filter(|&(_, variant)| !variant.attrs.skip_deserializing())
+        .map(
+            |(i, variant)| {
+                let variant_name = field_i(i);
+                sub_params.this = syn::Path::from(variant_name.clone());
+
+                let this_decl = if is_unit(variant) {
+                    None
+                } else {
+                    Some(quote!(let this = &mut repr.#variant_name;))
+                };
+                let block = Stmts(deserialize_from_externally_tagged_variant(&sub_params, variant, cattrs));
+                quote! {
+                    (__Field::#variant_name, __variant) => {
+                        {
+                            #this_decl
+                            #block;
+                        }
+                        #tag_access = __Tag::#variant_name;
+                        _serde::export::Result::Ok(())
+                    }
+                }
+            },
+        );
+
+    let all_skipped = variants
+        .iter()
+        .all(|variant| variant.attrs.skip_deserializing());
+
+    let match_variant_from = if all_skipped {
+        // This is an empty enum like `enum Impossible {}` or an enum in which
+        // all variants have `#[serde(skip_deserializing)]`.
+        quote! {
+            // FIXME: Once we drop support for Rust 1.15:
+            // let _serde::export::Err(__err) = _serde::de::EnumAccess::variant::<__Field>(__data);
+            // _serde::export::Err(__err)
+            _serde::export::Result::map(
+                _serde::de::EnumAccess::variant::<__Field>(__data),
+                |(__impossible, _)| match __impossible {})
+        }
+    } else {
+        let unit_field = field_i(unit_index);
+        
+        quote! {
+            unsafe {
+                let repr = ::std::mem::transmute::<&mut #this #ty_generics, &mut __EnumRepr>(self.dest);
+                #tag_access = __Tag::#unit_field;
+                match try!(_serde::de::EnumAccess::variant(__data)) {
+                    #(#variant_arms_from)*
+                }
+            }
+        }
+    };
+
+    let repr_cases = variants
+        .iter()
+        .enumerate()
+        .filter_map(
+            |(i, variant)| {
+                if is_unit(&variant) {
+                    None
+                } else {
+                    let variant_name = field_i(i);
+                    Some(quote!(#variant_name: #variant_name))
+                }
+            }
+        );
+
+    let tag_cases = variants
+        .iter()
+        .enumerate()
+        .map(
+            |(i, _variant)| {
+                let variant_name = field_i(i);
+
+                quote!(#variant_name)
+            }
+        );
+    
+
+    let repr_payloads = variants
+        .iter()
+        .enumerate()
+        .filter_map(
+            |(i, variant)| {
+                let variant_name = field_i(i);
+                match variant.style {
+                    Style::Struct => {
+                        let fields = variant.fields.iter().enumerate().map(|(j, field)| {
+                            let field_name = field_i(j);
+                            let field_ty = field.ty;
+                            quote!(#field_name: #field_ty)
+                        });
+
+                        let payload = quote! {
+                            #[repr(C)]
+                            #[derive(Copy, Clone)]
+                            #[allow(non_camel_case_types)]
+                            struct #variant_name #ty_generics {
+                                tag: __Tag,
+                                #(#fields),*
+                            }
+                        };
+                        Some(payload)
+                    }
+                    Style::Tuple | Style::Newtype => {
+                        let fields = variant.fields.iter().map(|field| {
+                            let field_ty = field.ty;
+                            quote!(#field_ty)
+                        });
+
+                        let payload = quote! {
+                            #[repr(C)]
+                            #[derive(Copy, Clone)]
+                            #[allow(non_camel_case_types)]
+                            struct #variant_name #ty_generics (
+                                __Tag,
+                                #(#fields),*
+
+                            );
+                        };
+                        Some(payload)
+                    }
+                    Style::Unit => None,
+                }
+                
+            }
+        );
+
+    let raw_repr = quote! {
+        #[repr(C)]
+        #[allow(non_camel_case_types)]
+        union __EnumRepr #ty_generics {
+            #(#repr_cases),*
+        }
+
+        #int_repr
+        #[derive(Copy, Clone)]
+        #[allow(non_camel_case_types)]
+        enum __Tag {
+            #(#tag_cases),*
+        }
+
+        #(#repr_payloads)*
+    };
+
+    let de_from_impl_generics = de_impl_generics.with_dest();
+    let de_from_ty_generics = de_ty_generics.with_dest();
+    let dest_life = dest_lifetime();
+
+    Some(quote_block! {
+        #variant_visitor
+
+        struct __Visitor #de_from_impl_generics #where_clause {
+            dest: &#dest_life mut #this #ty_generics,
+            lifetime: _serde::export::PhantomData<&#delife ()>,
+        }
+
+        impl #de_from_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_from_ty_generics #where_clause {
+            type Value = ();
+
+            fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
+                _serde::export::Formatter::write_str(formatter, #expecting)
+            }
+
+            fn visit_enum<__A>(self, __data: __A) -> _serde::export::Result<Self::Value, __A::Error>
+                where __A: _serde::de::EnumAccess<#delife>
+            {
+                #raw_repr
+
+                #match_variant_from
+            }
+        }
+
+        #variants_stmt
+
+        _serde::Deserializer::deserialize_enum(__deserializer, #type_name, VARIANTS,
+                                               __Visitor {
+                                                   dest: self,
+                                                   lifetime: _serde::export::PhantomData,
+                                               })
+    })
+}
+
 fn deserialize_internally_tagged_enum(
     params: &Parameters,
     variants: &[Variant],
     cattrs: &attr::Container,
     tag: &str,
 ) -> Fragment {
     let variant_names_idents: Vec<_> = variants
         .iter()
@@ -747,16 +1448,17 @@ fn deserialize_adjacently_tagged_enum(
     params: &Parameters,
     variants: &[Variant],
     cattrs: &attr::Container,
     tag: &str,
     content: &str,
 ) -> Fragment {
     let this = &params.this;
     let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,);
+    let delife = params.borrowed.de_lifetime();
 
     let variant_names_idents: Vec<_> = variants
         .iter()
         .enumerate()
         .filter(|&(_, variant)| !variant.attrs.skip_deserializing())
         .map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)),)
         .collect();
 
@@ -792,39 +1494,31 @@ fn deserialize_adjacently_tagged_enum(
             },
         )
         .collect();
 
     let expecting = format!("adjacently tagged enum {}", params.type_name());
     let type_name = cattrs.name().deserialize_name();
     let deny_unknown_fields = cattrs.deny_unknown_fields();
 
-    /// If unknown fields are allowed, we pick the visitor that can
-    /// step over those. Otherwise we pick the visitor that fails on
-    /// unknown keys.
+    // If unknown fields are allowed, we pick the visitor that can step over
+    // those. Otherwise we pick the visitor that fails on unknown keys.
     let field_visitor_ty = if deny_unknown_fields {
         quote! { _serde::private::de::TagOrContentFieldVisitor }
     } else {
         quote! { _serde::private::de::TagContentOtherFieldVisitor }
     };
 
     let tag_or_content = quote! {
         #field_visitor_ty {
             tag: #tag,
             content: #content,
         }
     };
 
-    fn is_unit(variant: &Variant) -> bool {
-        match variant.style {
-            Style::Unit => true,
-            Style::Struct | Style::Tuple | Style::Newtype => false,
-        }
-    }
-
     let mut missing_content = quote! {
         _serde::export::Err(<__A::Error as _serde::de::Error>::missing_field(#content))
     };
     if variants.iter().any(is_unit) {
         let fallthrough = if variants.iter().all(is_unit) {
             None
         } else {
             Some(
@@ -849,23 +1543,23 @@ fn deserialize_adjacently_tagged_enum(
         missing_content = quote! {
             match __field {
                 #(#arms)*
                 #fallthrough
             }
         };
     }
 
-    /// Advance the map by one key, returning early in case of error.
+    // Advance the map by one key, returning early in case of error.
     let next_key = quote! {
         try!(_serde::de::MapAccess::next_key_seed(&mut __map, #tag_or_content))
     };
 
-    /// When allowing unknown fields, we want to transparently step through keys we don't care
-    /// about until we find `tag`, `content`, or run out of keys.
+    // When allowing unknown fields, we want to transparently step through keys
+    // we don't care about until we find `tag`, `content`, or run out of keys.
     let next_relevant_key = if deny_unknown_fields {
         next_key
     } else {
         quote! {
             {
                 let mut __rk : _serde::export::Option<_serde::private::de::TagOrContentField> = _serde::export::None;
                 while let _serde::export::Some(__k) = #next_key {
                     match __k {
@@ -884,19 +1578,19 @@ fn deserialize_adjacently_tagged_enum(
                     }
                 }
 
                 __rk
             }
         }
     };
 
-    /// Step through remaining keys, looking for duplicates of previously-seen keys.
-    /// When unknown fields are denied, any key that isn't a duplicate will at this
-    /// point immediately produce an error.
+    // Step through remaining keys, looking for duplicates of previously-seen
+    // keys. When unknown fields are denied, any key that isn't a duplicate will
+    // at this point immediately produce an error.
     let visit_remaining_keys = quote! {
         match #next_relevant_key {
             _serde::export::Some(_serde::private::de::TagOrContentField::Tag) => {
                 _serde::export::Err(<__A::Error as _serde::de::Error>::duplicate_field(#tag))
             }
             _serde::export::Some(_serde::private::de::TagOrContentField::Content) => {
                 _serde::export::Err(<__A::Error as _serde::de::Error>::duplicate_field(#content))
             }
@@ -907,45 +1601,45 @@ fn deserialize_adjacently_tagged_enum(
     quote_block! {
         #variant_visitor
 
         #variants_stmt
 
         struct __Seed #de_impl_generics #where_clause {
             field: __Field,
             marker: _serde::export::PhantomData<#this #ty_generics>,
-            lifetime: _serde::export::PhantomData<&'de ()>,
+            lifetime: _serde::export::PhantomData<&#delife ()>,
         }
 
-        impl #de_impl_generics _serde::de::DeserializeSeed<'de> for __Seed #de_ty_generics #where_clause {
+        impl #de_impl_generics _serde::de::DeserializeSeed<#delife> for __Seed #de_ty_generics #where_clause {
             type Value = #this #ty_generics;
 
             fn deserialize<__D>(self, __deserializer: __D) -> _serde::export::Result<Self::Value, __D::Error>
-                where __D: _serde::Deserializer<'de>
+                where __D: _serde::Deserializer<#delife>
             {
                 match self.field {
                     #(#variant_arms)*
                 }
             }
         }
 
         struct __Visitor #de_impl_generics #where_clause {
             marker: _serde::export::PhantomData<#this #ty_generics>,
-            lifetime: _serde::export::PhantomData<&'de ()>,
+            lifetime: _serde::export::PhantomData<&#delife ()>,
         }
 
-        impl #de_impl_generics _serde::de::Visitor<'de> for __Visitor #de_ty_generics #where_clause {
+        impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
             type Value = #this #ty_generics;
 
             fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
                 _serde::export::Formatter::write_str(formatter, #expecting)
             }
 
             fn visit_map<__A>(self, mut __map: __A) -> _serde::export::Result<Self::Value, __A::Error>
-                where __A: _serde::de::MapAccess<'de>
+                where __A: _serde::de::MapAccess<#delife>
             {
                 // Visit the first relevant key.
                 match #next_relevant_key {
                     // First key is the tag.
                     _serde::export::Some(_serde::private::de::TagOrContentField::Tag) => {
                         // Parse the tag.
                         let __field = try!(_serde::de::MapAccess::next_value(&mut __map));
                         // Visit the second key.
@@ -999,17 +1693,17 @@ fn deserialize_adjacently_tagged_enum(
                     // There is no first key.
                     _serde::export::None => {
                         _serde::export::Err(<__A::Error as _serde::de::Error>::missing_field(#tag))
                     }
                 }
             }
 
             fn visit_seq<__A>(self, mut __seq: __A) -> _serde::export::Result<Self::Value, __A::Error>
-                where __A: _serde::de::SeqAccess<'de>
+                where __A: _serde::de::SeqAccess<#delife>
             {
                 // Visit the first element - the tag.
                 match try!(_serde::de::SeqAccess::next_element(&mut __seq)) {
                     _serde::export::Some(__field) => {
                         // Visit the second element - the content.
                         match try!(_serde::de::SeqAccess::next_element_seed(&mut __seq,
                                 __Seed {
                                     field: __field,
@@ -1081,16 +1775,26 @@ fn deserialize_untagged_enum(
     }
 }
 
 fn deserialize_externally_tagged_variant(
     params: &Parameters,
     variant: &Variant,
     cattrs: &attr::Container,
 ) -> Fragment {
+    if let Some(path) = variant.attrs.deserialize_with() {
+        let (wrapper, wrapper_ty, unwrap_fn) =
+            wrap_deserialize_variant_with(params, &variant, path);
+        return quote_block! {
+            #wrapper
+            _serde::export::Result::map(
+                _serde::de::VariantAccess::newtype_variant::<#wrapper_ty>(__variant), #unwrap_fn)
+        };
+    }
+
     let variant_ident = &variant.ident;
 
     match variant.style {
         Style::Unit => {
             let this = &params.this;
             quote_block! {
                 try!(_serde::de::VariantAccess::unit_variant(__variant));
                 _serde::export::Ok(#this::#variant_ident)
@@ -1098,52 +1802,121 @@ fn deserialize_externally_tagged_variant
         }
         Style::Newtype => {
             deserialize_externally_tagged_newtype_variant(variant_ident, params, &variant.fields[0])
         }
         Style::Tuple => {
             deserialize_tuple(Some(variant_ident), params, &variant.fields, cattrs, None)
         }
         Style::Struct => {
-            deserialize_struct(Some(variant_ident), params, &variant.fields, cattrs, None)
+            deserialize_struct(Some(variant_ident), params, &variant.fields, cattrs, None, Untagged::No)
+        }
+    }
+}
+
+#[cfg(feature = "deserialize_from")]
+fn deserialize_from_externally_tagged_variant(
+    params: &Parameters,
+    variant: &Variant,
+    cattrs: &attr::Container,
+) -> Fragment {
+    if let Some(_path) = variant.attrs.deserialize_with() {
+        unimplemented!()
+        /*
+        let (wrapper, wrapper_ty, unwrap_fn) =
+            wrap_deserialize_variant_with(params, &variant, path);
+        return quote_block! {
+            #wrapper
+            _serde::export::Result::map(
+                _serde::de::VariantAccess::newtype_variant::<#wrapper_ty>(__variant), #unwrap_fn)
+        };
+        */
+    }
+
+    let variant_ident = &variant.ident;
+
+    match variant.style {
+        Style::Unit => {
+            quote_block! {
+                try!(_serde::de::VariantAccess::unit_variant(__variant));
+            }
+        }
+        Style::Newtype => {
+            deserialize_from_externally_tagged_newtype_variant(variant_ident, params, &variant.fields[0])
+        }
+        Style::Tuple => {
+            deserialize_from_tuple(Some(variant_ident), params, &variant.fields, cattrs, None).expect("???")
+        }
+        Style::Struct => {
+            unimplemented!()
+            // deserialize_struct(None, params, &variant.fields, cattrs, None, Untagged::No).0
         }
     }
 }
 
 fn deserialize_internally_tagged_variant(
     params: &Parameters,
     variant: &Variant,
     cattrs: &attr::Container,
     deserializer: Tokens,
 ) -> Fragment {
+    if variant.attrs.deserialize_with().is_some() {
+        return deserialize_untagged_variant(params, variant, cattrs, deserializer);
+    }
+
     let variant_ident = &variant.ident;
 
     match variant.style {
         Style::Unit => {
             let this = &params.this;
             let type_name = params.type_name();
             let variant_name = variant.ident.as_ref();
             quote_block! {
                 try!(_serde::Deserializer::deserialize_any(#deserializer, _serde::private::de::InternallyTaggedUnitVisitor::new(#type_name, #variant_name)));
                 _serde::export::Ok(#this::#variant_ident)
             }
         }
-        Style::Newtype | Style::Struct => {
-            deserialize_untagged_variant(params, variant, cattrs, deserializer)
+        Style::Newtype => {
+            deserialize_untagged_newtype_variant(
+                variant_ident,
+                params,
+                &variant.fields[0],
+                deserializer,
+            )
+        }
+        Style::Struct => {
+            deserialize_struct(
+                Some(variant_ident),
+                params,
+                &variant.fields,
+                cattrs,
+                Some(deserializer),
+                Untagged::No,
+            )
         }
         Style::Tuple => unreachable!("checked in serde_derive_internals"),
     }
 }
 
 fn deserialize_untagged_variant(
     params: &Parameters,
     variant: &Variant,
     cattrs: &attr::Container,
     deserializer: Tokens,
 ) -> Fragment {
+    if let Some(path) = variant.attrs.deserialize_with() {
+        let (wrapper, wrapper_ty, unwrap_fn) =
+            wrap_deserialize_variant_with(params, &variant, path);
+        return quote_block! {
+            #wrapper
+            _serde::export::Result::map(
+                <#wrapper_ty as _serde::Deserialize>::deserialize(#deserializer), #unwrap_fn)
+        };
+    }
+
     let variant_ident = &variant.ident;
 
     match variant.style {
         Style::Unit => {
             let this = &params.this;
             let type_name = params.type_name();
             let variant_name = variant.ident.as_ref();
             quote_expr! {
@@ -1174,16 +1947,17 @@ fn deserialize_untagged_variant(
         }
         Style::Struct => {
             deserialize_struct(
                 Some(variant_ident),
                 params,
                 &variant.fields,
                 cattrs,
                 Some(deserializer),
+                Untagged::Yes,
             )
         }
     }
 }
 
 fn deserialize_externally_tagged_newtype_variant(
     variant_ident: &syn::Ident,
     params: &Parameters,
@@ -1195,27 +1969,54 @@ fn deserialize_externally_tagged_newtype
             let field_ty = &field.ty;
             quote_expr! {
                 _serde::export::Result::map(
                     _serde::de::VariantAccess::newtype_variant::<#field_ty>(__variant),
                     #this::#variant_ident)
             }
         }
         Some(path) => {
-            let (wrapper, wrapper_ty) = wrap_deserialize_with(params, field.ty, path);
+            let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
             quote_block! {
                 #wrapper
                 _serde::export::Result::map(
                     _serde::de::VariantAccess::newtype_variant::<#wrapper_ty>(__variant),
                     |__wrapper| #this::#variant_ident(__wrapper.value))
             }
         }
     }
 }
 
+fn deserialize_from_externally_tagged_newtype_variant(
+    _variant_ident: &syn::Ident,
+    params: &Parameters,
+    field: &Field,
+) -> Fragment {
+    let _this = &params.this;
+    match field.attrs.deserialize_with() {
+        None => {
+            quote_expr! {
+                try!(_serde::de::VariantAccess::newtype_variant_seed(__variant, _serde::private::de::DeserializeFromSeed(&mut this.1)));
+            }
+        }
+        Some(_path) => {
+            unimplemented!();
+            /*
+            let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
+            quote_block! {
+                #wrapper
+                _serde::export::Result::map(
+                    _serde::de::VariantAccess::newtype_variant::<#wrapper_ty>(__variant),
+                    |__wrapper| #this::#variant_ident(__wrapper.value))
+            }
+            */
+        }
+    }
+}
+
 fn deserialize_untagged_newtype_variant(
     variant_ident: &syn::Ident,
     params: &Parameters,
     field: &Field,
     deserializer: Tokens,
 ) -> Fragment {
     let this = &params.this;
     match field.attrs.deserialize_with() {
@@ -1223,17 +2024,17 @@ fn deserialize_untagged_newtype_variant(
             let field_ty = &field.ty;
             quote_expr! {
                 _serde::export::Result::map(
                     <#field_ty as _serde::Deserialize>::deserialize(#deserializer),
                     #this::#variant_ident)
             }
         }
         Some(path) => {
-            let (wrapper, wrapper_ty) = wrap_deserialize_with(params, field.ty, path);
+            let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
             quote_block! {
                 #wrapper
                 _serde::export::Result::map(
                     <#wrapper_ty as _serde::Deserialize>::deserialize(#deserializer),
                     |__wrapper| #this::#variant_ident(__wrapper.value))
             }
         }
     }
@@ -1336,28 +2137,29 @@ fn deserialize_custom_identifier(
     } else {
         let fields = quote! {
             const FIELDS: &'static [&'static str] = &[ #(#names),* ];
         };
         Some(fields)
     };
 
     let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,);
+    let delife = params.borrowed.de_lifetime();
     let visitor_impl =
         Stmts(deserialize_identifier(this.clone(), &names_idents, is_variant, fallthrough),);
 
     quote_block! {
         #names_const
 
         struct __FieldVisitor #de_impl_generics #where_clause {
             marker: _serde::export::PhantomData<#this #ty_generics>,
-            lifetime: _serde::export::PhantomData<&'de ()>,
+            lifetime: _serde::export::PhantomData<&#delife ()>,
         }
 
-        impl #de_impl_generics _serde::de::Visitor<'de> for __FieldVisitor #de_ty_generics #where_clause {
+        impl #de_impl_generics _serde::de::Visitor<#delife> for __FieldVisitor #de_ty_generics #where_clause {
             type Value = #this #ty_generics;
 
             #visitor_impl
         }
 
         let __visitor = __FieldVisitor {
             marker: _serde::export::PhantomData::<#this #ty_generics>,
             lifetime: _serde::export::PhantomData,
@@ -1381,36 +2183,37 @@ fn deserialize_identifier(
                                      .collect();
 
     let expecting = if is_variant {
         "variant identifier"
     } else {
         "field identifier"
     };
 
-    let visit_index = if is_variant {
-        let variant_indices = 0u32..;
-        let fallthrough_msg = format!("variant index 0 <= i < {}", fields.len());
-        let visit_index = quote! {
-            fn visit_u32<__E>(self, __value: u32) -> _serde::export::Result<Self::Value, __E>
-                where __E: _serde::de::Error
-            {
-                match __value {
-                    #(
-                        #variant_indices => _serde::export::Ok(#constructors),
-                    )*
-                    _ => _serde::export::Err(_serde::de::Error::invalid_value(
-                                _serde::de::Unexpected::Unsigned(__value as u64),
-                                &#fallthrough_msg))
-                }
+    let index_expecting = if is_variant {
+        "variant"
+    } else {
+        "field"
+    };
+
+    let variant_indices = 0u64..;
+    let fallthrough_msg = format!("{} index 0 <= i < {}", index_expecting, fields.len());
+    let visit_index = quote! {
+        fn visit_u64<__E>(self, __value: u64) -> _serde::export::Result<Self::Value, __E>
+            where __E: _serde::de::Error
+        {
+            match __value {
+                #(
+                    #variant_indices => _serde::export::Ok(#constructors),
+                )*
+                _ => _serde::export::Err(_serde::de::Error::invalid_value(
+                            _serde::de::Unexpected::Unsigned(__value),
+                            &#fallthrough_msg))
             }
-        };
-        Some(visit_index)
-    } else {
-        None
+        }
     };
 
     let bytes_to_str = if fallthrough.is_some() {
         None
     } else {
         let conversion = quote! {
             let __value = &_serde::export::from_utf8_lossy(__value);
         };
@@ -1525,17 +2328,17 @@ fn deserialize_map(
             let visit = match field.attrs.deserialize_with() {
                 None => {
                     let field_ty = &field.ty;
                     quote! {
                         try!(_serde::de::MapAccess::next_value::<#field_ty>(&mut __map))
                     }
                 }
                 Some(path) => {
-                    let (wrapper, wrapper_ty) = wrap_deserialize_with(
+                    let (wrapper, wrapper_ty) = wrap_deserialize_field_with(
                         params, field.ty, path);
                     quote!({
                         #wrapper
                         try!(_serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map)).value
                     })
                 }
             };
             quote! {
@@ -1650,55 +2453,288 @@ fn deserialize_map(
         #let_default
 
         #(#extract_values)*
 
         _serde::export::Ok(#result)
     }
 }
 
+#[cfg(feature = "deserialize_from")]
+fn deserialize_from_struct_visitor(
+    params: &Parameters,
+    fields: &[Field],
+    cattrs: &attr::Container,
+) -> (Fragment, Fragment, Fragment) {
+    let field_names_idents: Vec<_> = fields
+        .iter()
+        .enumerate()
+        .filter(|&(_, field)| !field.attrs.skip_deserializing())
+        .map(|(i, field)| (field.attrs.name().deserialize_name(), field_i(i)),)
+        .collect();
+
+    let fields_stmt = {
+        let field_names = field_names_idents.iter().map(|&(ref name, _)| name);
+        quote_block! {
+            const FIELDS: &'static [&'static str] = &[ #(#field_names),* ];
+        }
+    };
+
+    let field_visitor = deserialize_generated_identifier(field_names_idents, cattrs, false);
+
+    let visit_map = deserialize_from_map(params, fields, cattrs);
+
+    (field_visitor, fields_stmt, visit_map)
+}
+
+#[cfg(feature = "deserialize_from")]
+fn deserialize_from_map(
+    params: &Parameters,
+    fields: &[Field],
+    cattrs: &attr::Container,
+) -> Fragment {
+    // Create the field names for the fields.
+    let fields_names: Vec<_> = fields
+        .iter()
+        .enumerate()
+        .map(|(i, field)| (field, field_i(i)))
+        .collect();
+
+    // For deserialize_from, declare booleans for each field that will be deserialized.
+    let let_flags = fields_names
+        .iter()
+        .filter(|&&(field, _)| !field.attrs.skip_deserializing())
+        .map(
+            |&(_, ref name)| {
+                quote! {
+                    let mut #name: bool = false;
+                }
+            },
+        );
+
+    // Match arms to extract a value for a field.
+    let value_arms_from = fields_names.iter()
+        .filter(|&&(field, _)| !field.attrs.skip_deserializing())
+        .map(|&(field, ref name)| {
+            let deser_name = field.attrs.name().deserialize_name();
+            let field_name = &field.ident;
+
+            let visit = match field.attrs.deserialize_with() {
+                None => {
+                    quote! {
+                        try!(_serde::de::MapAccess::next_value_seed(&mut __map, _serde::private::de::DeserializeFromSeed(&mut self.dest.#field_name)))
+                    }
+                }
+                Some(path) => {
+                    let (wrapper, wrapper_ty) = wrap_deserialize_field_with(
+                        params, field.ty, path);
+                    quote!({
+                        #wrapper
+                        self.dest.#field_name = try!(_serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map)).value
+                    })
+                }
+            };
+            quote! {
+                __Field::#name => {
+                    if #name {
+                        return _serde::export::Err(<__A::Error as _serde::de::Error>::duplicate_field(#deser_name));
+                    }
+                    #visit;
+                    #name = true;
+                }
+            }
+        });
+
+    // Visit ignored values to consume them
+    let ignored_arm = if cattrs.deny_unknown_fields() {
+        None
+    } else {
+        Some(quote! {
+            _ => { let _ = try!(_serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)); }
+        })
+    };
+
+    let all_skipped = fields
+        .iter()
+        .all(|field| field.attrs.skip_deserializing());
+
+    let match_keys = if cattrs.deny_unknown_fields() && all_skipped {
+        quote! {
+            // FIXME: Once we drop support for Rust 1.15:
+            // let _serde::export::None::<__Field> = try!(_serde::de::MapAccess::next_key(&mut __map));
+            _serde::export::Option::map(
+                try!(_serde::de::MapAccess::next_key::<__Field>(&mut __map)),
+                |__impossible| match __impossible {});
+        }
+    } else {
+        quote! {
+            while let _serde::export::Some(__key) = try!(_serde::de::MapAccess::next_key::<__Field>(&mut __map)) {
+                match __key {
+                    #(#value_arms_from)*
+                    #ignored_arm
+                }
+            }
+        }
+    };
+
+    let check_flags = fields_names
+        .iter()
+        .filter(|&&(field, _)| !field.attrs.skip_deserializing())
+        .map(
+            |&(field, ref name)| {
+                let missing_expr = Expr(expr_is_missing(&field, cattrs));
+                let field_name = &field.ident;
+                quote! {
+                    if !#name {
+                        self.dest.#field_name = #missing_expr;
+                    };
+                }
+            },
+        );
+
+    let this = &params.this;
+    let (_, _, ty_generics, _) = split_with_de_lifetime(params,);
+
+    let let_default = match *cattrs.default() {
+        attr::Default::Default => {
+            Some(
+                quote!(
+                let __default: #this #ty_generics = _serde::export::Default::default();
+            ),
+            )
+        }
+        attr::Default::Path(ref path) => {
+            Some(
+                quote!(
+                let __default: #this #ty_generics = #path();
+            ),
+            )
+        }
+        attr::Default::None => {
+            // We don't need the default value, to prevent an unused variable warning
+            // we'll leave the line empty.
+            None
+        }
+    };
+
+    quote_block! {
+        #(#let_flags)*
+
+        #match_keys
+
+        #let_default
+
+        #(#check_flags)*
+
+        _serde::export::Ok(())
+    }
+}
+
 fn field_i(i: usize) -> Ident {
     Ident::new(format!("__field{}", i))
 }
 
 /// This function wraps the expression in `#[serde(deserialize_with = "...")]`
 /// in a trait to prevent it from accessing the internal `Deserialize` state.
 fn wrap_deserialize_with(
     params: &Parameters,
-    field_ty: &syn::Ty,
+    value_ty: Tokens,
     deserialize_with: &syn::Path,
 ) -> (Tokens, Tokens) {
     let this = &params.this;
     let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,);
+    let delife = params.borrowed.de_lifetime();
 
     let wrapper = quote! {
         struct __DeserializeWith #de_impl_generics #where_clause {
-            value: #field_ty,
+            value: #value_ty,
             phantom: _serde::export::PhantomData<#this #ty_generics>,
-            lifetime: _serde::export::PhantomData<&'de ()>,
+            lifetime: _serde::export::PhantomData<&#delife ()>,
         }
 
-        impl #de_impl_generics _serde::Deserialize<'de> for __DeserializeWith #de_ty_generics #where_clause {
+        impl #de_impl_generics _serde::Deserialize<#delife> for __DeserializeWith #de_ty_generics #where_clause {
             fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<Self, __D::Error>
-                where __D: _serde::Deserializer<'de>
+                where __D: _serde::Deserializer<#delife>
             {
                 _serde::export::Ok(__DeserializeWith {
                     value: try!(#deserialize_with(__deserializer)),
                     phantom: _serde::export::PhantomData,
                     lifetime: _serde::export::PhantomData,
                 })
             }
         }
     };
 
     let wrapper_ty = quote!(__DeserializeWith #de_ty_generics);
 
     (wrapper, wrapper_ty)
 }
 
+fn wrap_deserialize_field_with(
+    params: &Parameters,
+    field_ty: &syn::Ty,
+    deserialize_with: &syn::Path,
+) -> (Tokens, Tokens) {
+    wrap_deserialize_with(params, quote!(#field_ty), deserialize_with)
+}
+
+fn wrap_deserialize_variant_with(
+    params: &Parameters,
+    variant: &Variant,
+    deserialize_with: &syn::Path,
+) -> (Tokens, Tokens, Tokens) {
+    let this = &params.this;
+    let variant_ident = &variant.ident;
+
+    let field_tys = variant.fields.iter().map(|field| field.ty);
+    let (wrapper, wrapper_ty) =
+        wrap_deserialize_with(params, quote!((#(#field_tys),*)), deserialize_with);
+
+    let field_access = (0..variant.fields.len()).map(|n| Ident::new(format!("{}", n)));
+    let unwrap_fn = match variant.style {
+        Style::Struct => {
+            let field_idents = variant.fields.iter().map(|field| field.ident.as_ref().unwrap());
+            quote! {
+                {
+                    |__wrap| {
+                        #this::#variant_ident { #(#field_idents: __wrap.value.#field_access),* }
+                    }
+                }
+            }
+        }
+        Style::Tuple => {
+            quote! {
+                {
+                    |__wrap| {
+                        #this::#variant_ident(#(__wrap.value.#field_access),*)
+                    }
+                }
+            }
+        }
+        Style::Newtype => {
+            quote! {
+                {
+                    |__wrap| {
+                        #this::#variant_ident(__wrap.value)
+                    }
+                }
+            }
+        }
+        Style::Unit => {
+            quote! {
+                {
+                    |__wrap| { #this::#variant_ident }
+                }
+            }
+        }
+    };
+
+    (wrapper, wrapper_ty, unwrap_fn)
+}
+
 fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment {
     match *field.attrs.default() {
         attr::Default::Default => {
             return quote_expr!(_serde::export::Default::default());
         }
         attr::Default::Path(ref path) => {
             return quote_expr!(#path());
         }
@@ -1725,38 +2761,110 @@ fn expr_is_missing(field: &Field, cattrs
             quote_expr! {
                 return _serde::export::Err(<__A::Error as _serde::de::Error>::missing_field(#name))
             }
         }
     }
 }
 
 struct DeImplGenerics<'a>(&'a Parameters);
+#[cfg(feature = "deserialize_from")]
+struct DeFromImplGenerics<'a>(&'a Parameters);
 
 impl<'a> ToTokens for DeImplGenerics<'a> {
     fn to_tokens(&self, tokens: &mut Tokens) {
         let mut generics = self.0.generics.clone();
-        generics.lifetimes.insert(0, self.0.de_lifetime_def());
+        if let Some(de_lifetime) = self.0.borrowed.de_lifetime_def() {
+            generics.lifetimes.insert(0, de_lifetime);
+        }
+        let (impl_generics, _, _) = generics.split_for_impl();
+        impl_generics.to_tokens(tokens);
+    }
+}
+
+#[cfg(feature = "deserialize_from")]
+impl<'a> ToTokens for DeFromImplGenerics<'a> {
+    fn to_tokens(&self, tokens: &mut Tokens) {
+        let dest_lifetime = dest_lifetime();
+        let mut generics = self.0.generics.clone();
+
+        // Add lifetime for `&'dest mut Self, and `'a: 'dest`
+        for lifetime in &mut generics.lifetimes {
+            lifetime.bounds.push(dest_lifetime.lifetime.clone());
+        }
+        for generic in &mut generics.ty_params {
+            generic.bounds.push(syn::TyParamBound::Region(dest_lifetime.lifetime.clone()));
+        }
+        generics.lifetimes.insert(0, dest_lifetime);
+        if let Some(de_lifetime) = self.0.borrowed.de_lifetime_def() {
+            generics.lifetimes.insert(0, de_lifetime);
+        }
         let (impl_generics, _, _) = generics.split_for_impl();
         impl_generics.to_tokens(tokens);
     }
 }
 
-struct DeTyGenerics<'a>(&'a syn::Generics);
+#[cfg(feature = "deserialize_from")]
+impl<'a> DeImplGenerics<'a> {
+    fn with_dest(&self) -> DeFromImplGenerics<'a> {
+        DeFromImplGenerics(self.0)
+    }
+}
+
+struct DeTyGenerics<'a>(&'a Parameters);
+#[cfg(feature = "deserialize_from")]
+struct DeFromTyGenerics<'a>(&'a Parameters);
 
 impl<'a> ToTokens for DeTyGenerics<'a> {
     fn to_tokens(&self, tokens: &mut Tokens) {
-        let mut generics = self.0.clone();
-        generics
-            .lifetimes
-            .insert(0, syn::LifetimeDef::new("'de"));
+        let mut generics = self.0.generics.clone();
+        if self.0.borrowed.de_lifetime_def().is_some() {
+            generics
+                .lifetimes
+                .insert(0, syn::LifetimeDef::new("'de"));
+        }
         let (_, ty_generics, _) = generics.split_for_impl();
         ty_generics.to_tokens(tokens);
     }
 }
 
+#[cfg(feature = "deserialize_from")]
+impl<'a> ToTokens for DeFromTyGenerics<'a> {
+    fn to_tokens(&self, tokens: &mut Tokens) {
+        let mut generics = self.0.generics.clone();
+        generics.lifetimes.insert(0, dest_lifetime());
+
+        if self.0.borrowed.de_lifetime_def().is_some() {
+            generics
+                .lifetimes
+                .insert(0, syn::LifetimeDef::new("'de"));
+        }
+        let (_, ty_generics, _) = generics.split_for_impl();
+        ty_generics.to_tokens(tokens);
+    }
+}
+
+#[cfg(feature = "deserialize_from")]
+impl<'a> DeTyGenerics<'a> {
+    fn with_dest(&self) -> DeFromTyGenerics<'a> {
+        DeFromTyGenerics(self.0)
+    }
+}
+
+#[cfg(feature = "deserialize_from")]
+fn dest_lifetime() -> syn::LifetimeDef {
+    syn::LifetimeDef::new("'dest")
+}
+
 fn split_with_de_lifetime(params: &Parameters,)
     -> (DeImplGenerics, DeTyGenerics, syn::TyGenerics, &syn::WhereClause) {
     let de_impl_generics = DeImplGenerics(&params);
-    let de_ty_generics = DeTyGenerics(&params.generics);
+    let de_ty_generics = DeTyGenerics(&params);
     let (_, ty_generics, where_clause) = params.generics.split_for_impl();
     (de_impl_generics, de_ty_generics, ty_generics, where_clause)
 }
+
+fn is_unit(variant: &Variant) -> bool {
+    match variant.style {
+        Style::Unit => true,
+        Style::Struct | Style::Tuple | Style::Newtype => false,
+    }
+}
--- a/third_party/rust/serde_derive/src/lib.rs
+++ b/third_party/rust/serde_derive/src/lib.rs
@@ -3,25 +3,31 @@
 // 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.
 
 //! This crate provides Serde's two derive macros.
 //!
-//! ```rust,ignore
+//! ```rust
+//! # #[macro_use]
+//! # extern crate serde_derive;
+//! #
 //! #[derive(Serialize, Deserialize)]
+//! # struct S;
+//! #
+//! # fn main() {}
 //! ```
 //!
 //! Please refer to [https://serde.rs/derive.html] for how to set this up.
 //!
 //! [https://serde.rs/derive.html]: https://serde.rs/derive.html
 
-#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.8")]
+#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.23")]
 
 #![cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))]
 #![cfg_attr(feature = "cargo-clippy", allow(used_underscore_binding))]
 
 // The `quote!` macro requires deep recursion.
 #![recursion_limit = "192"]
 
 extern crate syn;
--- a/third_party/rust/serde_derive/src/ser.rs
+++ b/third_party/rust/serde_derive/src/ser.rs
@@ -24,19 +24,20 @@ pub fn expand_derive_serialize(input: &s
 
     let ident = &cont.ident;
     let params = Parameters::new(&cont);
     let (impl_generics, ty_generics, where_clause) = params.generics.split_for_impl();
     let dummy_const = Ident::new(format!("_IMPL_SERIALIZE_FOR_{}", ident));
     let body = Stmts(serialize_body(&cont, &params));
 
     let impl_block = if let Some(remote) = cont.attrs.remote() {
+        let vis = &input.vis;
         quote! {
             impl #impl_generics #ident #ty_generics #where_clause {
-                fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
+                #vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
                     where __S: _serde::Serializer
                 {
                     #body
                 }
             }
         }
     } else {
         quote! {
@@ -137,30 +138,34 @@ fn build_generics(cont: &Container) -> s
                 &generics,
                 needs_serialize_bound,
                 &path!(_serde::Serialize),
             )
         }
     }
 }
 
-// Fields with a `skip_serializing` or `serialize_with` attribute are not
-// serialized by us so we do not generate a bound. Fields with a `bound`
-// attribute specify their own bound so we do not generate one. All other fields
-// may need a `T: Serialize` bound where T is the type of the field.
-fn needs_serialize_bound(attrs: &attr::Field) -> bool {
-    !attrs.skip_serializing() && attrs.serialize_with().is_none() && attrs.ser_bound().is_none()
+// Fields with a `skip_serializing` or `serialize_with` attribute, or which
+// belong to a variant with a `serialize_with` attribute, are not serialized by
+// us so we do not generate a bound. Fields with a `bound` attribute specify
+// their own bound so we do not generate one. All other fields may need a `T:
+// Serialize` bound where T is the type of the field.
+fn needs_serialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool {
+    !field.skip_serializing() &&
+    field.serialize_with().is_none() &&
+    field.ser_bound().is_none() &&
+    variant.map_or(true, |variant| variant.serialize_with().is_none())
 }
 
 fn serialize_body(cont: &Container, params: &Parameters) -> Fragment {
     if let Some(into_type) = cont.attrs.into_type() {
         serialize_into(params, into_type)
     } else {
         match cont.body {
-            Body::Enum(ref variants) => serialize_enum(params, variants, &cont.attrs),
+            Body::Enum(_, ref variants) => serialize_enum(params, variants, &cont.attrs),
             Body::Struct(Style::Struct, ref fields) => {
                 if fields.iter().any(|field| field.ident.is_none()) {
                     panic!("struct has unnamed fields");
                 }
                 serialize_struct(params, fields, &cont.attrs)
             }
             Body::Struct(Style::Tuple, ref fields) => {
                 if fields.iter().any(|field| field.ident.is_some()) {
@@ -197,17 +202,17 @@ fn serialize_newtype_struct(
     params: &Parameters,
     field: &Field,
     cattrs: &attr::Container,
 ) -> Fragment {
     let type_name = cattrs.name().serialize_name();
 
     let mut field_expr = get_field(params, field, 0);
     if let Some(path) = field.attrs.serialize_with() {
-        field_expr = wrap_serialize_with(params, field.ty, path, field_expr);
+        field_expr = wrap_serialize_field_with(params, field.ty, path, field_expr);
     }
 
     quote_expr! {
         _serde::Serializer::serialize_newtype_struct(__serializer, #type_name, #field_expr)
     }
 }
 
 fn serialize_tuple_struct(
@@ -236,16 +241,17 @@ fn serialize_tuple_struct(
 fn serialize_struct(params: &Parameters, fields: &[Field], cattrs: &attr::Container) -> Fragment {
     assert!(fields.len() as u64 <= u32::MAX as u64);
 
     let serialize_fields = serialize_struct_visitor(
         fields,
         params,
         false,
         quote!(_serde::ser::SerializeStruct::serialize_field),
+        quote!(_serde::ser::SerializeStruct::skip_field),
     );
 
     let type_name = cattrs.name().serialize_name();
 
     let mut serialized_fields = fields
         .iter()
         .filter(|&field| !field.attrs.skip_serializing())
         .peekable();
@@ -389,32 +395,45 @@ fn serialize_externally_tagged_variant(
     params: &Parameters,
     variant: &Variant,
     variant_index: u32,
     cattrs: &attr::Container,
 ) -> Fragment {
     let type_name = cattrs.name().serialize_name();
     let variant_name = variant.attrs.name().serialize_name();
 
+    if let Some(path) = variant.attrs.serialize_with() {
+        let ser = wrap_serialize_variant_with(params, path, &variant);
+        return quote_expr! {
+            _serde::Serializer::serialize_newtype_variant(
+                __serializer,
+                #type_name,
+                #variant_index,
+                #variant_name,
+                #ser,
+            )
+        };
+    }
+
     match variant.style {
         Style::Unit => {
             quote_expr! {
                 _serde::Serializer::serialize_unit_variant(
                     __serializer,
                     #type_name,
                     #variant_index,
                     #variant_name,
                 )
             }
         }
         Style::Newtype => {
             let field = &variant.fields[0];
             let mut field_expr = quote!(__field0);
             if let Some(path) = field.attrs.serialize_with() {
-                field_expr = wrap_serialize_with(params, field.ty, path, field_expr);
+                field_expr = wrap_serialize_field_with(params, field.ty, path, field_expr);
             }
 
             quote_expr! {
                 _serde::Serializer::serialize_newtype_variant(
                     __serializer,
                     #type_name,
                     #variant_index,
                     #variant_name,
@@ -454,31 +473,45 @@ fn serialize_internally_tagged_variant(
     tag: &str,
 ) -> Fragment {
     let type_name = cattrs.name().serialize_name();
     let variant_name = variant.attrs.name().serialize_name();
 
     let enum_ident_str = params.type_name();
     let variant_ident_str = variant.ident.as_ref();
 
+    if let Some(path) = variant.attrs.serialize_with() {
+        let ser = wrap_serialize_variant_with(params, path, &variant);
+        return quote_expr! {
+            _serde::private::ser::serialize_tagged_newtype(
+                __serializer,
+                #enum_ident_str,
+                #variant_ident_str,
+                #tag,
+                #variant_name,
+                #ser,
+            )
+        };
+    }
+
     match variant.style {
         Style::Unit => {
             quote_block! {
                 let mut __struct = try!(_serde::Serializer::serialize_struct(
                     __serializer, #type_name, 1));
                 try!(_serde::ser::SerializeStruct::serialize_field(
                     &mut __struct, #tag, #variant_name));
                 _serde::ser::SerializeStruct::end(__struct)
             }
         }
         Style::Newtype => {
             let field = &variant.fields[0];
             let mut field_expr = quote!(__field0);
             if let Some(path) = field.attrs.serialize_with() {
-                field_expr = wrap_serialize_with(params, field.ty, path, field_expr);
+                field_expr = wrap_serialize_field_with(params, field.ty, path, field_expr);
             }
 
             quote_expr! {
                 _serde::private::ser::serialize_tagged_newtype(
                     __serializer,
                     #enum_ident_str,
                     #variant_ident_str,
                     #tag,
@@ -509,54 +542,67 @@ fn serialize_adjacently_tagged_variant(
     tag: &str,
     content: &str,
 ) -> Fragment {
     let this = &params.this;
     let type_name = cattrs.name().serialize_name();
     let variant_name = variant.attrs.name().serialize_name();
 
     let inner = Stmts(
-        match variant.style {
-            Style::Unit => {
-                return quote_block! {
-                    let mut __struct = try!(_serde::Serializer::serialize_struct(
-                        __serializer, #type_name, 1));
-                    try!(_serde::ser::SerializeStruct::serialize_field(
-                        &mut __struct, #tag, #variant_name));
-                    _serde::ser::SerializeStruct::end(__struct)
-                };
+        if let Some(path) = variant.attrs.serialize_with() {
+            let ser = wrap_serialize_variant_with(params, path, &variant);
+            quote_expr! {
+                _serde::Serialize::serialize(#ser, __serializer)
             }
-            Style::Newtype => {
-                let field = &variant.fields[0];
-                let mut field_expr = quote!(__field0);
-                if let Some(path) = field.attrs.serialize_with() {
-                    field_expr = wrap_serialize_with(params, field.ty, path, field_expr);
+        } else {
+            match variant.style {
+                Style::Unit => {
+                    return quote_block! {
+                        let mut __struct = try!(_serde::Serializer::serialize_struct(
+                            __serializer, #type_name, 1));
+                        try!(_serde::ser::SerializeStruct::serialize_field(
+                            &mut __struct, #tag, #variant_name));
+                        _serde::ser::SerializeStruct::end(__struct)
+                    };
                 }
+                Style::Newtype => {
+                    let field = &variant.fields[0];
+                    let mut field_expr = quote!(__field0);
+                    if let Some(path) = field.attrs.serialize_with() {
+                        field_expr = wrap_serialize_field_with(params, field.ty, path, field_expr);
+                    }
 
-                quote_expr! {
-                    _serde::Serialize::serialize(#field_expr, __serializer)
+                    quote_expr! {
+                        _serde::Serialize::serialize(#field_expr, __serializer)
+                    }
                 }
-            }
-            Style::Tuple => {
-                serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields)
-            }
-            Style::Struct => {
-                serialize_struct_variant(
-                    StructVariant::Untagged,
-                    params,
-                    &variant.fields,
-                    &variant_name,
-                )
+                Style::Tuple => {
+                    serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields)
+                }
+                Style::Struct => {
+                    serialize_struct_variant(
+                        StructVariant::Untagged,
+                        params,
+                        &variant.fields,
+                        &variant_name,
+                    )
+                }
             }
         },
     );
 
     let fields_ty = variant.fields.iter().map(|f| &f.ty);
     let ref fields_ident: Vec<_> = match variant.style {
-        Style::Unit => unreachable!(),
+        Style::Unit => {
+            if variant.attrs.serialize_with().is_some() {
+                vec![]
+            } else {
+                unreachable!()
+            }
+        }
         Style::Newtype => vec![Ident::new("__field0")],
         Style::Tuple => {
             (0..variant.fields.len())
                 .map(|i| Ident::new(format!("__field{}", i)))
                 .collect()
         }
         Style::Struct => {
             variant
@@ -570,17 +616,21 @@ fn serialize_adjacently_tagged_variant(
                     },
                 )
                 .collect()
         }
     };
 
     let (_, ty_generics, where_clause) = params.generics.split_for_impl();
 
-    let wrapper_generics = bound::with_lifetime_bound(&params.generics, "'__a");
+    let wrapper_generics = if let Style::Unit = variant.style {
+        params.generics.clone()
+    } else {
+        bound::with_lifetime_bound(&params.generics, "'__a")
+    };
     let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl();
 
     quote_block! {
         struct __AdjacentlyTagged #wrapper_generics #where_clause {
             data: (#(&'__a #fields_ty,)*),
             phantom: _serde::export::PhantomData<#this #ty_generics>,
         }
 
@@ -606,27 +656,34 @@ fn serialize_adjacently_tagged_variant(
     }
 }
 
 fn serialize_untagged_variant(
     params: &Parameters,
     variant: &Variant,
     cattrs: &attr::Container,
 ) -> Fragment {
+    if let Some(path) = variant.attrs.serialize_with() {
+        let ser = wrap_serialize_variant_with(params, path, &variant);
+        return quote_expr! {
+            _serde::Serialize::serialize(#ser, __serializer)
+        };
+    }
+
     match variant.style {
         Style::Unit => {
             quote_expr! {
                 _serde::Serializer::serialize_unit(__serializer)
             }
         }
         Style::Newtype => {
             let field = &variant.fields[0];
             let mut field_expr = quote!(__field0);
             if let Some(path) = field.attrs.serialize_with() {
-                field_expr = wrap_serialize_with(params, field.ty, path, field_expr);
+                field_expr = wrap_serialize_field_with(params, field.ty, path, field_expr);
             }
 
             quote_expr! {
                 _serde::Serialize::serialize(#field_expr, __serializer)
             }
         }
         Style::Tuple => serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields),
         Style::Struct => {
@@ -701,25 +758,33 @@ enum StructVariant<'a> {
 }
 
 fn serialize_struct_variant<'a>(
     context: StructVariant<'a>,
     params: &Parameters,
     fields: &[Field],
     name: &str,
 ) -> Fragment {
-    let method = match context {
+    let (method, skip_method) = match context {
         StructVariant::ExternallyTagged { .. } => {
-            quote!(_serde::ser::SerializeStructVariant::serialize_field)
+            (
+                quote!(_serde::ser::SerializeStructVariant::serialize_field),
+                quote!(_serde::ser::SerializeStructVariant::skip_field),
+            )
         }
         StructVariant::InternallyTagged { .. } |
-        StructVariant::Untagged => quote!(_serde::ser::SerializeStruct::serialize_field),
+        StructVariant::Untagged => {
+            (
+                quote!(_serde::ser::SerializeStruct::serialize_field),
+                quote!(_serde::ser::SerializeStruct::skip_field),
+            )
+        }
     };
 
-    let serialize_fields = serialize_struct_visitor(fields, params, true, method);
+    let serialize_fields = serialize_struct_visitor(fields, params, true, method, skip_method);
 
     let mut serialized_fields = fields
         .iter()
         .filter(|&field| !field.attrs.skip_serializing())
         .peekable();
 
     let let_mut = mut_if(serialized_fields.peek().is_some());
 
@@ -802,17 +867,17 @@ fn serialize_tuple_struct_visitor(
                 };
 
                 let skip = field
                     .attrs
                     .skip_serializing_if()
                     .map(|path| quote!(#path(#field_expr)));
 
                 if let Some(path) = field.attrs.serialize_with() {
-                    field_expr = wrap_serialize_with(params, field.ty, path, field_expr);
+                    field_expr = wrap_serialize_field_with(params, field.ty, path, field_expr);
                 }
 
                 let ser = quote! {
                     try!(#func(&mut __serde_state, #field_expr));
                 };
 
                 match skip {
                     None => ser,
@@ -823,16 +888,17 @@ fn serialize_tuple_struct_visitor(
         .collect()
 }
 
 fn serialize_struct_visitor(
     fields: &[Field],
     params: &Parameters,
     is_enum: bool,
     func: Tokens,
+    skip_func: Tokens,
 ) -> Vec<Tokens> {
     fields
         .iter()
         .filter(|&field| !field.attrs.skip_serializing())
         .map(
             |field| {
                 let field_ident = field.ident.clone().expect("struct has unnamed field");
                 let mut field_expr = if is_enum {
@@ -844,60 +910,103 @@ fn serialize_struct_visitor(
                 let key_expr = field.attrs.name().serialize_name();
 
                 let skip = field
                     .attrs
                     .skip_serializing_if()
                     .map(|path| quote!(#path(#field_expr)));
 
                 if let Some(path) = field.attrs.serialize_with() {
-                    field_expr = wrap_serialize_with(params, field.ty, path, field_expr)
+                    field_expr = wrap_serialize_field_with(params, field.ty, path, field_expr);
                 }
 
                 let ser = quote! {
                     try!(#func(&mut __serde_state, #key_expr, #field_expr));
                 };
 
                 match skip {
                     None => ser,
-                    Some(skip) => quote!(if !#skip { #ser }),
+                    Some(skip) => {
+                        quote! {
+                            if !#skip {
+                                #ser
+                            } else {
+                                try!(#skip_func(&mut __serde_state, #key_expr));
+                            }
+                        }
+                    }
                 }
             },
         )
         .collect()
 }
 
-fn wrap_serialize_with(
+fn wrap_serialize_field_with(
     params: &Parameters,
     field_ty: &syn::Ty,
     serialize_with: &syn::Path,
-    value: Tokens,
+    field_expr: Tokens,
+) -> Tokens {
+    wrap_serialize_with(params,
+                        serialize_with,
+                        &[field_ty],
+                        &[quote!(#field_expr)])
+}
+
+fn wrap_serialize_variant_with(
+    params: &Parameters,
+    serialize_with: &syn::Path,
+    variant: &Variant,
+) -> Tokens {
+    let field_tys: Vec<_> = variant.fields.iter().map(|field| field.ty).collect();
+    let field_exprs: Vec<_> = variant.fields.iter()
+        .enumerate()
+        .map(|(i, field)| {
+            let id = field.ident.as_ref().map_or_else(|| Ident::new(format!("__field{}", i)),
+                                                      |id| id.clone());
+            quote!(#id)
+        })
+        .collect();
+    wrap_serialize_with(params, serialize_with, field_tys.as_slice(), field_exprs.as_slice())
+}
+
+fn wrap_serialize_with(
+    params: &Parameters,
+    serialize_with: &syn::Path,
+    field_tys: &[&syn::Ty],
+    field_exprs: &[Tokens],
 ) -> Tokens {
     let this = &params.this;
     let (_, ty_generics, where_clause) = params.generics.split_for_impl();
 
-    let wrapper_generics = bound::with_lifetime_bound(&params.generics, "'__a");
+    let wrapper_generics = if field_exprs.len() == 0 {
+        params.generics.clone()
+    } else {
+        bound::with_lifetime_bound(&params.generics, "'__a")
+    };
     let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl();
 
+    let field_access = (0..field_exprs.len()).map(|n| Ident::new(format!("{}", n)));
+
     quote!({
         struct __SerializeWith #wrapper_impl_generics #where_clause {
-            value: &'__a #field_ty,
+            values: (#(&'__a #field_tys, )*),
             phantom: _serde::export::PhantomData<#this #ty_generics>,
         }
 
         impl #wrapper_impl_generics _serde::Serialize for __SerializeWith #wrapper_ty_generics #where_clause {
             fn serialize<__S>(&self, __s: __S) -> _serde::export::Result<__S::Ok, __S::Error>
                 where __S: _serde::Serializer
             {
-                #serialize_with(self.value, __s)
+                #serialize_with(#(self.values.#field_access, )* __s)
             }
         }
 
         &__SerializeWith {
-            value: #value,
+            values: (#(#field_exprs, )*),
             phantom: _serde::export::PhantomData::<#this #ty_generics>,
         }
     })
 }
 
 // Serialization of an empty struct results in code like:
 //
 //     let mut __serde_state = try!(serializer.serialize_struct("S", 0));
--- a/third_party/rust/serde_derive_internals/.cargo-checksum.json
+++ b/third_party/rust/serde_derive_internals/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"511194979a2e34ebea7b27d4abe9350a6d6d2beb4ee074e296c5b95f4c8fc6e9","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"eedee04bddb61e99bc816656bb3b8ae2fa50ff00045ecdb5212682f3592d9ab2","src/ast.rs":"6d41e5055cc012474f72a2fb25874d8f59b872ccccddc2dee83ceaaa08135cd9","src/attr.rs":"bfd6120502807f8a5531a846fd76128ce133b9f9d162a6ea35e471afb73a3b20","src/case.rs":"036711fc550a405ab86d9470c94bac1d58dcdcad4e3a672c73cc0c5a0ecc138b","src/check.rs":"69ecc07d0916ae33ba868eb697ca35f7cd2e97127187f1e95efdcf7ad8e5e2f8","src/ctxt.rs":"98eab1acd3de8617b516d1de7d5d870bb1d2a1c1aca258a4cca2bde3f8df88e4","src/lib.rs":"7fef231c76b77486d813fa43a5dc7394fdeb8b1e95e02f5c1205213725ed400b"},"package":"37aee4e0da52d801acfbc0cc219eb1eda7142112339726e427926a6f6ee65d3a"}
\ No newline at end of file
+{"files":{"Cargo.toml":"0435204d95404e25ee07fa3169ddf5eef26bde3fce03f4e63e9e55774d620199","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"7dc6376a88195594cd6b43cb891aad10f57144ff737178b55d046aa04739b43a","src/ast.rs":"bc9936766227f78bf34cf003d271ffd70ad056e1272caafc1b185bdd32cc46bb","src/attr.rs":"51c92750f7b490a2c46950a68b5491d83181815d98e0fe3db102369b1ca9fe6e","src/case.rs":"be3288491dae43ca53643cb8409431e5e65ccf39c69c8047676e89c997827b0c","src/check.rs":"e976c9bac0daa334b2c82c6a91ac472235c7a1d91c5fe0deb2a83fe71b7c0663","src/ctxt.rs":"98eab1acd3de8617b516d1de7d5d870bb1d2a1c1aca258a4cca2bde3f8df88e4","src/lib.rs":"f242433bcb42c2360b8887d6e9f1b286a332080f1f0a081de06b0c061b563348"},"package":null}
\ No newline at end of file
--- a/third_party/rust/serde_derive_internals/Cargo.toml
+++ b/third_party/rust/serde_derive_internals/Cargo.toml
@@ -1,11 +1,11 @@
 [package]
 name = "serde_derive_internals"
-version = "0.15.1" # remember to update html_root_url
+version = "0.17.0" # remember to update html_root_url
 authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
 license = "MIT/Apache-2.0"
 description = "AST representation used by Serde derive macros. Unstable."
 homepage = "https://serde.rs"
 repository = "https://github.com/serde-rs/serde"
 documentation = "https://docs.serde.rs/serde_derive_internals/"
 keywords = ["serde", "serialization"]
 readme = "README.md"
--- a/third_party/rust/serde_derive_internals/README.md
+++ b/third_party/rust/serde_derive_internals/README.md
@@ -15,19 +15,40 @@ You may be looking for:
 - [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
 
-<a href="http://play.integer32.com/?gist=9003c5b88c1f4989941925d7190c6eec" target="_blank">
-<img align="right" width="50" src="https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/run.png">
-</a>
+<details>
+<summary>
+Click to show Cargo.toml.
+<a href="http://play.integer32.com/?gist=9003c5b88c1f4989941925d7190c6eec" target="_blank">Run this code in the playground.</a>
+</summary>
+
+```toml
+[dependencies]
+
+# The core APIs, including the Serialize and Deserialize traits. Always
+# required when using Serde.
+serde = "1.0"
+
+# Support for #[derive(Serialize, Deserialize)]. Required if you want Serde
+# to work for structs and enums defined in your crate.
+serde_derive = "1.0"
+
+# Each data format lives in its own crate; the sample code below uses JSON
+# but you may be using a different one.
+serde_json = "1.0"
+```
+
+</details>
+<p></p>
 
 ```rust
 #[macro_use]
 extern crate serde_derive;
 
 extern crate serde;
 extern crate serde_json;
 
--- a/third_party/rust/serde_derive_internals/src/ast.rs
+++ b/third_party/rust/serde_derive_internals/src/ast.rs
@@ -14,61 +14,69 @@ use Ctxt;
 pub struct Container<'a> {
     pub ident: syn::Ident,
     pub attrs: attr::Container,
     pub body: Body<'a>,
     pub generics: &'a syn::Generics,
 }
 
 pub enum Body<'a> {
-    Enum(Vec<Variant<'a>>),
+    Enum(Repr, Vec<Variant<'a>>),
     Struct(Style, Vec<Field<'a>>),
 }
 
 pub struct Variant<'a> {
     pub ident: syn::Ident,
     pub attrs: attr::Variant,
     pub style: Style,
     pub fields: Vec<Field<'a>>,
 }
 
 pub struct Field<'a> {
     pub ident: Option<syn::Ident>,
     pub attrs: attr::Field,
     pub ty: &'a syn::Ty,
 }
 
+pub struct Repr {
+    pub int_repr: Option<&'static str>,
+    pub c_repr: bool,
+    pub other_repr: bool,
+}
+
 #[derive(Copy, Clone)]
 pub enum Style {
     Struct,
     Tuple,
     Newtype,
     Unit,
 }
 
 impl<'a> Container<'a> {
     pub fn from_ast(cx: &Ctxt, item: &'a syn::DeriveInput) -> Container<'a> {
         let attrs = attr::Container::from_ast(cx, item);
 
         let mut body = match item.body {
-            syn::Body::Enum(ref variants) => Body::Enum(enum_from_ast(cx, variants)),
+            syn::Body::Enum(ref variants) => enum_from_ast(cx, item, variants),
             syn::Body::Struct(ref variant_data) => {
-                let (style, fields) = struct_from_ast(cx, variant_data);
+                let (style, fields) = struct_from_ast(cx, variant_data, None);
                 Body::Struct(style, fields)
             }
         };
 
         match body {
-            Body::Enum(ref mut variants) => {
+            Body::Enum(_, ref mut variants) => {
                 for ref mut variant in variants {
                     variant.attrs.rename_by_rule(attrs.rename_all());
                     for ref mut field in &mut variant.fields {
                         field.attrs.rename_by_rule(variant.attrs.rename_all());
                     }
                 }
+
+                
             }
             Body::Struct(_, ref mut fields) => {
                 for field in fields {
                     field.attrs.rename_by_rule(attrs.rename_all());
                 }
             }
         }
 
@@ -81,63 +89,125 @@ impl<'a> Container<'a> {
         check::check(cx, &item);
         item
     }
 }
 
 impl<'a> Body<'a> {
     pub fn all_fields(&'a self) -> Box<Iterator<Item = &'a Field<'a>> + 'a> {
         match *self {
-            Body::Enum(ref variants) => {
+            Body::Enum(_, ref variants) => {
                 Box::new(variants.iter().flat_map(|variant| variant.fields.iter()))
             }
             Body::Struct(_, ref fields) => Box::new(fields.iter()),
         }
     }
 
     pub fn has_getter(&self) -> bool {
         self.all_fields().any(|f| f.attrs.getter().is_some())
     }
 }
 
-fn enum_from_ast<'a>(cx: &Ctxt, variants: &'a [syn::Variant]) -> Vec<Variant<'a>> {
-    variants
+impl Repr {
+    /// Gives the int type to use for the `repr(int)` enum layout
+    pub fn get_stable_rust_enum_layout(&self) -> Option<&'static str> {
+        if self.c_repr || self.other_repr {
+            None
+        } else {
+            self.int_repr
+        }
+    }
+
+    /// Gives the int type to use for the `repr(C, int)` enum layout
+    pub fn get_stable_c_enum_layout(&self) -> Option<&'static str> {
+        if !self.c_repr && self.other_repr {
+            None
+        } else {
+            self.int_repr
+        }
+    }
+}
+
+fn enum_from_ast<'a>(cx: &Ctxt, item: &'a syn::DeriveInput, variants: &'a [syn::Variant]) -> Body<'a> {
+    let variants = variants
         .iter()
         .map(
             |variant| {
-                let (style, fields) = struct_from_ast(cx, &variant.data);
+                let attrs = attr::Variant::from_ast(cx, variant);
+                let (style, fields) = struct_from_ast(cx, &variant.data, Some(&attrs));
                 Variant {
                     ident: variant.ident.clone(),
-                    attrs: attr::Variant::from_ast(cx, variant),
+                    attrs: attrs,
                     style: style,
                     fields: fields,
                 }
             },
         )
-        .collect()
+        .collect();
+
+    // Compute repr info for enum optimizations
+    static INT_TYPES: [&'static str; 12] = [
+        "u8", "u16", "u32", "u64", "u128", "usize",
+        "i8", "i16", "i32", "i64", "i128", "isize",
+    ];
+
+    let mut int_repr = None;
+    let mut c_repr = false;
+    let mut other_repr = false;
+
+    for attr in &item.attrs {
+        if let syn::MetaItem::List(ref ident, ref vals) = attr.value {
+            if *ident == "repr" {
+                // has_repr = true;
+                for repr in vals {
+                    if let syn::NestedMetaItem::MetaItem(syn::MetaItem::Word(ref repr)) = *repr {
+                        if repr == "C" {
+                            c_repr = true;
+                        } else if let Some(int_type) = INT_TYPES.iter().cloned().find(|int_type| repr == int_type) {
+                            if int_repr.is_some() { 
+                                // This shouldn't happen, but we shouldn't crash if we see it.
+                                // So just treat the enum as having a mysterious other repr,
+                                // which makes us discard any attempt to optimize based on layout.
+                                other_repr = true; 
+                            }
+                            int_repr = Some(int_type);
+                        } else {
+                            other_repr = true;
+                        }
+                    } else {
+                        panic!("impossible repr? {:?}", repr);
+                    }
+                }
+            }
+        }
+    }
+
+    let repr = Repr { int_repr, c_repr, other_repr };
+
+    Body::Enum(repr, variants)
 }
 
-fn struct_from_ast<'a>(cx: &Ctxt, data: &'a syn::VariantData) -> (Style, Vec<Field<'a>>) {
+fn struct_from_ast<'a>(cx: &Ctxt, data: &'a syn::VariantData, attrs: Option<&attr::Variant>) -> (Style, Vec<Field<'a>>) {
     match *data {
-        syn::VariantData::Struct(ref fields) => (Style::Struct, fields_from_ast(cx, fields)),
+        syn::VariantData::Struct(ref fields) => (Style::Struct, fields_from_ast(cx, fields, attrs)),
         syn::VariantData::Tuple(ref fields) if fields.len() == 1 => {
-            (Style::Newtype, fields_from_ast(cx, fields))
+            (Style::Newtype, fields_from_ast(cx, fields, attrs))
         }
-        syn::VariantData::Tuple(ref fields) => (Style::Tuple, fields_from_ast(cx, fields)),
+        syn::VariantData::Tuple(ref fields) => (Style::Tuple, fields_from_ast(cx, fields, attrs)),
         syn::VariantData::Unit => (Style::Unit, Vec::new()),
     }
 }
 
-fn fields_from_ast<'a>(cx: &Ctxt, fields: &'a [syn::Field]) -> Vec<Field<'a>> {
+fn fields_from_ast<'a>(cx: &Ctxt, fields: &'a [syn::Field], attrs: Option<&attr::Variant>) -> Vec<Field<'a>> {
     fields
         .iter()
         .enumerate()
         .map(
             |(i, field)| {
                 Field {
                     ident: field.ident.clone(),
-                    attrs: attr::Field::from_ast(cx, i, field),
+                    attrs: attr::Field::from_ast(cx, i, field, attrs),
                     ty: &field.ty,
                 }
             },
         )
         .collect()
 }
--- a/third_party/rust/serde_derive_internals/src/attr.rs
+++ b/third_party/rust/serde_derive_internals/src/attr.rs
@@ -505,26 +505,32 @@ fn decide_identifier(
 pub struct Variant {
     name: Name,
     ser_renamed: bool,
     de_renamed: bool,
     rename_all: RenameRule,
     skip_deserializing: bool,
     skip_serializing: bool,
     other: bool,
+    serialize_with: Option<syn::Path>,
+    deserialize_with: Option<syn::Path>,
+    borrow: Option<syn::MetaItem>,
 }
 
 impl Variant {
     pub fn from_ast(cx: &Ctxt, variant: &syn::Variant) -> Self {
         let mut ser_name = Attr::none(cx, "rename");
         let mut de_name = Attr::none(cx, "rename");
         let mut skip_deserializing = BoolAttr::none(cx, "skip_deserializing");
         let mut skip_serializing = BoolAttr::none(cx, "skip_serializing");
         let mut rename_all = Attr::none(cx, "rename_all");
         let mut other = BoolAttr::none(cx, "other");
+        let mut serialize_with = Attr::none(cx, "serialize_with");
+        let mut deserialize_with = Attr::none(cx, "deserialize_with");
+        let mut borrow = Attr::none(cx, "borrow");
 
         for meta_items in variant.attrs.iter().filter_map(get_serde_meta_items) {
             for meta_item in meta_items {
                 match meta_item {
                     // Parse `#[serde(rename = "foo")]`
                     MetaItem(NameValue(ref name, ref lit)) if name == "rename" => {
                         if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
                             ser_name.set(s.clone());
@@ -564,16 +570,54 @@ impl Variant {
                         skip_serializing.set_true();
                     }
 
                     // Parse `#[serde(other)]`
                     MetaItem(Word(ref name)) if name == "other" => {
                         other.set_true();
                     }
 
+                    // Parse `#[serde(with = "...")]`
+                    MetaItem(NameValue(ref name, ref lit)) if name == "with" => {
+                        if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
+                            let mut ser_path = path.clone();
+                            ser_path.segments.push("serialize".into());
+                            serialize_with.set(ser_path);
+                            let mut de_path = path;
+                            de_path.segments.push("deserialize".into());
+                            deserialize_with.set(de_path);
+                        }
+                    }
+
+                    // Parse `#[serde(serialize_with = "...")]`
+                    MetaItem(NameValue(ref name, ref lit)) if name == "serialize_with" => {
+                        if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
+                            serialize_with.set(path);
+                        }
+                    }
+
+                    // Parse `#[serde(deserialize_with = "...")]`
+                    MetaItem(NameValue(ref name, ref lit)) if name == "deserialize_with" => {
+                        if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
+                            deserialize_with.set(path);
+                        }
+                    }
+
+                    // Defer `#[serde(borrow)]` and `#[serde(borrow = "'a + 'b")]`
+                    MetaItem(ref mi) if mi.name() == "borrow" => {
+                        match variant.data {
+                            syn::VariantData::Tuple(ref fields) if fields.len() == 1 => {
+                                borrow.set(mi.clone());
+                            }
+                            _ => {
+                                cx.error("#[serde(borrow)] may only be used on newtype variants");
+                            }
+                        }
+                    }
+
                     MetaItem(ref meta_item) => {
                         cx.error(format!("unknown serde variant attribute `{}`", meta_item.name()));
                     }
 
                     Literal(_) => {
                         cx.error("unexpected literal in serde variant attribute");
                     }
                 }
@@ -590,16 +634,19 @@ impl Variant {
                 deserialize: de_name.unwrap_or_else(|| variant.ident.to_string()),
             },
             ser_renamed: ser_renamed,
             de_renamed: de_renamed,
             rename_all: rename_all.get().unwrap_or(RenameRule::None),
             skip_deserializing: skip_deserializing.get(),
             skip_serializing: skip_serializing.get(),
             other: other.get(),
+            serialize_with: serialize_with.get(),
+            deserialize_with: deserialize_with.get(),
+            borrow: borrow.get(),
         }
     }
 
     pub fn name(&self) -> &Name {
         &self.name
     }
 
     pub fn rename_by_rule(&mut self, rule: &RenameRule) {
@@ -621,16 +668,24 @@ impl Variant {
 
     pub fn skip_serializing(&self) -> bool {
         self.skip_serializing
     }
 
     pub fn other(&self) -> bool {
         self.other
     }
+
+    pub fn serialize_with(&self) -> Option<&syn::Path> {
+        self.serialize_with.as_ref()
+    }
+
+    pub fn deserialize_with(&self) -> Option<&syn::Path> {
+        self.deserialize_with.as_ref()
+    }
 }
 
 /// Represents field attribute information
 #[derive(Debug)]
 pub struct Field {
     name: Name,
     ser_renamed: bool,
     de_renamed: bool,
@@ -654,17 +709,17 @@ pub enum Default {
     /// The default is given by `std::default::Default::default()`.
     Default,
     /// The default is given by this function.
     Path(syn::Path),
 }
 
 impl Field {
     /// Extract out the `#[serde(...)]` attributes from a struct field.
-    pub fn from_ast(cx: &Ctxt, index: usize, field: &syn::Field) -> Self {
+    pub fn from_ast(cx: &Ctxt, index: usize, field: &syn::Field, attrs: Option<&Variant>) -> Self {
         let mut ser_name = Attr::none(cx, "rename");
         let mut de_name = Attr::none(cx, "rename");
         let mut skip_serializing = BoolAttr::none(cx, "skip_serializing");
         let mut skip_deserializing = BoolAttr::none(cx, "skip_deserializing");
         let mut skip_serializing_if = Attr::none(cx, "skip_serializing_if");
         let mut default = Attr::none(cx, "default");
         let mut serialize_with = Attr::none(cx, "serialize_with");
         let mut deserialize_with = Attr::none(cx, "deserialize_with");
@@ -673,17 +728,23 @@ impl Field {
         let mut borrowed_lifetimes = Attr::none(cx, "borrow");
         let mut getter = Attr::none(cx, "getter");
 
         let ident = match field.ident {
             Some(ref ident) => ident.to_string(),
             None => index.to_string(),
         };
 
-        for meta_items in field.attrs.iter().filter_map(get_serde_meta_items) {
+        let variant_borrow = attrs
+            .map(|variant| &variant.borrow)
+            .unwrap_or(&None)
+            .as_ref()
+            .map(|borrow| vec![MetaItem(borrow.clone())]);
+
+        for meta_items in field.attrs.iter().filter_map(get_serde_meta_items).chain(variant_borrow) {
             for meta_item in meta_items {
                 match meta_item {
                     // Parse `#[serde(rename = "foo")]`
                     MetaItem(NameValue(ref name, ref lit)) if name == "rename" => {
                         if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
                             ser_name.set(s.clone());
                             de_name.set(s);
                         }
--- a/third_party/rust/serde_derive_internals/src/case.rs
+++ b/third_party/rust/serde_derive_internals/src/case.rs
@@ -1,17 +1,20 @@
 // Copyright 2017 Serde Developers
 //
 // 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.
 
+// See https://users.rust-lang.org/t/psa-dealing-with-warning-unused-import-std-ascii-asciiext-in-today-s-nightly/13726
+#[allow(unused_imports)]
 use std::ascii::AsciiExt;
+
 use std::str::FromStr;
 
 use self::RenameRule::*;
 
 #[derive(Debug, PartialEq)]
 pub enum RenameRule {
     /// Don't apply a default rename rule.
     None,
@@ -22,16 +25,18 @@ pub enum RenameRule {
     /// Rename direct children to "camelCase" style.
     CamelCase,
     /// Rename direct children to "snake_case" style, as commonly used for fields.
     SnakeCase,
     /// Rename direct children to "SCREAMING_SNAKE_CASE" style, as commonly used for constants.
     ScreamingSnakeCase,
     /// Rename direct children to "kebab-case" style.
     KebabCase,
+    /// Rename direct children to "SCREAMING-KEBAB-CASE" style.
+    ScreamingKebabCase
 }
 
 impl RenameRule {
     pub fn apply_to_variant(&self, variant: &str) -> String {
         match *self {
             None | PascalCase => variant.to_owned(),
             LowerCase => variant.to_ascii_lowercase(),
             CamelCase => variant[..1].to_ascii_lowercase() + &variant[1..],
@@ -42,16 +47,17 @@ impl RenameRule {
                         snake.push('_');
                     }
                     snake.push(ch.to_ascii_lowercase());
                 }
                 snake
             }
             ScreamingSnakeCase => SnakeCase.apply_to_variant(variant).to_ascii_uppercase(),
             KebabCase => SnakeCase.apply_to_variant(variant).replace('_', "-"),
+            ScreamingKebabCase => ScreamingSnakeCase.apply_to_variant(variant).replace('_', "-")
         }
     }
 
     pub fn apply_to_field(&self, field: &str) -> String {
         match *self {
             None | LowerCase | SnakeCase => field.to_owned(),
             PascalCase => {
                 let mut pascal = String::new();
@@ -69,64 +75,68 @@ impl RenameRule {
                 pascal
             }
             CamelCase => {
                 let pascal = PascalCase.apply_to_field(field);
                 pascal[..1].to_ascii_lowercase() + &pascal[1..]
             }
             ScreamingSnakeCase => field.to_ascii_uppercase(),
             KebabCase => field.replace('_', "-"),
+            ScreamingKebabCase => ScreamingSnakeCase.apply_to_field(field).replace('_', "-")
         }
     }
 }
 
 impl FromStr for RenameRule {
     type Err = ();
 
     fn from_str(rename_all_str: &str) -> Result<Self, Self::Err> {
         match rename_all_str {
             "lowercase" => Ok(LowerCase),
             "PascalCase" => Ok(PascalCase),
             "camelCase" => Ok(CamelCase),
             "snake_case" => Ok(SnakeCase),
             "SCREAMING_SNAKE_CASE" => Ok(ScreamingSnakeCase),
             "kebab-case" => Ok(KebabCase),
+            "SCREAMING-KEBAB-CASE" => Ok(ScreamingKebabCase),
             _ => Err(()),
         }
     }
 }
 
 #[test]
 fn rename_variants() {
-    for &(original, lower, camel, snake, screaming, kebab) in
+    for &(original, lower, camel, snake, screaming, kebab, screaming_kebab) in
         &[
-            ("Outcome", "outcome", "outcome", "outcome", "OUTCOME", "outcome"),
-            ("VeryTasty", "verytasty", "veryTasty", "very_tasty", "VERY_TASTY", "very-tasty"),
-            ("A", "a", "a", "a", "A", "a"),
-            ("Z42", "z42", "z42", "z42", "Z42", "z42"),
+            ("Outcome", "outcome", "outcome", "outcome", "OUTCOME", "outcome", "OUTCOME"),
+            ("VeryTasty", "verytasty", "veryTasty", "very_tasty", "VERY_TASTY", "very-tasty", "VERY-TASTY"),
+            ("A", "a", "a", "a", "A", "a", "A"),
+            ("Z42", "z42", "z42", "z42", "Z42", "z42", "Z42"),
         ] {
         assert_eq!(None.apply_to_variant(original), original);
         assert_eq!(LowerCase.apply_to_variant(original), lower);
         assert_eq!(PascalCase.apply_to_variant(original), original);
         assert_eq!(CamelCase.apply_to_variant(original), camel);
         assert_eq!(SnakeCase.apply_to_variant(original), snake);
         assert_eq!(ScreamingSnakeCase.apply_to_variant(original), screaming);
         assert_eq!(KebabCase.apply_to_variant(original), kebab);
+        assert_eq!(ScreamingKebabCase.apply_to_variant(original), screaming_kebab);
     }
 }
 
 #[test]
 fn rename_fields() {
-    for &(original, pascal, camel, screaming, kebab) in
+    for &(original, pascal, camel, screaming, kebab, screaming_kebab) in
         &[
-            ("outcome", "Outcome", "outcome", "OUTCOME", "outcome"),
-            ("very_tasty", "VeryTasty", "veryTasty", "VERY_TASTY", "very-tasty"),
-            ("a", "A", "a", "A", "a"),
-            ("z42", "Z42", "z42", "Z42", "z42"),
+            ("outcome", "Outcome", "outcome", "OUTCOME", "outcome", "OUTCOME"),
+            ("very_tasty", "VeryTasty", "veryTasty", "VERY_TASTY", "very-tasty", "VERY-TASTY"),
+            ("a", "A", "a", "A", "a", "A"),
+            ("z42", "Z42", "z42", "Z42", "z42", "Z42"),
         ] {
         assert_eq!(None.apply_to_field(original), original);
         assert_eq!(PascalCase.apply_to_field(original), pascal);
         assert_eq!(CamelCase.apply_to_field(original), camel);
         assert_eq!(SnakeCase.apply_to_field(original), original);
         assert_eq!(ScreamingSnakeCase.apply_to_field(original), screaming);
         assert_eq!(KebabCase.apply_to_field(original), kebab);
+        assert_eq!(ScreamingKebabCase.apply_to_field(original), screaming_kebab);
     }
 }
--- a/third_party/rust/serde_derive_internals/src/check.rs
+++ b/third_party/rust/serde_derive_internals/src/check.rs
@@ -10,23 +10,24 @@ use ast::{Body, Container, Style};
 use attr::Identifier;
 use Ctxt;
 
 /// Cross-cutting checks that require looking at more than a single attrs
 /// object. Simpler checks should happen when parsing and building the attrs.
 pub fn check(cx: &Ctxt, cont: &Container) {
     check_getter(cx, cont);
     check_identifier(cx, cont);
+    check_variant_skip_attrs(cx, cont);
 }
 
 /// Getters are only allowed inside structs (not enums) with the `remote`
 /// attribute.
 fn check_getter(cx: &Ctxt, cont: &Container) {
     match cont.body {
-        Body::Enum(_) => {
+        Body::Enum(_, _) => {
             if cont.body.has_getter() {
                 cx.error("#[serde(getter = \"...\")] is not allowed in an enum");
             }
         }
         Body::Struct(_, _) => {
             if cont.body.has_getter() && cont.attrs.remote().is_none() {
                 cx.error(
                     "#[serde(getter = \"...\")] can only be used in structs \
@@ -40,17 +41,17 @@ fn check_getter(cx: &Ctxt, cont: &Contai
 /// The `other` attribute must be used at most once and it must be the last
 /// variant of an enum that has the `field_identifier` attribute.
 ///
 /// Inside a `variant_identifier` all variants must be unit variants. Inside a
 /// `field_identifier` all but possibly one variant must be unit variants. The
 /// last variant may be a newtype variant which is an implicit "other" case.
 fn check_identifier(cx: &Ctxt, cont: &Container) {
     let variants = match cont.body {
-        Body::Enum(ref variants) => variants,
+        Body::Enum(_, ref variants) => variants,
         Body::Struct(_, _) => {
             return;
         }
     };
 
     for (i, variant) in variants.iter().enumerate() {
         match (variant.style, cont.attrs.identifier(), variant.attrs.other()) {
             // The `other` attribute may only be used in a field_identifier.
@@ -89,8 +90,63 @@ fn check_identifier(cx: &Ctxt, cont: &Co
             }
 
             (_, Identifier::Variant, false) => {
                 cx.error("variant_identifier may only contain unit variants");
             }
         }
     }
 }
+
+/// Skip-(de)serializing attributes are not allowed on variants marked
+/// (de)serialize_with.
+fn check_variant_skip_attrs(cx: &Ctxt, cont: &Container) {
+    let variants = match cont.body {
+        Body::Enum(_, ref variants) => variants,
+        Body::Struct(_, _) => {
+            return;
+        }
+    };
+
+    for variant in variants.iter() {
+        if variant.attrs.serialize_with().is_some() {
+            if variant.attrs.skip_serializing() {
+                cx.error(format!("variant `{}` cannot have both #[serde(serialize_with)] and \
+                                  #[serde(skip_serializing)]", variant.ident));
+            }
+
+            for (i, field) in variant.fields.iter().enumerate() {
+                let ident = field.ident.as_ref().map_or_else(|| format!("{}", i),
+                                                             |ident| format!("`{}`", ident));
+
+                if field.attrs.skip_serializing() {
+                    cx.error(format!("variant `{}` cannot have both #[serde(serialize_with)] and \
+                                      a field {} marked with #[serde(skip_serializing)]",
+                                     variant.ident, ident));
+                }
+
+                if field.attrs.skip_serializing_if().is_some() {
+                    cx.error(format!("variant `{}` cannot have both #[serde(serialize_with)] and \
+                                      a field {} marked with #[serde(skip_serializing_if)]",
+                                     variant.ident, ident));
+                }
+            }
+        }
+
+        if variant.attrs.deserialize_with().is_some() {
+            if variant.attrs.skip_deserializing() {
+                cx.error(format!("variant `{}` cannot have both #[serde(deserialize_with)] and \
+                                  #[serde(skip_deserializing)]", variant.ident));
+            }
+
+            for (i, field) in variant.fields.iter().enumerate() {
+                if field.attrs.skip_deserializing() {
+                    let ident = field.ident.as_ref().map_or_else(|| format!("{}", i),
+                                                                 |ident| format!("`{}`", ident));
+
+                    cx.error(format!("variant `{}` cannot have both #[serde(deserialize_with)] \
+                                      and a field {} marked with #[serde(skip_deserializing)]",
+                                     variant.ident, ident));
+                }
+            }
+        }
+    }
+}
--- a/third_party/rust/serde_derive_internals/src/lib.rs
+++ b/third_party/rust/serde_derive_internals/src/lib.rs
@@ -1,17 +1,17 @@
 // Copyright 2017 Serde Developers
 //
 // 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.
 
-#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.15.1")]
+#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.17.0")]
 
 extern crate syn;
 #[macro_use]
 extern crate synom;
 
 pub mod ast;
 pub mod attr;
 
deleted file mode 100644
--- a/third_party/rust/smallvec-0.5.0/.cargo-checksum.json
+++ /dev/null
@@ -1,1 +0,0 @@
-{"files":{".travis.yml":"91edce5ea2a1956399db4b17f580c8b7995af3aa9801c4314865f560c55d6d09","Cargo.toml":"bc42bda24309b1a1d289458aad00fc1e1b354586c5e7f69ab0c83a16b66d4b61","README.md":"ecca7edfce86fe7b219535e3c14721d1de838de7035de077a4d497959260bccc","benches/bench.rs":"54cf4879d36ba2a9f3423af91bb93227b70849200e5bf74e384a166d6aa09893","lib.rs":"517f626b3d4649ae03cee12d6dd26d4baf8a6e1fac9bf410796f08a3e784007f"},"package":"872c0ff227000041c520cca51e883b858d388ab0ecf646bab76f065cebaec025"}
\ No newline at end of file
deleted file mode 100644
--- a/third_party/rust/smallvec-0.5.0/.travis.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-language: rust
-rust:
-  - nightly
-  - beta
-  - stable
-script: |
-  cargo build --verbose &&
-  cargo build --all-features --verbose &&
-  cargo test --verbose &&
-  cargo test --all-features --verbose &&
-  ([ $TRAVIS_RUST_VERSION != nightly ] || cargo test --verbose --no-default-features) &&
-  ([ $TRAVIS_RUST_VERSION != nightly ] || cargo bench --verbose bench)
-notifications:
-  webhooks: http://build.servo.org:54856/travis
deleted file mode 100644
--- a/third_party/rust/smallvec-0.5.0/Cargo.toml
+++ /dev/null
@@ -1,35 +0,0 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g. crates.io) dependencies
-#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
-[package]
-name = "smallvec"
-version = "0.5.0"
-authors = ["Simon Sapin <simon.sapin@exyr.org>"]
-description = "'Small vector' optimization: store up to a small number of items on the stack"
-documentation = "http://doc.servo.org/smallvec/"
-readme = "README.md"
-keywords = ["small", "vec", "vector", "stack", "no_std"]
-license = "MPL-2.0"
-repository = "https://github.com/servo/rust-smallvec"
-
-[lib]
-name = "smallvec"
-path = "lib.rs"
-[dependencies.serde]
-version = "1"
-optional = true
-[dev-dependencies.bincode]
-version = "0.8"
-
-[features]
-default = ["std"]
-std = []
deleted file mode 100644
--- a/third_party/rust/smallvec-0.5.0/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-rust-smallvec
-=============
-
-[Documentation](http://docs.rs/smallvec/)
-
-"Small vector" optimization for Rust: store up to a small number of items on the stack
deleted file mode 100644
--- a/third_party/rust/smallvec-0.5.0/benches/bench.rs
+++ /dev/null
@@ -1,111 +0,0 @@
-#![feature(test)]
-
-extern crate smallvec;
-extern crate test;
-
-use smallvec::SmallVec;
-use self::test::Bencher;
-
-#[bench]
-fn bench_push(b: &mut Bencher) {
-    #[inline(never)]
-    fn push_noinline(vec: &mut SmallVec<[u64; 16]>, x: u64) {
-        vec.push(x)
-    }
-
-    b.iter(|| {
-        let mut vec: SmallVec<[u64; 16]> = SmallVec::new();
-        for x in 0..100 {
-            push_noinline(&mut vec, x);
-        }
-        vec
-    });
-}
-
-#[bench]
-fn bench_insert(b: &mut Bencher) {
-    #[inline(never)]
-    fn insert_noinline(vec: &mut SmallVec<[u64; 16]>, x: u64) {
-        vec.insert(0, x)
-    }
-
-    b.iter(|| {
-        let mut vec: SmallVec<[u64; 16]> = SmallVec::new();
-        for x in 0..100 {
-            insert_noinline(&mut vec, x);
-        }
-        vec
-    });
-}
-
-#[bench]
-fn bench_insert_many(b: &mut Bencher) {
-    #[inline(never)]
-    fn insert_many_noinline<I: IntoIterator<Item=u64>>(
-        vec: &mut SmallVec<[u64; 16]>, index: usize, iterable: I) {
-        vec.insert_many(index, iterable)
-    }
-
-    b.iter(|| {
-        let mut vec: SmallVec<[u64; 16]> = SmallVec::new();
-        insert_many_noinline(&mut vec, 0, 0..100);
-        insert_many_noinline(&mut vec, 0, 0..100);
-        vec
-    });
-}
-
-#[bench]
-fn bench_extend(b: &mut Bencher) {
-    b.iter(|| {
-        let mut vec: SmallVec<[u64; 16]> = SmallVec::new();
-        vec.extend(0..100);
-        vec
-    });
-}
-
-#[bench]
-fn bench_from_slice(b: &mut Bencher) {
-    let v: Vec<u64> = (0..100).collect();
-    b.iter(|| {
-        let vec: SmallVec<[u64; 16]> = SmallVec::from_slice(&v);
-        vec
-    });
-}
-
-#[bench]
-fn bench_extend_from_slice(b: &mut Bencher) {
-    let v: Vec<u64> = (0..100).collect();
-    b.iter(|| {
-        let mut vec: SmallVec<[u64; 16]> = SmallVec::new();
-        vec.extend_from_slice(&v);
-        vec
-    });
-}
-
-#[bench]
-fn bench_insert_from_slice(b: &mut Bencher) {
-    let v: Vec<u64> = (0..100).collect();
-    b.iter(|| {
-        let mut vec: SmallVec<[u64; 16]> = SmallVec::new();
-        vec.insert_from_slice(0, &v);
-        vec.insert_from_slice(0, &v);
-        vec
-    });
-}
-
-#[bench]
-fn bench_pushpop(b: &mut Bencher) {
-    #[inline(never)]
-    fn pushpop_noinline(vec: &mut SmallVec<[u64; 16]>, x: u64) {
-        vec.push(x);
-        vec.pop();
-    }
-
-    b.iter(|| {
-        let mut vec: SmallVec<[u64; 16]> = SmallVec::new();
-        for x in 0..100 {
-            pushpop_noinline(&mut vec, x);
-        }
-        vec
-    });
-}
deleted file mode 100644
--- a/third_party/rust/smallvec-0.5.0/lib.rs
+++ /dev/null
@@ -1,1723 +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/. */
-
-//! Small vectors in various sizes. These store a certain number of elements inline, and fall back
-//! to the heap for larger allocations.  This can be a useful optimization for improving cache
-//! locality and reducing allocator traffic for workloads that fit within the inline buffer.
-//!
-//! ## no_std support
-//!
-//! By default, `smallvec` depends on `libstd`. However, it can be configured to use the unstable
-//! `liballoc` API instead, for use on platforms that have `liballoc` but not `libstd`.  This
-//! configuration is currently unstable and is not guaranteed to work on all versions of Rust.
-//!
-//! To depend on `smallvec` without `libstd`, use `default-features = false` in the `smallvec`
-//! section of Cargo.toml to disable its `"std"` feature.
-
-#![cfg_attr(not(feature = "std"), no_std)]
-#![cfg_attr(not(feature = "std"), feature(alloc))]
-
-
-#[cfg(not(feature = "std"))]
-#[cfg_attr(test, macro_use)]
-extern crate alloc;
-
-#[cfg(not(feature = "std"))]
-use alloc::Vec;
-
-#[cfg(feature = "serde")]
-extern crate serde;
-
-#[cfg(not(feature = "std"))]
-mod std {
-    pub use core::*;
-}
-
-use std::borrow::{Borrow, BorrowMut};
-use std::cmp;
-use std::fmt;
-use std::hash::{Hash, Hasher};
-use std::iter::{IntoIterator, FromIterator};
-use std::mem;
-use std::ops;
-use std::ptr;
-use std::slice;
-#[cfg(feature = "std")]
-use std::io;
-#[cfg(feature = "serde")]
-use serde::ser::{Serialize, Serializer, SerializeSeq};
-#[cfg(feature = "serde")]
-use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
-#[cfg(feature = "serde")]
-use std::marker::PhantomData;
-
-use SmallVecData::{Inline, Heap};
-
-/// Common operations implemented by both `Vec` and `SmallVec`.
-///
-/// This can be used to write generic code that works with both `Vec` and `SmallVec`.
-///
-/// ## Example
-///
-/// ```rust
-/// use smallvec::{VecLike, SmallVec8};
-///
-/// fn initialize<V: VecLike<u8>>(v: &mut V) {
-///     for i in 0..5 {
-///         v.push(i);
-///     }
-/// }
-///
-/// let mut vec = Vec::new();
-/// initialize(&mut vec);
-///
-/// let mut small_vec = SmallVec8::new();
-/// initialize(&mut small_vec);
-/// ```
-pub trait VecLike<T>:
-        ops::Index<usize, Output=T> +
-        ops::IndexMut<usize> +
-        ops::Index<ops::Range<usize>, Output=[T]> +
-        ops::IndexMut<ops::Range<usize>> +
-        ops::Index<ops::RangeFrom<usize>, Output=[T]> +
-        ops::IndexMut<ops::RangeFrom<usize>> +
-        ops::Index<ops::RangeTo<usize>, Output=[T]> +
-        ops::IndexMut<ops::RangeTo<usize>> +
-        ops::Index<ops::RangeFull, Output=[T]> +
-        ops::IndexMut<ops::RangeFull> +
-        ops::DerefMut<Target = [T]> +
-        Extend<T> {
-
-    /// Append an element to the vector.
-    fn push(&mut self, value: T);
-}
-
-impl<T> VecLike<T> for Vec<T> {
-    #[inline]
-    fn push(&mut self, value: T) {
-        Vec::push(self, value);
-    }
-}
-
-/// Trait to be implemented by a collection that can be extended from a slice
-///
-/// ## Example
-///
-/// ```rust
-/// use smallvec::{ExtendFromSlice, SmallVec8};
-///
-/// fn initialize<V: ExtendFromSlice<u8>>(v: &mut V) {
-///     v.extend_from_slice(b"Test!");
-/// }
-///
-/// let mut vec = Vec::new();
-/// initialize(&mut vec);
-/// assert_eq!(&vec, b"Test!");
-///
-/// let mut small_vec = SmallVec8::new();
-/// initialize(&mut small_vec);
-/// assert_eq!(&small_vec as &[_], b"Test!");
-/// ```
-pub trait ExtendFromSlice<T>: VecLike<T> {
-    /// Extends a collection from a slice of its element type
-    fn extend_from_slice(&mut self, other: &[T]);
-}
-
-impl<T: Clone> ExtendFromSlice<T> for Vec<T> {
-    fn extend_from_slice(&mut self, other: &[T]) {
-        Vec::extend_from_slice(self, other)
-    }
-}
-
-unsafe fn deallocate<T>(ptr: *mut T, capacity: usize) {
-    let _vec: Vec<T> = Vec::from_raw_parts(ptr, 0, capacity);
-    // Let it drop.
-}
-
-pub struct Drain<'a, T: 'a> {
-    iter: slice::IterMut<'a,T>,
-}
-
-impl<'a, T: 'a> Iterator for Drain<'a,T> {
-    type Item = T;
-
-    #[inline]
-    fn next(&mut self) -> Option<T> {
-        match self.iter.next() {
-            None => None,
-            Some(reference) => {
-                unsafe {
-                    Some(ptr::read(reference))
-                }
-            }
-        }
-    }
-
-    #[inline]
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        self.iter.size_hint()
-    }
-}
-
-impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> {
-    #[inline]
-    fn next_back(&mut self) -> Option<T> {
-        match self.iter.next_back() {
-            None => None,
-            Some(reference) => {
-                unsafe {
-                    Some(ptr::read(reference))
-                }
-            }
-        }
-    }
-}
-
-impl<'a, T> ExactSizeIterator for Drain<'a, T> { }
-
-impl<'a, T: 'a> Drop for Drain<'a,T> {
-    fn drop(&mut self) {
-        // Destroy the remaining elements.
-        for _ in self.by_ref() {}
-    }
-}
-
-enum SmallVecData<A: Array> {
-    Inline { array: A },
-    Heap { ptr: *mut A::Item, capacity: usize },
-}
-
-impl<A: Array> SmallVecData<A> {
-    fn ptr_mut(&mut self) -> *mut A::Item {
-        match *self {
-            Inline { ref mut array } => array.ptr_mut(),
-            Heap { ptr, .. } => ptr,
-        }
-    }
-}
-
-unsafe impl<A: Array + Send> Send for SmallVecData<A> {}
-unsafe impl<A: Array + Sync> Sync for SmallVecData<A> {}
-
-impl<A: Array> Drop for SmallVecData<A> {
-    fn drop(&mut self) {
-        unsafe {
-            match *self {
-                ref mut inline @ Inline { .. } => {
-                    // Inhibit the array destructor.
-                    ptr::write(inline, Heap {
-                        ptr: ptr::null_mut(),
-                        capacity: 0,
-                    });
-                }
-                Heap { ptr, capacity } => deallocate(ptr, capacity),
-            }
-        }
-    }
-}
-
-/// A `Vec`-like container that can store a small number of elements inline.
-///
-/// `SmallVec` acts like a vector, but can store a limited amount of data inline within the
-/// `Smallvec` struct rather than in a separate allocation.  If the data exceeds this limit, the
-/// `SmallVec` will "spill" its data onto the heap, allocating a new buffer to hold it.
-///
-/// The amount of data that a `SmallVec` can store inline depends on its backing store. The backing
-/// store can be any type that implements the `Array` trait; usually it is a small fixed-sized
-/// array.  For example a `SmallVec<[u64; 8]>` can hold up to eight 64-bit integers inline.
-///
-/// Type aliases like `SmallVec8<T>` are provided as convenient shorthand for types like
-/// `SmallVec<[T; 8]>`.
-///
-/// ## Example
-///
-/// ```rust
-/// use smallvec::SmallVec;
-/// let mut v = SmallVec::<[u8; 4]>::new(); // initialize an empty vector
-///
-/// use smallvec::SmallVec4;
-/// let mut v: SmallVec4<u8> = SmallVec::new(); // alternate way to write the above
-///
-/// // SmallVec4 can hold up to 4 items without spilling onto the heap.
-/// v.extend(0..4);
-/// assert_eq!(v.len(), 4);
-/// assert!(!v.spilled());
-///
-/// // Pushing another element will force the buffer to spill:
-/// v.push(4);
-/// assert_eq!(v.len(), 5);
-/// assert!(v.spilled());
-/// ```
-pub struct SmallVec<A: Array> {
-    len: usize,
-    data: SmallVecData<A>,
-}
-
-impl<A: Array> SmallVec<A> {
-    /// Construct an empty vector
-    #[inline]
-    pub fn new() -> SmallVec<A> {
-        unsafe {
-            SmallVec {
-                len: 0,
-                data: Inline { array: mem::uninitialized() },
-            }
-        }
-    }
-
-    /// Construct an empty vector with enough capacity pre-allocated to store at least `n`
-    /// elements.
-    ///
-    /// Will create a heap allocation only if `n` is larger than the inline capacity.
-    ///
-    /// ```
-    /// # use smallvec::SmallVec;
-    ///
-    /// let v: SmallVec<[u8; 3]> = SmallVec::with_capacity(100);
-    ///
-    /// assert!(v.is_empty());
-    /// assert!(v.capacity() >= 100);
-    /// ```
-    #[inline]
-    pub fn with_capacity(n: usize) -> Self {
-        let mut v = SmallVec::new();
-        v.reserve_exact(n);
-        v
-    }
-
-    /// Construct a new `SmallVec` from a `Vec<A::Item>` without copying
-    /// elements.
-    ///
-    /// ```rust
-    /// use smallvec::SmallVec;
-    ///
-    /// let vec = vec![1, 2, 3, 4, 5];
-    /// let small_vec: SmallVec<[_; 3]> = SmallVec::from_vec(vec);
-    ///
-    /// assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
-    /// ```
-    #[inline]
-    pub fn from_vec(mut vec: Vec<A::Item>) -> SmallVec<A> {
-        let (ptr, cap, len) = (vec.as_mut_ptr(), vec.capacity(), vec.len());
-        mem::forget(vec);
-
-        SmallVec {
-            len: len,
-            data: SmallVecData::Heap {
-                ptr: ptr,
-                capacity: cap
-            }
-        }
-    }
-
-    /// Constructs a new `SmallVec` on the stack from an `A` without
-    /// copying elements.
-    ///
-    /// ```rust
-    /// use smallvec::SmallVec;
-    ///
-    /// let buf = [1, 2, 3, 4, 5];
-    /// let small_vec: SmallVec<_> = SmallVec::from_buf(buf);
-    ///
-    /// assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
-    /// ```
-    #[inline]
-    pub fn from_buf(buf: A) -> SmallVec<A> {
-        SmallVec {
-            len: A::size(),
-            data: SmallVecData::Inline { array: buf },
-        }
-    }
-
-    /// Sets the length of a vector.
-    ///
-    /// This will explicitly set the size of the vector, without actually
-    /// modifying its buffers, so it is up to the caller to ensure that the
-    /// vector is actually the specified size.
-    pub unsafe fn set_len(&mut self, new_len: usize) {
-        self.len = new_len
-    }
-
-    /// The maximum number of elements this vector can hold inline
-    #[inline]
-    pub fn inline_size(&self) -> usize {
-        A::size()
-    }
-
-    /// The number of elements stored in the vector
-    #[inline]
-    pub fn len(&self) -> usize {
-        self.len
-    }
-
-    /// Returns `true` if the vector is empty
-    #[inline]
-    pub fn is_empty(&self) -> bool {
-        self.len == 0
-    }
-
-    /// The number of items the vector can hold without reallocating
-    #[inline]
-    pub fn capacity(&self) -> usize {
-        match self.data {
-            Inline { .. } => A::size(),
-            Heap { capacity, .. } => capacity,
-        }
-    }
-
-    /// Returns `true` if the data has spilled into a separate heap-allocated buffer.
-    #[inline]
-    pub fn spilled(&self) -> bool {
-        match self.data {
-            Inline { .. } => false,
-            Heap { .. } => true,
-        }
-    }
-
-    /// Empty the vector and return an iterator over its former contents.
-    pub fn drain(&mut self) -> Drain<A::Item> {
-        unsafe {
-            let current_len = self.len();
-            self.set_len(0);
-
-            let ptr = self.data.ptr_mut();
-
-            let slice = slice::from_raw_parts_mut(ptr, current_len);
-
-            Drain {
-                iter: slice.iter_mut(),
-            }
-        }
-    }
-
-    /// Append an item to the vector.
-    #[inline]
-    pub fn push(&mut self, value: A::Item) {
-        let cap = self.capacity();
-        if self.len == cap {
-            self.grow(cmp::max(cap * 2, 1))
-        }
-        unsafe {
-            let end = self.as_mut_ptr().offset(self.len as isize);
-            ptr::write(end, value);
-            let len = self.len;
-            self.set_len(len + 1)
-        }
-    }
-
-    /// Append elements from an iterator.
-    ///
-    /// This function is deprecated; it has been replaced by `Extend::extend`.
-    #[deprecated(note = "Use `extend` instead")]
-    pub fn push_all_move<V: IntoIterator<Item=A::Item>>(&mut self, other: V) {
-        self.extend(other)
-    }
-
-    /// Remove an item from the end of the vector and return it, or None if empty.
-    #[inline]
-    pub fn pop(&mut self) -> Option<A::Item> {
-        if self.len == 0 {
-            return None
-        }
-        let last_index = self.len - 1;
-        if (last_index as isize) < 0 {
-            panic!("overflow")
-        }
-        unsafe {
-            let end_ptr = self.as_ptr().offset(last_index as isize);
-            let value = ptr::read(end_ptr);
-            self.set_len(last_index);
-            Some(value)
-        }
-    }
-
-    /// Re-allocate to set the capacity to `new_cap`.
-    ///
-    /// Panics if `new_cap` is less than the vector's length.
-    pub fn grow(&mut self, new_cap: usize) {
-        assert!(new_cap >= self.len);
-        let mut vec: Vec<A::Item> = Vec::with_capacity(new_cap);
-        let new_alloc = vec.as_mut_ptr();
-        unsafe {
-            mem::forget(vec);
-            ptr::copy_nonoverlapping(self.as_ptr(), new_alloc, self.len);
-
-            match self.data {
-                Inline { .. } => {}
-                Heap { ptr, capacity } => deallocate(ptr, capacity),
-            }
-            ptr::write(&mut self.data, Heap {
-                ptr: new_alloc,
-                capacity: new_cap,
-            });
-        }
-    }
-
-    /// Reserve capacity for `additional` more elements to be inserted.
-    ///
-    /// May reserve more space to avoid frequent reallocations.
-    ///
-    /// If the new capacity would overflow `usize` then it will be set to `usize::max_value()`
-    /// instead. (This means that inserting `additional` new elements is not guaranteed to be
-    /// possible after calling this function.)
-    pub fn reserve(&mut self, additional: usize) {
-        let len = self.len();
-        if self.capacity() - len < additional {
-            match len.checked_add(additional).and_then(usize::checked_next_power_of_two) {
-                Some(cap) => self.grow(cap),
-                None => self.grow(usize::max_value()),
-            }
-        }
-    }
-
-    /// Reserve the minumum capacity for `additional` more elements to be inserted.
-    ///
-    /// Panics if the new capacity overflows `usize`.
-    pub fn reserve_exact(&mut self, additional: usize) {
-        let len = self.len();
-        if self.capacity() - len < additional {
-            match len.checked_add(additional) {
-                Some(cap) => self.grow(cap),
-                None => panic!("reserve_exact overflow"),
-            }
-        }
-    }
-
-    /// Shrink the capacity of the vector as much as possible.
-    ///
-    /// When possible, this will move data from an external heap buffer to the vector's inline
-    /// storage.
-    pub fn shrink_to_fit(&mut self) {
-        let len = self.len;
-        if self.inline_size() >= len {
-            unsafe {
-                let (ptr, capacity) = match self.data {
-                    Inline { .. } => return,
-                    Heap { ptr, capacity } => (ptr, capacity),
-                };
-                ptr::write(&mut self.data, Inline { array: mem::uninitialized() });
-                ptr::copy_nonoverlapping(ptr, self.as_mut_ptr(), len);
-                deallocate(ptr, capacity);
-            }
-        } else if self.capacity() > len {
-            self.grow(len);
-        }
-    }
-
-    /// Shorten the vector, keeping the first `len` elements and dropping the rest.
-    ///
-    /// If `len` is greater than or equal to the vector's current length, this has no
-    /// effect.
-    ///
-    /// This does not re-allocate.  If you want the vector's capacity to shrink, call
-    /// `shrink_to_fit` after truncating.
-    pub fn truncate(&mut self, len: usize) {
-        let end_ptr = self.as_ptr();
-        while len < self.len {
-            unsafe {
-                let last_index = self.len - 1;
-                self.set_len(last_index);
-                ptr::read(end_ptr.offset(last_index as isize));
-            }
-        }
-    }
-
-    /// Extracts a slice containing the entire vector.
-    ///
-    /// Equivalent to `&mut s[..]`.
-    pub fn as_slice(&self) -> &[A::Item] {
-        self
-    }
-
-    /// Extracts a mutable slice of the entire vector.
-    ///
-    /// Equivalent to `&mut s[..]`.
-    pub fn as_mut_slice(&mut self) -> &mut [A::Item] {
-        self
-    }
-
-    /// Remove the element at position `index`, replacing it with the last element.
-    ///
-    /// This does not preserve ordering, but is O(1).
-    ///
-    /// Panics if `index` is out of bounds.
-    #[inline]
-    pub fn swap_remove(&mut self, index: usize) -> A::Item {
-        let len = self.len;
-        self.swap(len - 1, index);
-        self.pop().unwrap()
-    }
-
-    /// Remove all elements from the vector.
-    #[inline]
-    pub fn clear(&mut self) {
-        self.truncate(0);
-    }
-
-    /// Remove and return the element at position `index`, shifting all elements after it to the
-    /// left.
-    ///
-    /// Panics if `index` is out of bounds.
-    pub fn remove(&mut self, index: usize) -> A::Item {
-        let len = self.len();
-
-        assert!(index < len);
-
-        unsafe {
-            let ptr = self.as_mut_ptr().offset(index as isize);
-            let item = ptr::read(ptr);
-            ptr::copy(ptr.offset(1), ptr, len - index - 1);
-            self.set_len(len - 1);
-            item
-        }
-    }
-
-    /// Insert an element at position `index`, shifting all elements after it to the right.
-    ///
-    /// Panics if `index` is out of bounds.
-    pub fn insert(&mut self, index: usize, element: A::Item) {
-        self.reserve(1);
-
-        let len = self.len;
-        assert!(index <= len);
-
-        unsafe {
-            let ptr = self.as_mut_ptr().offset(index as isize);
-            ptr::copy(ptr, ptr.offset(1), len - index);
-            ptr::write(ptr, element);
-            self.set_len(len + 1);
-        }
-    }
-
-    pub fn insert_many<I: IntoIterator<Item=A::Item>>(&mut self, index: usize, iterable: I) {
-        let iter = iterable.into_iter();
-        let (lower_size_bound, _) = iter.size_hint();
-        assert!(lower_size_bound <= std::isize::MAX as usize);  // Ensure offset is indexable
-        assert!(index + lower_size_bound >= index);  // Protect against overflow
-        self.reserve(lower_size_bound);
-
-        unsafe {
-            let old_len = self.len;
-            assert!(index <= old_len);
-            let ptr = self.as_mut_ptr().offset(index as isize);
-            ptr::copy(ptr, ptr.offset(lower_size_bound as isize), old_len - index);
-            for (off, element) in iter.enumerate() {
-                if off < lower_size_bound {
-                    ptr::write(ptr.offset(off as isize), element);
-                    self.len = self.len + 1;
-                } else {
-                    // Iterator provided more elements than the hint.
-                    assert!(index + off >= index);  // Protect against overflow.
-                    self.insert(index + off, element);
-                }
-            }
-            let num_added = self.len - old_len;
-            if num_added < lower_size_bound {
-                // Iterator provided fewer elements than the hint
-                ptr::copy(ptr.offset(lower_size_bound as isize), ptr.offset(num_added as isize), old_len - index);
-            }
-        }
-    }
-
-    /// Convert a SmallVec to a Vec, without reallocating if the SmallVec has already spilled onto
-    /// the heap.
-    pub fn into_vec(self) -> Vec<A::Item> {
-        match self.data {
-            Inline { .. } => self.into_iter().collect(),
-            Heap { ptr, capacity } => unsafe {
-                let v = Vec::from_raw_parts(ptr, self.len, capacity);
-                mem::forget(self);
-                v
-            }
-        }
-    }
-
-    /// Retains only the elements specified by the predicate.
-    ///
-    /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
-    /// This method operates in place and preserves the order of the retained
-    /// elements.
-    pub fn retain<F: FnMut(&A::Item) -> bool>(&mut self, mut f: F) {
-        let mut del = 0;
-        let len = self.len;
-        for i in 0..len {
-            if !f(&self[i]) {
-                del += 1;
-            } else if del > 0 {
-                self.swap(i - del, i);
-            }
-        }
-        self.truncate(len - del);
-    }
-}
-
-impl<A: Array> SmallVec<A> where A::Item: Copy {
-    pub fn from_slice(slice: &[A::Item]) -> Self {
-        let mut vec = Self::new();
-        vec.extend_from_slice(slice);
-        vec
-    }
-
-    pub fn insert_from_slice(&mut self, index: usize, slice: &[A::Item]) {
-        self.reserve(slice.len());
-
-        let len = self.len;
-        assert!(index <= len);
-
-        unsafe {
-            let slice_ptr = slice.as_ptr();
-            let ptr = self.as_mut_ptr().offset(index as isize);
-            ptr::copy(ptr, ptr.offset(slice.len() as isize), len - index);
-            ptr::copy(slice_ptr, ptr, slice.len());
-            self.set_len(len + slice.len());
-        }
-    }
-
-    #[inline]
-    pub fn extend_from_slice(&mut self, slice: &[A::Item]) {
-        let len = self.len();
-        self.insert_from_slice(len, slice);
-    }
-}
-
-impl<A: Array> ops::Deref for SmallVec<A> {
-    type Target = [A::Item];
-    #[inline]
-    fn deref(&self) -> &[A::Item] {
-        let ptr: *const _ = match self.data {
-            Inline { ref array } => array.ptr(),
-            Heap { ptr, .. } => ptr,
-        };
-        unsafe {
-            slice::from_raw_parts(ptr, self.len)
-        }
-    }
-}
-
-impl<A: Array> ops::DerefMut for SmallVec<A> {
-    #[inline]
-    fn deref_mut(&mut self) -> &mut [A::Item] {
-        let ptr = self.data.ptr_mut();
-        unsafe {
-            slice::from_raw_parts_mut(ptr, self.len)
-        }
-    }
-}
-
-impl<A: Array> AsRef<[A::Item]> for SmallVec<A> {
-    #[inline]
-    fn as_ref(&self) -> &[A::Item] {
-        self
-    }
-}
-
-impl<A: Array> AsMut<[A::Item]> for SmallVec<A> {
-    #[inline]
-    fn as_mut(&mut self) -> &mut [A::Item] {
-        self
-    }
-}
-
-impl<A: Array> Borrow<[A::Item]> for SmallVec<A> {
-    #[inline]
-    fn borrow(&self) -> &[A::Item] {
-        self
-    }
-}
-
-impl<A: Array> BorrowMut<[A::Item]> for SmallVec<A> {
-    #[inline]
-    fn borrow_mut(&mut self) -> &mut [A::Item] {
-        self
-    }
-}
-
-#[cfg(feature = "std")]
-impl<A: Array<Item = u8>> io::Write for SmallVec<A> {
-    #[inline]
-    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        self.extend_from_slice(buf);
-        Ok(buf.len())
-    }
-
-    #[inline]
-    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
-        self.extend_from_slice(buf);
-        Ok(())
-    }
-
-    #[inline]
-    fn flush(&mut self) -> io::Result<()> {
-        Ok(())
-    }
-}
-
-#[cfg(feature = "serde")]
-impl<A: Array> Serialize for SmallVec<A> where A::Item: Serialize {
-    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
-        let mut state = serializer.serialize_seq(Some(self.len()))?;
-        for item in self {
-            state.serialize_element(&item)?;
-        }
-        state.end()
-    }
-}
-
-#[cfg(feature = "serde")]
-impl<'de, A: Array> Deserialize<'de> for SmallVec<A> where A::Item: Deserialize<'de> {
-    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
-        deserializer.deserialize_seq(SmallVecVisitor{phantom: PhantomData})
-    }
-}
-
-#[cfg(feature = "serde")]
-struct SmallVecVisitor<A> {
-    phantom: PhantomData<A>
-}
-
-#[cfg(feature = "serde")]
-impl<'de, A: Array> Visitor<'de> for SmallVecVisitor<A>
-where A::Item: Deserialize<'de>,
-{
-    type Value = SmallVec<A>;
-
-    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
-        formatter.write_str("a sequence")
-    }
-
-    fn visit_seq<B>(self, mut seq: B) -> Result<Self::Value, B::Error>
-        where
-            B: SeqAccess<'de>,
-    {
-        let mut values = SmallVec::new();
-
-        while let Some(value) = seq.next_element()? {
-            values.push(value);
-        }
-
-        Ok(values)
-    }
-}
-
-impl<'a, A: Array> From<&'a [A::Item]> for SmallVec<A> where A::Item: Clone {
-    #[inline]
-    fn from(slice: &'a [A::Item]) -> SmallVec<A> {
-        slice.into_iter().cloned().collect()
-    }
-}
-
-impl<A: Array> From<Vec<A::Item>> for SmallVec<A> {
-    #[inline]
-    fn from(vec: Vec<A::Item>) -> SmallVec<A> {
-        SmallVec::from_vec(vec)
-    }
-}
-
-impl<A: Array> From<A> for SmallVec<A> {
-    #[inline]
-    fn from(array: A) -> SmallVec<A> {
-        SmallVec::from_buf(array)
-    }
-}
-
-macro_rules! impl_index {
-    ($index_type: ty, $output_type: ty) => {
-        impl<A: Array> ops::Index<$index_type> for SmallVec<A> {
-            type Output = $output_type;
-            #[inline]
-            fn index(&self, index: $index_type) -> &$output_type {
-                &(&**self)[index]
-            }
-        }
-
-        impl<A: Array> ops::IndexMut<$index_type> for SmallVec<A> {
-            #[inline]
-            fn index_mut(&mut self, index: $index_type) -> &mut $output_type {
-                &mut (&mut **self)[index]
-            }
-        }
-    }
-}
-
-impl_index!(usize, A::Item);
-impl_index!(ops::Range<usize>, [A::Item]);
-impl_index!(ops::RangeFrom<usize>, [A::Item]);
-impl_index!(ops::RangeTo<usize>, [A::Item]);
-impl_index!(ops::RangeFull, [A::Item]);
-
-impl<A: Array> ExtendFromSlice<A::Item> for SmallVec<A> where A::Item: Copy {
-    fn extend_from_slice(&mut self, other: &[A::Item]) {
-        SmallVec::extend_from_slice(self, other)
-    }
-}
-
-impl<A: Array> VecLike<A::Item> for SmallVec<A> {
-    #[inline]
-    fn push(&mut self, value: A::Item) {
-        SmallVec::push(self, value);
-    }
-}
-
-impl<A: Array> FromIterator<A::Item> for SmallVec<A> {
-    fn from_iter<I: IntoIterator<Item=A::Item>>(iterable: I) -> SmallVec<A> {
-        let mut v = SmallVec::new();
-        v.extend(iterable);
-        v
-    }
-}
-
-impl<A: Array> Extend<A::Item> for SmallVec<A> {
-    fn extend<I: IntoIterator<Item=A::Item>>(&mut self, iterable: I) {
-        let iter = iterable.into_iter();
-        let (lower_size_bound, _) = iter.size_hint();
-
-        let target_len = self.len + lower_size_bound;
-
-        if target_len > self.capacity() {
-           self.grow(target_len);
-        }
-
-        for elem in iter {
-            self.push(elem);
-        }
-    }
-}
-
-impl<A: Array> fmt::Debug for SmallVec<A> where A::Item: fmt::Debug {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{:?}", &**self)
-    }
-}
-
-impl<A: Array> Default for SmallVec<A> {
-    #[inline]
-    fn default() -> SmallVec<A> {
-        SmallVec::new()
-    }
-}
-
-impl<A: Array> Drop for SmallVec<A> {
-    fn drop(&mut self) {
-        // Note on panic safety: dropping an element may panic,
-        // but the inner SmallVecData destructor will still run
-        unsafe {
-            let ptr = self.as_ptr();
-            for i in 0 .. self.len {
-                ptr::read(ptr.offset(i as isize));
-            }
-        }
-    }
-}
-
-impl<A: Array> Clone for SmallVec<A> where A::Item: Clone {
-    fn clone(&self) -> SmallVec<A> {
-        let mut new_vector = SmallVec::new();
-        for element in self.iter() {
-            new_vector.push((*element).clone())
-        }
-        new_vector
-    }
-}
-
-impl<A: Array, B: Array> PartialEq<SmallVec<B>> for SmallVec<A>
-    where A::Item: PartialEq<B::Item> {
-    #[inline]
-    fn eq(&self, other: &SmallVec<B>) -> bool { self[..] == other[..] }
-    #[inline]
-    fn ne(&self, other: &SmallVec<B>) -> bool { self[..] != other[..] }
-}
-
-impl<A: Array> Eq for SmallVec<A> where A::Item: Eq {}
-
-impl<A: Array> PartialOrd for SmallVec<A> where A::Item: PartialOrd {
-    #[inline]
-    fn partial_cmp(&self, other: &SmallVec<A>) -> Option<cmp::Ordering> {
-        PartialOrd::partial_cmp(&**self, &**other)
-    }
-}
-
-impl<A: Array> Ord for SmallVec<A> where A::Item: Ord {
-    #[inline]
-    fn cmp(&self, other: &SmallVec<A>) -> cmp::Ordering {
-        Ord::cmp(&**self, &**other)
-    }
-}
-
-impl<A: Array> Hash for SmallVec<A> where A::Item: Hash {
-    fn hash<H: Hasher>(&self, state: &mut H) {
-        (**self).hash(state)
-    }
-}
-
-unsafe impl<A: Array> Send for SmallVec<A> where A::Item: Send {}
-
-pub struct IntoIter<A: Array> {
-    data: SmallVecData<A>,
-    current: usize,
-    end: usize,
-}
-
-impl<A: Array> Drop for IntoIter<A> {
-    fn drop(&mut self) {
-        for _ in self { }
-    }
-}
-
-impl<A: Array> Iterator for IntoIter<A> {
-    type Item = A::Item;
-
-    #[inline]
-    fn next(&mut self) -> Option<A::Item> {
-        if self.current == self.end {
-            None
-        }
-        else {
-            unsafe {
-                let current = self.current as isize;
-                self.current += 1;
-                Some(ptr::read(self.data.ptr_mut().offset(current)))
-            }
-        }
-    }
-
-    #[inline]
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        let size = self.end - self.current;
-        (size, Some(size))
-    }
-}
-
-impl<A: Array> DoubleEndedIterator for IntoIter<A> {
-    #[inline]
-    fn next_back(&mut self) -> Option<A::Item> {
-        if self.current == self.end {
-            None
-        }
-        else {
-            unsafe {
-                self.end -= 1;
-                Some(ptr::read(self.data.ptr_mut().offset(self.end as isize)))
-            }
-        }
-    }
-}
-
-impl<A: Array> ExactSizeIterator for IntoIter<A> { }
-
-impl<A: Array> IntoIterator for SmallVec<A> {
-    type IntoIter = IntoIter<A>;
-    type Item = A::Item;
-    fn into_iter(mut self) -> Self::IntoIter {
-        let len = self.len();
-        unsafe {
-            // Only grab the `data` field, the `IntoIter` type handles dropping of the elements
-            let data = ptr::read(&mut self.data);
-            mem::forget(self);
-            IntoIter {
-                data: data,
-                current: 0,
-                end: len,
-            }
-        }
-    }
-}
-
-impl<'a, A: Array> IntoIterator for &'a SmallVec<A> {
-    type IntoIter = slice::Iter<'a, A::Item>;
-    type Item = &'a A::Item;
-    fn into_iter(self) -> Self::IntoIter {
-        self.iter()
-    }
-}
-
-impl<'a, A: Array> IntoIterator for &'a mut SmallVec<A> {
-    type IntoIter = slice::IterMut<'a, A::Item>;
-    type Item = &'a mut A::Item;
-    fn into_iter(self) -> Self::IntoIter {
-        self.iter_mut()
-    }
-}
-
-// TODO: Remove these and its users.
-
-/// Deprecated alias to ease transition from an earlier version.
-#[deprecated]
-pub type SmallVec1<T> = SmallVec<[T; 1]>;
-
-/// Deprecated alias to ease transition from an earlier version.
-#[deprecated]
-pub type SmallVec2<T> = SmallVec<[T; 2]>;
-
-/// Deprecated alias to ease transition from an earlier version.
-#[deprecated]
-pub type SmallVec4<T> = SmallVec<[T; 4]>;
-
-/// Deprecated alias to ease transition from an earlier version.
-#[deprecated]
-pub type SmallVec8<T> = SmallVec<[T; 8]>;
-
-/// Deprecated alias to ease transition from an earlier version.
-#[deprecated]
-pub type SmallVec16<T> = SmallVec<[T; 16]>;
-
-/// Deprecated alias to ease transition from an earlier version.
-#[deprecated]
-pub type SmallVec24<T> = SmallVec<[T; 24]>;
-
-/// Deprecated alias to ease transition from an earlier version.
-#[deprecated]
-pub type SmallVec32<T> = SmallVec<[T; 32]>;
-
-/// Types that can be used as the backing store for a SmallVec
-pub unsafe trait Array {
-    type Item;
-    fn size() -> usize;
-    fn ptr(&self) -> *const Self::Item;
-    fn ptr_mut(&mut self) -> *mut Self::Item;
-}
-
-macro_rules! impl_array(
-    ($($size:expr),+) => {
-        $(
-            unsafe impl<T> Array for [T; $size] {
-                type Item = T;
-                fn size() -> usize { $size }
-                fn ptr(&self) -> *const T { &self[0] }
-                fn ptr_mut(&mut self) -> *mut T { &mut self[0] }
-            }
-        )+
-    }
-);
-
-impl_array!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 24, 32, 36,
-            0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000,
-            0x10000, 0x20000, 0x40000, 0x80000, 0x100000);
-
-#[cfg(test)]
-pub mod tests {
-    use SmallVec;
-
-    use std::iter::FromIterator;
-
-    #[cfg(feature = "std")]
-    use std::borrow::ToOwned;
-    #[cfg(not(feature = "std"))]
-    use alloc::borrow::ToOwned;
-    #[cfg(feature = "std")]
-    use std::rc::Rc;
-    #[cfg(not(feature = "std"))]
-    use alloc::rc::Rc;
-    #[cfg(not(feature = "std"))]
-    use alloc::boxed::Box;
-    #[cfg(not(feature = "std"))]
-    use alloc::vec::Vec;
-
-    // We heap allocate all these strings so that double frees will show up under valgrind.
-
-    #[test]
-    pub fn test_inline() {
-        let mut v = SmallVec::<[_; 16]>::new();
-        v.push("hello".to_owned());
-        v.push("there".to_owned());
-        assert_eq!(&*v, &[
-            "hello".to_owned(),
-            "there".to_owned(),
-        ][..]);
-    }
-
-    #[test]
-    pub fn test_spill() {
-        let mut v = SmallVec::<[_; 2]>::new();
-        v.push("hello".to_owned());
-        assert_eq!(v[0], "hello");
-        v.push("there".to_owned());
-        v.push("burma".to_owned());
-        assert_eq!(v[0], "hello");
-        v.push("shave".to_owned());
-        assert_eq!(&*v, &[
-            "hello".to_owned(),
-            "there".to_owned(),
-            "burma".to_owned(),
-            "shave".to_owned(),
-        ][..]);
-    }
-
-    #[test]
-    pub fn test_double_spill() {
-        let mut v = SmallVec::<[_; 2]>::new();
-        v.push("hello".to_owned());
-        v.push("there".to_owned());
-        v.push("burma".to_owned());
-        v.push("shave".to_owned());
-        v.push("hello".to_owned());
-        v.push("there".to_owned());
-        v.push("burma".to_owned());
-        v.push("shave".to_owned());
-        assert_eq!(&*v, &[
-            "hello".to_owned(),
-            "there".to_owned(),
-            "burma".to_owned(),
-            "shave".to_owned(),
-            "hello".to_owned(),
-            "there".to_owned(),
-            "burma".to_owned(),
-            "shave".to_owned(),
-        ][..]);
-    }
-
-    /// https://github.com/servo/rust-smallvec/issues/4
-    #[test]
-    fn issue_4() {
-        SmallVec::<[Box<u32>; 2]>::new();
-    }
-
-    /// https://github.com/servo/rust-smallvec/issues/5
-    #[test]
-    fn issue_5() {
-        assert!(Some(SmallVec::<[&u32; 2]>::new()).is_some());
-    }
-
-    #[test]
-    fn test_with_capacity() {
-        let v: SmallVec<[u8; 3]> = SmallVec::with_capacity(1);
-        assert!(v.is_empty());
-        assert!(!v.spilled());
-        assert_eq!(v.capacity(), 3);
-
-        let v: SmallVec<[u8; 3]> = SmallVec::with_capacity(10);
-        assert!(v.is_empty());
-        assert!(v.spilled());
-        assert_eq!(v.capacity(), 10);
-    }
-
-    #[test]
-    fn drain() {
-        let mut v: SmallVec<[u8; 2]> = SmallVec::new();
-        v.push(3);
-        assert_eq!(v.drain().collect::<Vec<_>>(), &[3]);
-
-        // spilling the vec
-        v.push(3);
-        v.push(4);
-        v.push(5);
-        assert_eq!(v.drain().collect::<Vec<_>>(), &[3, 4, 5]);
-    }
-
-    #[test]
-    fn drain_rev() {
-        let mut v: SmallVec<[u8; 2]> = SmallVec::new();
-        v.push(3);
-        assert_eq!(v.drain().rev().collect::<Vec<_>>(), &[3]);
-
-        // spilling the vec
-        v.push(3);
-        v.push(4);
-        v.push(5);
-        assert_eq!(v.drain().rev().collect::<Vec<_>>(), &[5, 4, 3]);
-    }
-
-    #[test]
-    fn into_iter() {
-        let mut v: SmallVec<[u8; 2]> = SmallVec::new();
-        v.push(3);
-        assert_eq!(v.into_iter().collect::<Vec<_>>(), &[3]);
-
-        // spilling the vec
-        let mut v: SmallVec<[u8; 2]> = SmallVec::new();
-        v.push(3);
-        v.push(4);
-        v.push(5);
-        assert_eq!(v.into_iter().collect::<Vec<_>>(), &[3, 4, 5]);
-    }
-
-    #[test]
-    fn into_iter_rev() {
-        let mut v: SmallVec<[u8; 2]> = SmallVec::new();
-        v.push(3);
-        assert_eq!(v.into_iter().rev().collect::<Vec<_>>(), &[3]);
-
-        // spilling the vec
-        let mut v: SmallVec<[u8; 2]> = SmallVec::new();
-        v.push(3);
-        v.push(4);
-        v.push(5);
-        assert_eq!(v.into_iter().rev().collect::<Vec<_>>(), &[5, 4, 3]);
-    }
-
-    #[test]
-    fn into_iter_drop() {
-        use std::cell::Cell;
-
-        struct DropCounter<'a>(&'a Cell<i32>);
-
-        impl<'a> Drop for DropCounter<'a> {
-            fn drop(&mut self) {
-                self.0.set(self.0.get() + 1);
-            }
-        }
-
-        {
-            let cell = Cell::new(0);
-            let mut v: SmallVec<[DropCounter; 2]> = SmallVec::new();
-            v.push(DropCounter(&cell));
-            v.into_iter();
-            assert_eq!(cell.get(), 1);
-        }
-
-        {
-            let cell = Cell::new(0);
-            let mut v: SmallVec<[DropCounter; 2]> = SmallVec::new();
-            v.push(DropCounter(&cell));
-            v.push(DropCounter(&cell));
-            assert!(v.into_iter().next().is_some());
-            assert_eq!(cell.get(), 2);
-        }
-
-        {
-            let cell = Cell::new(0);
-            let mut v: SmallVec<[DropCounter; 2]> = SmallVec::new();
-            v.push(DropCounter(&cell));
-            v.push(DropCounter(&cell));
-            v.push(DropCounter(&cell));
-            assert!(v.into_iter().next().is_some());
-            assert_eq!(cell.get(), 3);
-        }
-        {
-            let cell = Cell::new(0);
-            let mut v: SmallVec<[DropCounter; 2]> = SmallVec::new();
-            v.push(DropCounter(&cell));
-            v.push(DropCounter(&cell));
-            v.push(DropCounter(&cell));
-            {
-                let mut it = v.into_iter();
-                assert!(it.next().is_some());
-                assert!(it.next_back().is_some());
-            }
-            assert_eq!(cell.get(), 3);
-        }
-    }
-
-    #[test]
-    fn test_capacity() {
-        let mut v: SmallVec<[u8; 2]> = SmallVec::new();
-        v.reserve(1);
-        assert_eq!(v.capacity(), 2);
-        assert!(!v.spilled());
-
-        v.reserve_exact(0x100);
-        assert!(v.capacity() >= 0x100);
-
-        v.push(0);
-        v.push(1);
-        v.push(2);
-        v.push(3);
-
-        v.shrink_to_fit();
-        assert!(v.capacity() < 0x100);
-    }
-
-    #[test]
-    fn test_truncate() {
-        let mut v: SmallVec<[Box<u8>; 8]> = SmallVec::new();
-
-        for x in 0..8 {
-            v.push(Box::new(x));
-        }
-        v.truncate(4);
-
-        assert_eq!(v.len(), 4);
-        assert!(!v.spilled());
-
-        assert_eq!(*v.swap_remove(1), 1);
-        assert_eq!(*v.remove(1), 3);
-        v.insert(1, Box::new(3));
-
-        assert_eq!(&v.iter().map(|v| **v).collect::<Vec<_>>(), &[0, 3, 2]);
-    }
-
-    #[test]
-    fn test_insert_many() {
-        let mut v: SmallVec<[u8; 8]> = SmallVec::new();
-        for x in 0..4 {
-            v.push(x);
-        }
-        assert_eq!(v.len(), 4);
-        v.insert_many(1, [5, 6].iter().cloned());
-        assert_eq!(&v.iter().map(|v| *v).collect::<Vec<_>>(), &[0, 5, 6, 1, 2, 3]);
-    }
-
-    struct MockHintIter<T: Iterator>{x: T, hint: usize}
-    impl<T: Iterator> Iterator for MockHintIter<T> {
-        type Item = T::Item;
-        fn next(&mut self) -> Option<Self::Item> {self.x.next()}
-        fn size_hint(&self) -> (usize, Option<usize>) {(self.hint, None)}
-    }
-
-    #[test]
-    fn test_insert_many_short_hint() {
-        let mut v: SmallVec<[u8; 8]> = SmallVec::new();
-        for x in 0..4 {
-            v.push(x);
-        }
-        assert_eq!(v.len(), 4);
-        v.insert_many(1, MockHintIter{x: [5, 6].iter().cloned(), hint: 5});
-        assert_eq!(&v.iter().map(|v| *v).collect::<Vec<_>>(), &[0, 5, 6, 1, 2, 3]);
-    }
-
-    #[test]
-    fn test_insert_many_long_hint() {
-        let mut v: SmallVec<[u8; 8]> = SmallVec::new();
-        for x in 0..4 {
-            v.push(x);
-        }
-        assert_eq!(v.len(), 4);
-        v.insert_many(1, MockHintIter{x: [5, 6].iter().cloned(), hint: 1});
-        assert_eq!(&v.iter().map(|v| *v).collect::<Vec<_>>(), &[0, 5, 6, 1, 2, 3]);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_invalid_grow() {
-        let mut v: SmallVec<[u8; 8]> = SmallVec::new();
-        v.extend(0..8);
-        v.grow(5);
-    }
-
-    #[test]
-    fn test_insert_from_slice() {
-        let mut v: SmallVec<[u8; 8]> = SmallVec::new();
-        for x in 0..4 {
-            v.push(x);
-        }
-        assert_eq!(v.len(), 4);
-        v.insert_from_slice(1, &[5, 6]);
-        assert_eq!(&v.iter().map(|v| *v).collect::<Vec<_>>(), &[0, 5, 6, 1, 2, 3]);
-    }
-
-    #[test]
-    fn test_extend_from_slice() {
-        let mut v: SmallVec<[u8; 8]> = SmallVec::new();
-        for x in 0..4 {
-            v.push(x);
-        }
-        assert_eq!(v.len(), 4);
-        v.extend_from_slice(&[5, 6]);
-        assert_eq!(&v.iter().map(|v| *v).collect::<Vec<_>>(), &[0, 1, 2, 3, 5, 6]);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_drop_panic_smallvec() {
-        // This test should only panic once, and not double panic,
-        // which would mean a double drop
-        struct DropPanic;
-
-        impl Drop for DropPanic {
-            fn drop(&mut self) {
-                panic!("drop");
-            }
-        }
-
-        let mut v = SmallVec::<[_; 1]>::new();
-        v.push(DropPanic);
-    }
-
-    #[test]
-    fn test_eq() {
-        let mut a: SmallVec<[u32; 2]> = SmallVec::new();
-        let mut b: SmallVec<[u32; 2]> = SmallVec::new();
-        let mut c: SmallVec<[u32; 2]> = SmallVec::new();
-        // a = [1, 2]
-        a.push(1);
-        a.push(2);
-        // b = [1, 2]
-        b.push(1);
-        b.push(2);
-        // c = [3, 4]
-        c.push(3);
-        c.push(4);
-
-        assert!(a == b);
-        assert!(a != c);
-    }
-
-    #[test]
-    fn test_ord() {
-        let mut a: SmallVec<[u32; 2]> = SmallVec::new();
-        let mut b: SmallVec<[u32; 2]> = SmallVec::new();
-        let mut c: SmallVec<[u32; 2]> = SmallVec::new();
-        // a = [1]
-        a.push(1);
-        // b = [1, 1]
-        b.push(1);
-        b.push(1);
-        // c = [1, 2]
-        c.push(1);
-        c.push(2);
-
-        assert!(a < b);
-        assert!(b > a);
-        assert!(b < c);
-        assert!(c > b);
-    }
-
-    #[cfg(feature = "std")]
-    #[test]
-    fn test_hash() {
-        use std::hash::Hash;
-        use std::collections::hash_map::DefaultHasher;
-
-        {
-            let mut a: SmallVec<[u32; 2]> = SmallVec::new();
-            let b = [1, 2];
-            a.extend(b.iter().cloned());
-            let mut hasher = DefaultHasher::new();
-            assert_eq!(a.hash(&mut hasher), b.hash(&mut hasher));
-        }
-        {
-            let mut a: SmallVec<[u32; 2]> = SmallVec::new();
-            let b = [1, 2, 11, 12];
-            a.extend(b.iter().cloned());
-            let mut hasher = DefaultHasher::new();
-            assert_eq!(a.hash(&mut hasher), b.hash(&mut hasher));
-        }
-    }
-
-    #[test]
-    fn test_as_ref() {
-        let mut a: SmallVec<[u32; 2]> = SmallVec::new();
-        a.push(1);
-        assert_eq!(a.as_ref(), [1]);
-        a.push(2);
-        assert_eq!(a.as_ref(), [1, 2]);
-        a.push(3);
-        assert_eq!(a.as_ref(), [1, 2, 3]);
-    }
-
-    #[test]
-    fn test_as_mut() {
-        let mut a: SmallVec<[u32; 2]> = SmallVec::new();
-        a.push(1);
-        assert_eq!(a.as_mut(), [1]);
-        a.push(2);
-        assert_eq!(a.as_mut(), [1, 2]);
-        a.push(3);
-        assert_eq!(a.as_mut(), [1, 2, 3]);
-        a.as_mut()[1] = 4;
-        assert_eq!(a.as_mut(), [1, 4, 3]);
-    }
-
-    #[test]
-    fn test_borrow() {
-        use std::borrow::Borrow;
-
-        let mut a: SmallVec<[u32; 2]> = SmallVec::new();
-        a.push(1);
-        assert_eq!(a.borrow(), [1]);
-        a.push(2);
-        assert_eq!(a.borrow(), [1, 2]);
-        a.push(3);
-        assert_eq!(a.borrow(), [1, 2, 3]);
-    }
-
-    #[test]
-    fn test_borrow_mut() {
-        use std::borrow::BorrowMut;
-
-        let mut a: SmallVec<[u32; 2]> = SmallVec::new();
-        a.push(1);
-        assert_eq!(a.borrow_mut(), [1]);
-        a.push(2);
-        assert_eq!(a.borrow_mut(), [1, 2]);
-        a.push(3);
-        assert_eq!(a.borrow_mut(), [1, 2, 3]);
-        BorrowMut::<[u32]>::borrow_mut(&mut a)[1] = 4;
-        assert_eq!(a.borrow_mut(), [1, 4, 3]);
-    }
-
-    #[test]
-    fn test_from() {
-        assert_eq!(&SmallVec::<[u32; 2]>::from(&[1][..])[..], [1]);
-        assert_eq!(&SmallVec::<[u32; 2]>::from(&[1, 2, 3][..])[..], [1, 2, 3]);
-
-        let vec = vec![];
-        let small_vec: SmallVec<[u8; 3]> = SmallVec::from(vec);
-        assert_eq!(&*small_vec, &[]);
-        drop(small_vec);
-
-        let vec = vec![1, 2, 3, 4, 5];
-        let small_vec: SmallVec<[u8; 3]> = SmallVec::from(vec);
-        assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
-        drop(small_vec);
-
-        let vec = vec![1, 2, 3, 4, 5];
-        let small_vec: SmallVec<[u8; 1]> = SmallVec::from(vec);
-        assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
-        drop(small_vec);
-
-        let array = [1];
-        let small_vec: SmallVec<[u8; 1]> = SmallVec::from(array);
-        assert_eq!(&*small_vec, &[1]);
-        drop(small_vec);
-
-        let array = [99; 128];
-        let small_vec: SmallVec<[u8; 128]> = SmallVec::from(array);
-        assert_eq!(&*small_vec, vec![99u8; 128].as_slice());
-        drop(small_vec);
-    }
-
-    #[test]
-    fn test_from_slice() {
-        assert_eq!(&SmallVec::<[u32; 2]>::from_slice(&[1][..])[..], [1]);
-        assert_eq!(&SmallVec::<[u32; 2]>::from_slice(&[1, 2, 3][..])[..], [1, 2, 3]);
-    }
-
-    #[test]
-    fn test_exact_size_iterator() {
-        let mut vec = SmallVec::<[u32; 2]>::from(&[1, 2, 3][..]);
-        assert_eq!(vec.clone().into_iter().len(), 3);
-        assert_eq!(vec.drain().len(), 3);
-    }
-
-    #[test]
-    fn veclike_deref_slice() {
-        use super::VecLike;
-
-        fn test<T: VecLike<i32>>(vec: &mut T) {
-            assert!(!vec.is_empty());
-            assert_eq!(vec.len(), 3);
-
-            vec.sort();
-            assert_eq!(&vec[..], [1, 2, 3]);
-        }
-
-        let mut vec = SmallVec::<[i32; 2]>::from(&[3, 1, 2][..]);
-        test(&mut vec);
-    }
-
-    #[test]
-    fn shrink_to_fit_unspill() {
-        let mut vec = SmallVec::<[u8; 2]>::from_iter(0..3);
-        vec.pop();
-        assert!(vec.spilled());
-        vec.shrink_to_fit();
-        assert!(!vec.spilled(), "shrink_to_fit will un-spill if possible");
-    }
-
-    #[test]
-    fn test_into_vec() {
-        let vec = SmallVec::<[u8; 2]>::from_iter(0..2);
-        assert_eq!(vec.into_vec(), vec![0, 1]);
-
-        let vec = SmallVec::<[u8; 2]>::from_iter(0..3);
-        assert_eq!(vec.into_vec(), vec![0, 1, 2]);
-    }
-
-    #[test]
-    fn test_from_vec() {
-        let vec = vec![];
-        let small_vec: SmallVec<[u8; 3]> = SmallVec::from_vec(vec);
-        assert_eq!(&*small_vec, &[]);
-        drop(small_vec);
-
-        let vec = vec![];
-        let small_vec: SmallVec<[u8; 1]> = SmallVec::from_vec(vec);
-        assert_eq!(&*small_vec, &[]);
-        drop(small_vec);
-
-        let vec = vec![1];
-        let small_vec: SmallVec<[u8; 3]> = SmallVec::from_vec(vec);
-        assert_eq!(&*small_vec, &[1]);
-        drop(small_vec);
-
-        let vec = vec![1, 2, 3];
-        let small_vec: SmallVec<[u8; 3]> = SmallVec::from_vec(vec);
-        assert_eq!(&*small_vec, &[1, 2, 3]);
-        drop(small_vec);
-
-        let vec = vec![1, 2, 3, 4, 5];
-        let small_vec: SmallVec<[u8; 3]> = SmallVec::from_vec(vec);
-        assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
-        drop(small_vec);
-
-        let vec = vec![1, 2, 3, 4, 5];
-        let small_vec: SmallVec<[u8; 1]> = SmallVec::from_vec(vec);
-        assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
-        drop(small_vec);
-    }
-
-    #[test]
-    fn test_retain() {
-        // Test inline data storate
-        let mut sv: SmallVec<[i32; 5]> = SmallVec::from_slice(&[1, 2, 3, 3, 4]);
-        sv.retain(|&i| i != 3);
-        assert_eq!(sv.pop(), Some(4));
-        assert_eq!(sv.pop(), Some(2));
-        assert_eq!(sv.pop(), Some(1));
-        assert_eq!(sv.pop(), None);
-
-        // Test spilled data storage
-        let mut sv: SmallVec<[i32; 3]> = SmallVec::from_slice(&[1, 2, 3, 3, 4]);
-        sv.retain(|&i| i != 3);
-        assert_eq!(sv.pop(), Some(4));
-        assert_eq!(sv.pop(), Some(2));
-        assert_eq!(sv.pop(), Some(1));
-        assert_eq!(sv.pop(), None);
-
-        // Test that drop implementations are called for inline.
-        let one = Rc::new(1);
-        let mut sv: SmallVec<[Rc<i32>; 3]> = SmallVec::new();
-        sv.push(Rc::clone(&one));
-        assert_eq!(Rc::strong_count(&one), 2);
-        sv.retain(|_| false);
-        assert_eq!(Rc::strong_count(&one), 1);
-
-        // Test that drop implementations are called for spilled data.
-        let mut sv: SmallVec<[Rc<i32>; 1]> = SmallVec::new();
-        sv.push(Rc::clone(&one));
-        sv.push(Rc::new(2));
-        assert_eq!(Rc::strong_count(&one), 2);
-        sv.retain(|_| false);
-        assert_eq!(Rc::strong_count(&one), 1);
-    }
-
-    #[cfg(feature = "std")]
-    #[test]
-    fn test_write() {
-        use io::Write;
-
-        let data = [1, 2, 3, 4, 5];
-
-        let mut small_vec: SmallVec<[u8; 2]> = SmallVec::new();
-        let len = small_vec.write(&data[..]).unwrap();
-        assert_eq!(len, 5);
-        assert_eq!(small_vec.as_ref(), data.as_ref());
-
-        let mut small_vec: SmallVec<[u8; 2]> = SmallVec::new();
-        small_vec.write_all(&data[..]).unwrap();
-        assert_eq!(small_vec.as_ref(), data.as_ref());
-    }
-
-    #[cfg(feature = "serde")]
-    extern crate bincode;
-
-    #[cfg(feature = "serde")]
-    #[test]
-    fn test_serde() {
-        use self::bincode::{serialize, deserialize, Bounded};
-        let mut small_vec: SmallVec<[i32; 2]> = SmallVec::new();
-        small_vec.push(1);
-        let encoded = serialize(&small_vec, Bounded(100)).unwrap();
-        let decoded: SmallVec<[i32; 2]> = deserialize(&encoded).unwrap();
-        assert_eq!(small_vec, decoded);
-        small_vec.push(2);
-        // Spill the vec
-        small_vec.push(3);
-        small_vec.push(4);
-        // Check again after spilling.
-        let encoded = serialize(&small_vec, Bounded(100)).unwrap();
-        let decoded: SmallVec<[i32; 2]> = deserialize(&encoded).unwrap();
-        assert_eq!(small_vec, decoded);
-    }
-}
--- a/toolkit/library/gtest/rust/Cargo.lock
+++ b/toolkit/library/gtest/rust/Cargo.lock
@@ -8,32 +8,21 @@ dependencies = [
 
 [[package]]
 name = "ansi_term"
 version = "0.10.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "app_units"
-version = "0.5.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "app_units"
 version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
 ]
 
 [[package]]
 name = "arrayvec"
 version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -62,18 +51,18 @@ dependencies = [
  "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "cubeb-core 0.1.0",
  "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "memmap 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "mio 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
+ "serde_derive 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
 ]
 
 [[package]]
 name = "audioipc-client"
 version = "0.1.0"
 dependencies = [
  "audioipc 0.1.0",
  "cubeb-backend 0.2.0",
@@ -106,26 +95,26 @@ source = "registry+https://github.com/ru
 
 [[package]]
 name = "bincode"
 version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
 ]
 
 [[package]]
 name = "bincode"
 version = "0.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
 ]
 
 [[package]]
 name = "bindgen"
 version = "0.31.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -399,18 +388,18 @@ dependencies = [
 name = "dwrote"
 version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
+ "serde_derive 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "either"
 version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
@@ -451,33 +440,22 @@ dependencies = [
 
 [[package]]
 name = "error-chain"
 version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "euclid"
-version = "0.15.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "euclid"
 version = "0.16.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
 ]
 
 [[package]]
 name = "fallible"
 version = "0.0.1"
 dependencies = [
  "hashglobe 0.1.0",
  "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -629,24 +607,16 @@ source = "registry+https://github.com/ru
 [[package]]
 name = "hashglobe"
 version = "0.1.0"
 dependencies = [
  "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
-name = "heapsize"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
 name = "ident_case"
 version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "idna"
 version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1017,21 +987,21 @@ dependencies = [
 
 [[package]]
 name = "pkg-config"
 version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "plane-split"
-version = "0.6.0"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "precomputed-hash"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1124,21 +1094,16 @@ version = "0.0.1"
 dependencies = [
  "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "nserror 0.1.0",
  "nsstring 0.1.0",
  "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
-name = "rustc-serialize"
-version = "0.3.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
 name = "same-file"
 version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1175,36 +1140,36 @@ dependencies = [
 
 [[package]]
 name = "semver-parser"
 version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "serde"
-version = "1.0.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
+version = "1.0.23"
+source = "git+https://github.com/gankro/serde?branch=deserialize_from_enums3#fc6117367ef974fb2d3b2017c21c375d34823415"
 dependencies = [
- "serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
+version = "1.0.23"
+source = "git+https://github.com/gankro/serde?branch=deserialize_from_enums3#fc6117367ef974fb2d3b2017c21c375d34823415"
 dependencies = [
  "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive_internals 0.17.0 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
  "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "serde_derive_internals"
-version = "0.15.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
+version = "0.17.0"
+source = "git+https://github.com/gankro/serde?branch=deserialize_from_enums3#fc6117367ef974fb2d3b2017c21c375d34823415"
 dependencies = [
  "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "synom 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "servo_arc"
 version = "0.0.1"
@@ -1230,21 +1195,16 @@ source = "registry+https://github.com/ru
 
 [[package]]
 name = "smallbitvec"
 version = "1.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "smallvec"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "smallvec"
 version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "stable_deref_trait"
 version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
@@ -1491,72 +1451,73 @@ source = "registry+https://github.com/ru
 dependencies = [
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "webrender"
-version = "0.55.0"
+version = "0.56.1"
 dependencies = [
- "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bincode 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-text 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "dwrote 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "freetype 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "gleam 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "plane-split 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "plane-split 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "smallvec 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender_api 0.55.0",
+ "webrender_api 0.56.1",
 ]
 
 [[package]]
 name = "webrender_api"
-version = "0.55.0"
+version = "0.56.1"
 dependencies = [
- "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bincode 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "dwrote 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
+ "serde_derive 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
  "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "webrender_bindings"
 version = "0.1.0"
 dependencies = [
- "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "dwrote 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "gleam 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender 0.55.0",
+ "webrender 0.56.1",
 ]
 
 [[package]]
 name = "which"
 version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1587,17 +1548,16 @@ version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [metadata]
 "checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699"
 "checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455"
-"checksum app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ed0a4de09a3b8449515e649f3bb84f72ea15fc2d10639beb0776a09b7d308074"
 "checksum app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29069a9b483f7780aebb55dafb360c6225eefdc1f98c8d336a65148fd10c37b1"
 "checksum arrayvec 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2f0ef4a9820019a0c91d918918c93dc71d469f581a49b47ddc1d285d4270bbe2"
 "checksum atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb2dcb6e6d35f20276943cc04bb98e538b348d525a04ac79c10021561d202f21"
 "checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"
 "checksum binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88ceb0d16c4fd0e42876e298d7d3ce3780dd9ebdcbe4199816a32c77e08597ff"
 "checksum bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e103c8b299b28a9c6990458b7013dc4a8356a9b854c51b9883241f5866fac36e"
 "checksum bincode 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9d3fb369af639822830328794eba2501b3479652fcd021b2aeb1ed4984202afd"
 "checksum bindgen 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)" = "57253399c086f4f29e57ffd3b5cdbc23a806a00292619351aa4cfa39cb49d4ea"
@@ -1628,31 +1588,29 @@ dependencies = [
 "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
 "checksum dtoa-short 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "068d4026697c1a18f0b0bb8cfcad1b0c151b90d8edb9bf4c235ad68128920d1d"
 "checksum dwrote 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a207eb7b40e25d1d28dc679f451d321fb6954b73ceaa47986702575865469461"
 "checksum either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18785c1ba806c258137c937e44ada9ee7e69a37e3c72077542cd2f069d78562a"
 "checksum encoding_c 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "93ec52324ca72f423237a413ca0e1c60654c8b3d0934fcd5fd888508dfcc4ba7"
 "checksum encoding_rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f5215aabf22b83153be3ee44dfe3f940214541b2ce13d419c55e7a115c8c51a9"
 "checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b"
 "checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8"
-"checksum euclid 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f5ed7d77e46f6600f490463ad7b6349c3ebb2d2319af56e679e279e4c66495d9"
 "checksum euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "926c639bfdff1f3063f76bb66245f6d2b691aa20fdbaabecc38b2947a13a4eba"
 "checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
 "checksum foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ebc04f19019fff1f2d627b5581574ead502f80c48c88900575a46e0840fe5d0"
 "checksum freetype 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "398b8a11884898184d55aca9806f002b3cf68f0e860e0cbb4586f834ee39b0e7"
 "checksum fs2 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ab76cfd2aaa59b7bf6688ad9ba15bbae64bff97f04ea02144cfd3443e5c2866"
 "checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159"
 "checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82"
 "checksum futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "55f0008e13fc853f79ea8fc86e931486860d4c4c156cdffb59fa5f7fa833660a"
 "checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
 "checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518"
 "checksum gl_generator 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "75d69f914b49d9ff32fdf394cbd798f8c716d74fd19f9cc29da3e99797b2a78d"
 "checksum gleam 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)" = "dff613336334932baaa2759d001f14e06ea1a08a247c05962d1423aa0e89ee99"
 "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
-"checksum heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4c7593b1522161003928c959c20a2ca421c68e940d63d75573316a009e48a6d4"
 "checksum ident_case 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9826188e666f2ed92071d2dadef6edc430b11b158b5b2b3f4babbcc891eaaa"
 "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
 "checksum iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29d062ee61fccdf25be172e70f34c9f6efc597e1fb8f6526e8437b2046ab26be"
 "checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc"
 "checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c"
 "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
 "checksum khronos_api 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d867c645cfeb8a7fec503731679eac03ac11b7105aa5a71cb8f8ee5271636add"
 "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
@@ -1680,40 +1638,38 @@ dependencies = [
 "checksum parking_lot_core 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6c677d78851950b3aec390e681a411f78cc250cba277d4f578758a377f727970"
 "checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
 "checksum percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de154f638187706bde41d9b4738748933d64e6b37bdbffc0b47a97d16a6ae356"
 "checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc"
 "checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f"
 "checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03"
 "checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2"
 "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
-"checksum plane-split 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e57800a97ca52c556db6b6184a3201f05366ad5e11876f7d17e234589ca2fa26"
+"checksum plane-split 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2adb8d1523b2ddcd98275613e9bc04eef75b47a39e252e63733a3218ae3c1b7"
 "checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
 "checksum procedural-masquerade 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9f566249236c6ca4340f7ca78968271f0ed2b0f234007a61b66f9ecd0af09260"
 "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
 "checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd"
 "checksum rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b614fe08b6665cb9a231d07ac1364b0ef3cb3698f1239ee0c4c3a88a524f54c8"
 "checksum rayon-core 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2c21a92a5dca958fb030787c1158446c6deb7f976399b72fa8074603f169e2a"
 "checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0"
 "checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b"
 "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db"
 "checksum runloop 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d79b4b604167921892e84afbbaad9d5ad74e091bf6c511d9dbfb0593f09fabd"
-"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
 "checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
 "checksum scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c79eb2c3ac4bc2507cda80e7f3ac5b88bd8eae4c0914d5663e6a8933994be918"
 "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
 "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
-"checksum serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f530d36fb84ec48fb7146936881f026cdbf4892028835fd9398475f82c1bb4"
-"checksum serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "10552fad5500771f3902d0c5ba187c5881942b811b7ba0d8fbbfbf84d80806d3"
-"checksum serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37aee4e0da52d801acfbc0cc219eb1eda7142112339726e427926a6f6ee65d3a"
+"checksum serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)" = "<none>"
+"checksum serde_derive 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)" = "<none>"
+"checksum serde_derive_internals 0.17.0 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)" = "<none>"
 "checksum simd 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a94d14a2ae1f1f110937de5fb69e494372560181c7e1739a097fcc2cee37ba0"
 "checksum siphasher 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ffc669b726f2bc9a3bcff66e5e23b56ba6bf70e22a34c3d7b6d0b3450b65b84"
 "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
 "checksum smallbitvec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "79b776f00dfe01df905fa3b2eaa1659522e99e3fc4a7b1334171622205c4bdcf"
-"checksum smallvec 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "872c0ff227000041c520cca51e883b858d388ab0ecf646bab76f065cebaec025"
 "checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9"
 "checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
 "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
 "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
 "checksum synom 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "27e31aa4b09b9f4cb12dff3c30ba503e17b1a624413d764d32dab76e3920e5bc"
 "checksum synstructure 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cf318c34a2f8381a4f3d4db2c91b45bca2b1cd8cbe56caced900647be164800c"
 "checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
 "checksum thread-id 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8df7875b676fddfadffd96deea3b1124e5ede707d4884248931077518cf1f773"
--- a/toolkit/library/rust/Cargo.lock
+++ b/toolkit/library/rust/Cargo.lock
@@ -8,32 +8,21 @@ dependencies = [
 
 [[package]]
 name = "ansi_term"
 version = "0.10.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "app_units"
-version = "0.5.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "app_units"
 version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
 ]
 
 [[package]]
 name = "arrayvec"
 version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -62,18 +51,18 @@ dependencies = [
  "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "cubeb-core 0.1.0",
  "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "memmap 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "mio 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
+ "serde_derive 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
 ]
 
 [[package]]
 name = "audioipc-client"
 version = "0.1.0"
 dependencies = [
  "audioipc 0.1.0",
  "cubeb-backend 0.2.0",
@@ -106,26 +95,26 @@ source = "registry+https://github.com/ru
 
 [[package]]
 name = "bincode"
 version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
 ]
 
 [[package]]
 name = "bincode"
 version = "0.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
 ]
 
 [[package]]
 name = "bindgen"
 version = "0.31.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -399,18 +388,18 @@ dependencies = [
 name = "dwrote"
 version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
+ "serde_derive 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "either"
 version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
@@ -451,33 +440,22 @@ dependencies = [
 
 [[package]]
 name = "error-chain"
 version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "euclid"
-version = "0.15.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "euclid"
 version = "0.16.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
 ]
 
 [[package]]
 name = "fallible"
 version = "0.0.1"
 dependencies = [
  "hashglobe 0.1.0",
  "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -628,24 +606,16 @@ source = "registry+https://github.com/ru
 [[package]]
 name = "hashglobe"
 version = "0.1.0"
 dependencies = [
  "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
-name = "heapsize"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
 name = "ident_case"
 version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "idna"
 version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1005,21 +975,21 @@ dependencies = [
 
 [[package]]
 name = "pkg-config"
 version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "plane-split"
-version = "0.6.0"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "precomputed-hash"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1112,21 +1082,16 @@ version = "0.0.1"
 dependencies = [
  "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "nserror 0.1.0",
  "nsstring 0.1.0",
  "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
-name = "rustc-serialize"
-version = "0.3.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
 name = "same-file"
 version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1163,36 +1128,36 @@ dependencies = [
 
 [[package]]
 name = "semver-parser"
 version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "serde"
-version = "1.0.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
+version = "1.0.23"
+source = "git+https://github.com/gankro/serde?branch=deserialize_from_enums3#fc6117367ef974fb2d3b2017c21c375d34823415"
 dependencies = [
- "serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
+version = "1.0.23"
+source = "git+https://github.com/gankro/serde?branch=deserialize_from_enums3#fc6117367ef974fb2d3b2017c21c375d34823415"
 dependencies = [
  "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive_internals 0.17.0 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
  "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "serde_derive_internals"
-version = "0.15.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
+version = "0.17.0"
+source = "git+https://github.com/gankro/serde?branch=deserialize_from_enums3#fc6117367ef974fb2d3b2017c21c375d34823415"
 dependencies = [
  "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "synom 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "servo_arc"
 version = "0.0.1"
@@ -1222,21 +1187,16 @@ source = "registry+https://github.com/ru
 
 [[package]]
 name = "smallbitvec"
 version = "1.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "smallvec"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "smallvec"
 version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "stable_deref_trait"
 version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
@@ -1503,72 +1463,73 @@ source = "registry+https://github.com/ru
 dependencies = [
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "webrender"
-version = "0.55.0"
+version = "0.56.1"
 dependencies = [
- "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bincode 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-text 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "dwrote 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "freetype 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "gleam 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "plane-split 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "plane-split 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "smallvec 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender_api 0.55.0",
+ "webrender_api 0.56.1",
 ]
 
 [[package]]
 name = "webrender_api"
-version = "0.55.0"
+version = "0.56.1"
 dependencies = [
- "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bincode 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "dwrote 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
+ "serde_derive 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
  "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "webrender_bindings"
 version = "0.1.0"
 dependencies = [
- "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "dwrote 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "gleam 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender 0.55.0",
+ "webrender 0.56.1",
 ]
 
 [[package]]
 name = "which"
 version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1599,17 +1560,16 @@ version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [metadata]
 "checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699"
 "checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455"
-"checksum app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ed0a4de09a3b8449515e649f3bb84f72ea15fc2d10639beb0776a09b7d308074"
 "checksum app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29069a9b483f7780aebb55dafb360c6225eefdc1f98c8d336a65148fd10c37b1"
 "checksum arrayvec 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2f0ef4a9820019a0c91d918918c93dc71d469f581a49b47ddc1d285d4270bbe2"
 "checksum atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb2dcb6e6d35f20276943cc04bb98e538b348d525a04ac79c10021561d202f21"
 "checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"
 "checksum binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88ceb0d16c4fd0e42876e298d7d3ce3780dd9ebdcbe4199816a32c77e08597ff"
 "checksum bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e103c8b299b28a9c6990458b7013dc4a8356a9b854c51b9883241f5866fac36e"
 "checksum bincode 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9d3fb369af639822830328794eba2501b3479652fcd021b2aeb1ed4984202afd"
 "checksum bindgen 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)" = "57253399c086f4f29e57ffd3b5cdbc23a806a00292619351aa4cfa39cb49d4ea"
@@ -1640,31 +1600,29 @@ dependencies = [
 "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
 "checksum dtoa-short 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "068d4026697c1a18f0b0bb8cfcad1b0c151b90d8edb9bf4c235ad68128920d1d"
 "checksum dwrote 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a207eb7b40e25d1d28dc679f451d321fb6954b73ceaa47986702575865469461"
 "checksum either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18785c1ba806c258137c937e44ada9ee7e69a37e3c72077542cd2f069d78562a"
 "checksum encoding_c 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "93ec52324ca72f423237a413ca0e1c60654c8b3d0934fcd5fd888508dfcc4ba7"
 "checksum encoding_rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f5215aabf22b83153be3ee44dfe3f940214541b2ce13d419c55e7a115c8c51a9"
 "checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b"
 "checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8"
-"checksum euclid 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f5ed7d77e46f6600f490463ad7b6349c3ebb2d2319af56e679e279e4c66495d9"
 "checksum euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "926c639bfdff1f3063f76bb66245f6d2b691aa20fdbaabecc38b2947a13a4eba"
 "checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
 "checksum foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ebc04f19019fff1f2d627b5581574ead502f80c48c88900575a46e0840fe5d0"
 "checksum freetype 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "398b8a11884898184d55aca9806f002b3cf68f0e860e0cbb4586f834ee39b0e7"
 "checksum fs2 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ab76cfd2aaa59b7bf6688ad9ba15bbae64bff97f04ea02144cfd3443e5c2866"
 "checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159"
 "checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82"
 "checksum futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "55f0008e13fc853f79ea8fc86e931486860d4c4c156cdffb59fa5f7fa833660a"
 "checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
 "checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518"
 "checksum gl_generator 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "75d69f914b49d9ff32fdf394cbd798f8c716d74fd19f9cc29da3e99797b2a78d"
 "checksum gleam 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)" = "dff613336334932baaa2759d001f14e06ea1a08a247c05962d1423aa0e89ee99"
 "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
-"checksum heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4c7593b1522161003928c959c20a2ca421c68e940d63d75573316a009e48a6d4"
 "checksum ident_case 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9826188e666f2ed92071d2dadef6edc430b11b158b5b2b3f4babbcc891eaaa"
 "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
 "checksum iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29d062ee61fccdf25be172e70f34c9f6efc597e1fb8f6526e8437b2046ab26be"
 "checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc"
 "checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c"
 "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
 "checksum khronos_api 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d867c645cfeb8a7fec503731679eac03ac11b7105aa5a71cb8f8ee5271636add"
 "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
@@ -1692,40 +1650,38 @@ dependencies = [
 "checksum parking_lot_core 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6c677d78851950b3aec390e681a411f78cc250cba277d4f578758a377f727970"
 "checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
 "checksum percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de154f638187706bde41d9b4738748933d64e6b37bdbffc0b47a97d16a6ae356"
 "checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc"
 "checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f"
 "checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03"
 "checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2"
 "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
-"checksum plane-split 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e57800a97ca52c556db6b6184a3201f05366ad5e11876f7d17e234589ca2fa26"
+"checksum plane-split 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2adb8d1523b2ddcd98275613e9bc04eef75b47a39e252e63733a3218ae3c1b7"
 "checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
 "checksum procedural-masquerade 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9f566249236c6ca4340f7ca78968271f0ed2b0f234007a61b66f9ecd0af09260"
 "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
 "checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd"
 "checksum rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b614fe08b6665cb9a231d07ac1364b0ef3cb3698f1239ee0c4c3a88a524f54c8"
 "checksum rayon-core 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2c21a92a5dca958fb030787c1158446c6deb7f976399b72fa8074603f169e2a"
 "checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0"
 "checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b"
 "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db"
 "checksum runloop 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d79b4b604167921892e84afbbaad9d5ad74e091bf6c511d9dbfb0593f09fabd"
-"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
 "checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
 "checksum scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c79eb2c3ac4bc2507cda80e7f3ac5b88bd8eae4c0914d5663e6a8933994be918"
 "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
 "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
-"checksum serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f530d36fb84ec48fb7146936881f026cdbf4892028835fd9398475f82c1bb4"
-"checksum serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "10552fad5500771f3902d0c5ba187c5881942b811b7ba0d8fbbfbf84d80806d3"
-"checksum serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37aee4e0da52d801acfbc0cc219eb1eda7142112339726e427926a6f6ee65d3a"
+"checksum serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)" = "<none>"
+"checksum serde_derive 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)" = "<none>"
+"checksum serde_derive_internals 0.17.0 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)" = "<none>"
 "checksum simd 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a94d14a2ae1f1f110937de5fb69e494372560181c7e1739a097fcc2cee37ba0"
 "checksum siphasher 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ffc669b726f2bc9a3bcff66e5e23b56ba6bf70e22a34c3d7b6d0b3450b65b84"
 "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
 "checksum smallbitvec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "79b776f00dfe01df905fa3b2eaa1659522e99e3fc4a7b1334171622205c4bdcf"
-"checksum smallvec 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "872c0ff227000041c520cca51e883b858d388ab0ecf646bab76f065cebaec025"
 "checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9"
 "checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
 "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
 "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
 "checksum synom 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "27e31aa4b09b9f4cb12dff3c30ba503e17b1a624413d764d32dab76e3920e5bc"
 "checksum synstructure 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cf318c34a2f8381a4f3d4db2c91b45bca2b1cd8cbe56caced900647be164800c"
 "checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
 "checksum thread-id 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8df7875b676fddfadffd96deea3b1124e5ede707d4884248931077518cf1f773"