Bug 1508231 - Re-vendor rust dependencies. r=kats
authorWR Updater Bot <graphics-team@mozilla.staktrace.com>
Mon, 19 Nov 2018 18:25:34 +0000
changeset 503458 fa092e8167f2d92cf14735fe965a8c2c3b93151a
parent 503457 7614f586cc31d36590f4c539209e7168ba7c169a
child 503459 f5d0cd55a71393bd9fe0bf3673f500aa3a9c3ddb
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs1508231
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1508231 - Re-vendor rust dependencies. r=kats Depends on D12329 Differential Revision: https://phabricator.services.mozilla.com/D12330
Cargo.lock
third_party/rust/euclid/.cargo-checksum.json
third_party/rust/euclid/Cargo.toml
third_party/rust/euclid/src/lib.rs
third_party/rust/euclid/src/macros.rs
third_party/rust/euclid/src/point.rs
third_party/rust/euclid/src/size.rs
third_party/rust/euclid/src/transform2d.rs
third_party/rust/euclid/src/transform3d.rs
third_party/rust/euclid/src/translation.rs
third_party/rust/euclid/src/vector.rs
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -834,17 +834,17 @@ dependencies = [
 
 [[package]]
 name = "error-chain"
 version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "euclid"
-version = "0.19.0"
+version = "0.19.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "failure"
@@ -1413,17 +1413,17 @@ dependencies = [
 ]
 
 [[package]]
 name = "malloc_size_of"
 version = "0.0.1"
 dependencies = [
  "app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cssparser 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.19.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "hashglobe 0.1.0",
  "selectors 0.20.0",
  "servo_arc 0.1.1",
  "smallbitvec 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "thin-slice 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1869,17 +1869,17 @@ version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "plane-split"
 version = "0.13.3"
 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.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.19.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "podio"
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2363,17 +2363,17 @@ dependencies = [
  "app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "arrayvec 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bindgen 0.43.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "cssparser 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.19.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "fallible 0.0.1",
  "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "hashglobe 0.1.0",
  "itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "malloc_size_of 0.0.1",
@@ -2419,17 +2419,17 @@ dependencies = [
 
 [[package]]
 name = "style_traits"
 version = "0.0.1"
 dependencies = [
  "app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "cssparser 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.19.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "malloc_size_of 0.0.1",
  "malloc_size_of_derive 0.0.1",
  "selectors 0.20.0",
  "servo_arc 0.1.1",
 ]
 
 [[package]]
 name = "stylo_tests"
@@ -2941,17 +2941,16 @@ dependencies = [
  "bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-text 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "dwrote 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "freetype 0.4.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.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "plane-split 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2969,33 +2968,33 @@ version = "0.57.2"
 dependencies = [
  "app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "dwrote 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.19.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)",
  "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "webrender_bindings"
 version = "0.1.0"
 dependencies = [
  "app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "dwrote 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.19.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "foreign-types 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.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "nsstring 0.1.0",
  "rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3200,17 +3199,17 @@ dependencies = [
 "checksum dtoa-short 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "068d4026697c1a18f0b0bb8cfcad1b0c151b90d8edb9bf4c235ad68128920d1d"
 "checksum dwrote 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "18e895b763d82cafef31c7c1e2f4f17fb70f385ac651b0918a46ff5790664a63"
 "checksum either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18785c1ba806c258137c937e44ada9ee7e69a37e3c72077542cd2f069d78562a"
 "checksum ena 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "88dc8393b3c7352f94092497f6b52019643e493b6b890eb417cdb7c46117e621"
 "checksum encoding_c 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "769ecb8b33323998e482b218c0d13cd64c267609023b4b7ec3ee740714c318ee"
 "checksum encoding_rs 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f1a79fa56c329a5b087de13748054fb3b974c4a672c12c71f0b66e35c5addec5"
 "checksum env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0561146661ae44c579e993456bc76d11ce1e0c7d745e57b2fa7146b6e49fa2ad"
 "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
-"checksum euclid 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "70a2ebdf55fb9d6329046e026329a55ef8fbaae5ea833f56e170beb3125a8a5f"
+"checksum euclid 0.19.3 (registry+https://github.com/rust-lang/crates.io-index)" = "600657e7e5c03bfbccdc68721bc3b5abcb761553973387124eae9c9e4f02c210"
 "checksum failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6dd377bcc1b1b7ce911967e3ec24fa19c3224394ec05b54aa7b083d498341ac7"
 "checksum failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "64c2d913fe8ed3b6c6518eedf4538255b989945c14c2a7d5cbff62a5e2120596"
 "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
 "checksum fixedbitset 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "85cb8fec437468d86dc7c83ca7cfc933341d561873275f22dd5eedefa63a6478"
 "checksum flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fac2277e84e5e858483756647a9d0aa8d9a2b7cba517fd84325a0aaa69a0909"
 "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.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b659e75b7a7338fe75afd7f909fc2b71937845cffb6ebe54ba2e50f13d8e903d"
--- a/third_party/rust/euclid/.cargo-checksum.json
+++ b/third_party/rust/euclid/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"COPYRIGHT":"ec82b96487e9e778ee610c7ab245162464782cfa1f555c2299333f8dbe5c036a","Cargo.toml":"99a87c4c1a5ca910ddfd7d0d5a4bcd78aceb9d7f3604952bb5310fde801b1a72","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"62065228e42caebca7e7d7db1204cbb867033de5982ca4009928915e4095f3a3","README.md":"625bec69c76ce5423fdd05cfe46922b2680ec517f97c5854ce34798d1d8a9541","src/approxeq.rs":"6594377e8f6c20f88f628520d8de9b9a59c5892a0ee9a6ccd13c8400c1499911","src/homogen.rs":"cb26346ad1ea2797bdc1cac7f532872becabf28a1f9c60792f86ad4a655582f9","src/length.rs":"3171315822707728b1bfbdd04a4190ffb7206b4bfc59e9dd072bb2caa05ff292","src/lib.rs":"b3c2303ab06ce972784c2ec4faa09ecdaa8e0706316f427c8a2009445a52f6e9","src/macros.rs":"877b4bd62b63ea120e568803281e7169f33fb811fe1c1515e56bfc44a74c34a2","src/num.rs":"4439479fad5729073e0bfe0b96b547672a237430d48e564519759b9550baa033","src/point.rs":"d18046853e19012e649a01991d45fdb1ba8f51eb55e52273e68f567cd7df932a","src/rect.rs":"dc7131fe3884803d549fb66dec589ad671790451dbb3770d360509fbfabcf6ec","src/rotation.rs":"982aaca640215bacc5d2dc60a8949bb2510d5b6d492975b8b6946a7c8f69b496","src/scale.rs":"fc07bcf47f3a1215023c830059f0d270e570cbd37fe8c367ef4a47b191f4ae3e","src/side_offsets.rs":"f114cb881256bbeff2ee2aa305d363e2dea65aa8535140f104f6fa9364bd02f5","src/size.rs":"f6a4f12fc50cc54220af089339cb7fde37f22c6dfcc4c2c676d24caab07b1790","src/transform2d.rs":"137344a16162f5cd1dc4a2ae87b8ea3fdde7597874835582378945f55e45513e","src/transform3d.rs":"efd971ba35e8a9ab59b0c4062b2625532147af0e57bf96b8cd09117524cf23ed","src/trig.rs":"97a263c4f178b0332501659ca8143f9f637a0755aca189dd31ac551bcd4cb73c","src/vector.rs":"d84103384907174d2b2206acd60d6b3261edb3ac971ec5e121ae22ce6bcca5d9"},"package":"70a2ebdf55fb9d6329046e026329a55ef8fbaae5ea833f56e170beb3125a8a5f"}
\ No newline at end of file
+{"files":{"COPYRIGHT":"ec82b96487e9e778ee610c7ab245162464782cfa1f555c2299333f8dbe5c036a","Cargo.toml":"0bcb9056495f70a42ab15eb9c144416526d6566b95dc5ac8bd7ddd9cb9b71b4b","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"62065228e42caebca7e7d7db1204cbb867033de5982ca4009928915e4095f3a3","README.md":"625bec69c76ce5423fdd05cfe46922b2680ec517f97c5854ce34798d1d8a9541","src/approxeq.rs":"6594377e8f6c20f88f628520d8de9b9a59c5892a0ee9a6ccd13c8400c1499911","src/homogen.rs":"cb26346ad1ea2797bdc1cac7f532872becabf28a1f9c60792f86ad4a655582f9","src/length.rs":"3171315822707728b1bfbdd04a4190ffb7206b4bfc59e9dd072bb2caa05ff292","src/lib.rs":"f89c2b86cabae4431a956b88c630c5cbdf51f7329dfeb677ab4fd4ff02e7d53b","src/macros.rs":"d2b7b391f58fe9cedb426780cfa1d2771f9ac786a6237b0f89d3e5788f5ec1b7","src/num.rs":"4439479fad5729073e0bfe0b96b547672a237430d48e564519759b9550baa033","src/point.rs":"2c399e282c2e81528775a1fc6ee1a0f2f6f71ed4a14bbe426115ae78b4cf2149","src/rect.rs":"dc7131fe3884803d549fb66dec589ad671790451dbb3770d360509fbfabcf6ec","src/rotation.rs":"982aaca640215bacc5d2dc60a8949bb2510d5b6d492975b8b6946a7c8f69b496","src/scale.rs":"fc07bcf47f3a1215023c830059f0d270e570cbd37fe8c367ef4a47b191f4ae3e","src/side_offsets.rs":"f114cb881256bbeff2ee2aa305d363e2dea65aa8535140f104f6fa9364bd02f5","src/size.rs":"1fe99377bee13835ca416adbccdb0d163091a3dcf2977c3222da2d6b22d70621","src/transform2d.rs":"2f9bafe40b9a6dd9c41747aabfdefbfc9ee48daf4f4297d2320ccbdac185a30d","src/transform3d.rs":"6af722a693e6cd041440871be47069bad3392d670155ba05f9abbc11d9534b4c","src/translation.rs":"c835abaf167234b288e95323f9e693099be9fd992fc137cd6e692edbe4456f19","src/trig.rs":"97a263c4f178b0332501659ca8143f9f637a0755aca189dd31ac551bcd4cb73c","src/vector.rs":"b0b41eac9c823e05bf6357e69c71dac977db2d8ab27b25f80f1f44b056d15f6d"},"package":"600657e7e5c03bfbccdc68721bc3b5abcb761553973387124eae9c9e4f02c210"}
\ No newline at end of file
--- a/third_party/rust/euclid/Cargo.toml
+++ b/third_party/rust/euclid/Cargo.toml
@@ -7,24 +7,28 @@
 #
 # 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.19.0"
+version = "0.19.3"
 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.mint]
+version = "0.5.1"
+optional = true
+
 [dependencies.num-traits]
 version = "0.2"
 
 [dependencies.serde]
 version = "1.0"
 features = ["serde_derive"]
 optional = true
 [dev-dependencies.rand]
--- a/third_party/rust/euclid/src/lib.rs
+++ b/third_party/rust/euclid/src/lib.rs
@@ -55,33 +55,35 @@
 //! // Length::get returns the scalar value (f32).
 //! assert_eq!(p.x, p.x_typed().get());
 //! ```
 
 #[cfg(feature = "serde")]
 #[macro_use]
 extern crate serde;
 
+#[cfg(feature = "mint")]
+pub extern crate mint;
 extern crate num_traits;
 #[cfg(test)]
 extern crate rand;
-
 #[cfg(test)]
 use std as core;
 
 pub use length::Length;
 pub use scale::TypedScale;
 pub use transform2d::{Transform2D, TypedTransform2D};
 pub use transform3d::{Transform3D, TypedTransform3D};
 pub use point::{Point2D, Point3D, TypedPoint2D, TypedPoint3D, point2, point3};
 pub use vector::{TypedVector2D, TypedVector3D, Vector2D, Vector3D, vec2, vec3};
 pub use vector::{BoolVector2D, BoolVector3D, bvec2, bvec3};
 pub use homogen::HomogeneousVector;
 
 pub use rect::{rect, Rect, TypedRect};
+pub use translation::{TypedTranslation2D, TypedTranslation3D};
 pub use rotation::{Angle, Rotation2D, Rotation3D, TypedRotation2D, TypedRotation3D};
 pub use side_offsets::{SideOffsets2D, TypedSideOffsets2D};
 pub use size::{Size2D, TypedSize2D, size2};
 pub use trig::Trig;
 
 #[macro_use]
 mod macros;
 
@@ -92,16 +94,17 @@ mod length;
 mod point;
 mod rect;
 mod rotation;
 mod scale;
 mod side_offsets;
 mod size;
 mod transform2d;
 mod transform3d;
+mod translation;
 mod trig;
 mod vector;
 
 /// The default unit.
 #[derive(Clone, Copy)]
 pub struct UnknownUnit;
 
 /// Temporary alias to facilitate the transition to the new naming scheme
--- a/third_party/rust/euclid/src/macros.rs
+++ b/third_party/rust/euclid/src/macros.rs
@@ -79,8 +79,30 @@ macro_rules! define_matrix {
             where T: ::core::hash::Hash
         {
             fn hash<H: ::core::hash::Hasher>(&self, h: &mut H) {
                 $(self.$field.hash(h);)+
             }
         }
     )
 }
+
+macro_rules! mint_vec {
+    ($name:ident [ $($field:ident),* ] = $std_name:ident) => {
+        #[cfg(feature = "mint")]
+        impl<T, U> From<mint::$std_name<T>> for $name<T, U> {
+            fn from(v: mint::$std_name<T>) -> Self {
+                $name {
+                    $( $field: v.$field, )*
+                    _unit: PhantomData,
+                }
+            }
+        }
+        #[cfg(feature = "mint")]
+        impl<T, U> Into<mint::$std_name<T>> for $name<T, U> {
+            fn into(self) -> mint::$std_name<T> {
+                mint::$std_name {
+                    $( $field: self.$field, )*
+                }
+            }
+        }
+    }
+}
--- a/third_party/rust/euclid/src/point.rs
+++ b/third_party/rust/euclid/src/point.rs
@@ -7,30 +7,33 @@
 // 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::TypedScale;
 use size::TypedSize2D;
+#[cfg(feature = "mint")]
+use mint;
 use num::*;
 use num_traits::{Float, NumCast};
 use vector::{TypedVector2D, TypedVector3D, vec2, vec3};
 use core::fmt;
 use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
 use core::marker::PhantomData;
 
 define_matrix! {
     /// A 2d Point tagged with a unit.
     pub struct TypedPoint2D<T, U> {
         pub x: T,
         pub y: T,
     }
 }
+mint_vec!(TypedPoint2D[x, y] = Point2);
 
 /// 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.
@@ -190,16 +193,21 @@ impl<T: Float, U> TypedPoint2D<T, U> {
     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))
     }
+
+    #[inline]
+    pub fn clamp(&self, start: Self, end: Self) -> Self {
+        self.max(start).min(end)
+    }
 }
 
 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)
     }
@@ -403,16 +411,17 @@ impl<T: Copy, U> From<[T; 2]> for TypedP
 define_matrix! {
     /// A 3d Point tagged with a unit.
     pub struct TypedPoint3D<T, U> {
         pub x: T,
         pub y: T,
         pub z: T,
     }
 }
+mint_vec!(TypedPoint3D[x, y, z] = Point3);
 
 /// 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 components to zero.
@@ -612,16 +621,21 @@ impl<T: Float, U> TypedPoint3D<T, U> {
     #[inline]
     pub fn max(self, other: Self) -> Self {
         point3(
             self.x.max(other.x),
             self.y.max(other.y),
             self.z.max(other.z),
         )
     }
+
+    #[inline]
+    pub fn clamp(&self, start: Self, end: Self) -> Self {
+        self.max(start).min(end)
+    }
 }
 
 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)]
@@ -772,19 +786,22 @@ impl<T: Copy, U> From<[T; 3]> for TypedP
 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;
+    #[cfg(feature = "mint")]
+    use mint;
 
     #[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));
@@ -804,16 +821,26 @@ mod point2d {
     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(feature = "mint")]
+    #[test]
+    pub fn test_mint() {
+        let p1 = Point2D::new(1.0, 3.0);
+        let pm: mint::Point2<_> = p1.into();
+        let p2 = Point2D::from(pm);
+
+        assert_eq!(p1, p2);
+    }
 }
 
 #[cfg(test)]
 mod typedpoint2d {
     use super::{Point2D, TypedPoint2D, point2};
     use scale::TypedScale;
     use vector::vec2;
 
@@ -869,16 +896,18 @@ mod typedpoint2d {
         let p: Point2D<i32> = point2(1, 2);
         assert_eq!(p.yx(), point2(2, 1));
     }
 }
 
 #[cfg(test)]
 mod point3d {
     use super::{Point3D, point2, point3};
+    #[cfg(feature = "mint")]
+    use mint;
 
     #[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);
 
@@ -910,9 +939,20 @@ mod point3d {
 
     #[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));
     }
+
+    #[cfg(feature = "mint")]
+    #[test]
+    pub fn test_mint() {
+        let p1 = Point3D::new(1.0, 3.0, 5.0);
+        let pm: mint::Point3<_> = p1.into();
+        let p2 = Point3D::from(pm);
+
+        assert_eq!(p1, p2);
+    }
+
 }
--- a/third_party/rust/euclid/src/size.rs
+++ b/third_party/rust/euclid/src/size.rs
@@ -3,22 +3,24 @@
 //
 // 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;
+#[cfg(feature = "mint")]
+use mint;
 use length::Length;
 use scale::TypedScale;
 use vector::{TypedVector2D, vec2, BoolVector2D};
 use num::*;
 
-use num_traits::{NumCast, Signed};
+use num_traits::{Float, NumCast, Signed};
 use core::fmt;
 use core::ops::{Add, Div, Mul, Sub};
 use core::marker::PhantomData;
 
 /// A 2d size tagged with a unit.
 define_matrix! {
     pub struct TypedSize2D<T, U> {
         pub width: T,
@@ -322,24 +324,71 @@ impl<T: PartialEq, U> TypedSize2D<T, U> 
     pub fn not_equal(&self, other: &Self) -> BoolVector2D {
         BoolVector2D {
             x: self.width != other.width,
             y: self.height != other.height,
         }
     }
 }
 
+impl<T: Float, U> TypedSize2D<T, U> {
+    #[inline]
+    pub fn min(self, other: Self) -> Self {
+        size2(
+            self.width.min(other.width),
+            self.height.min(other.height),
+        )
+    }
+
+    #[inline]
+    pub fn max(self, other: Self) -> Self {
+        size2(
+            self.width.max(other.width),
+            self.height.max(other.height),
+        )
+    }
+
+    #[inline]
+    pub fn clamp(&self, start: Self, end: Self) -> Self {
+        self.max(start).min(end)
+    }
+}
+
+
 /// Shorthand for `TypedSize2D::new(w, h)`.
 pub fn size2<T, U>(w: T, h: T) -> TypedSize2D<T, U> {
     TypedSize2D::new(w, h)
 }
 
+#[cfg(feature = "mint")]
+impl<T, U> From<mint::Vector2<T>> for TypedSize2D<T, U> {
+    fn from(v: mint::Vector2<T>) -> Self {
+        TypedSize2D {
+            width: v.x,
+            height: v.y,
+            _unit: PhantomData,
+        }
+    }
+}
+#[cfg(feature = "mint")]
+impl<T, U> Into<mint::Vector2<T>> for TypedSize2D<T, U> {
+    fn into(self) -> mint::Vector2<T> {
+        mint::Vector2 {
+            x: self.width,
+            y: self.height,
+        }
+    }
+}
+
+
 #[cfg(test)]
 mod size2d {
     use super::Size2D;
+    #[cfg(feature = "mint")]
+    use mint;
 
     #[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);
@@ -374,9 +423,19 @@ mod size2d {
         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);
     }
+
+    #[cfg(feature = "mint")]
+    #[test]
+    pub fn test_mint() {
+        let s1 = Size2D::new(1.0, 2.0);
+        let sm: mint::Vector2<_> = s1.into();
+        let s2 = Size2D::from(sm);
+
+        assert_eq!(s1, s2);
+    }
 }
--- a/third_party/rust/euclid/src/transform2d.rs
+++ b/third_party/rust/euclid/src/transform2d.rs
@@ -5,16 +5,18 @@
 // 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 = "cargo-clippy", allow(just_underscores_and_digits))]
 
 use super::{UnknownUnit, Angle};
+#[cfg(feature = "mint")]
+use mint;
 use num::{One, Zero};
 use point::TypedPoint2D;
 use vector::{TypedVector2D, vec2};
 use rect::TypedRect;
 use transform3d::TypedTransform3D;
 use core::ops::{Add, Mul, Div, Sub, Neg};
 use core::marker::PhantomData;
 use approxeq::ApproxEq;
@@ -400,22 +402,47 @@ where T: Copy + fmt::Debug +
         if self.is_identity() {
             write!(f, "[I]")
         } else {
             self.to_row_major_array().fmt(f)
         }
     }
 }
 
+#[cfg(feature = "mint")]
+impl<T, Src, Dst> From<mint::RowMatrix3x2<T>> for TypedTransform2D<T, Src, Dst> {
+    fn from(m: mint::RowMatrix3x2<T>) -> Self {
+        TypedTransform2D {
+            m11: m.x.x, m12: m.x.y,
+            m21: m.y.x, m22: m.y.y,
+            m31: m.z.x, m32: m.z.y,
+            _unit: PhantomData,
+        }
+    }
+}
+#[cfg(feature = "mint")]
+impl<T, Src, Dst> Into<mint::RowMatrix3x2<T>> for TypedTransform2D<T, Src, Dst> {
+    fn into(self) -> mint::RowMatrix3x2<T> {
+        mint::RowMatrix3x2 {
+            x: mint::Vector2 { x: self.m11, y: self.m12 },
+            y: mint::Vector2 { x: self.m21, y: self.m22 },
+            z: mint::Vector2 { x: self.m31, y: self.m32 },
+        }
+    }
+}
+
+
 #[cfg(test)]
 mod test {
     use super::*;
     use approxeq::ApproxEq;
     use point::Point2D;
     use Angle;
+    #[cfg(feature = "mint")]
+    use mint;
 
     use core::f32::consts::FRAC_PI_2;
 
     type Mat = Transform2D<f32>;
 
     fn rad(v: f32) -> Angle<f32> { Angle::radians(v) }
 
     #[test]
@@ -534,9 +561,19 @@ mod test {
 
     #[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));
     }
+
+    #[cfg(feature = "mint")]
+    #[test]
+    pub fn test_mint() {
+        let m1 = Mat::create_rotation(rad(FRAC_PI_2));
+        let mm: mint::RowMatrix3x2<_> = m1.into();
+        let m2 = Mat::from(mm);
+
+        assert_eq!(m1, m2);
+    }
 }
--- a/third_party/rust/euclid/src/transform3d.rs
+++ b/third_party/rust/euclid/src/transform3d.rs
@@ -7,16 +7,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
 #![cfg_attr(feature = "cargo-clippy", allow(just_underscores_and_digits))]
 
 use super::{UnknownUnit, Angle};
 use approxeq::ApproxEq;
 use homogen::HomogeneousVector;
+#[cfg(feature = "mint")]
+use mint;
 use trig::Trig;
 use point::{TypedPoint2D, TypedPoint3D};
 use vector::{TypedVector2D, TypedVector3D, vec2, vec3};
 use rect::TypedRect;
 use transform2d::TypedTransform2D;
 use scale::TypedScale;
 use num::{One, Zero};
 use core::ops::{Add, Mul, Sub, Div, Neg};
@@ -736,16 +738,41 @@ where T: Copy + fmt::Debug +
         if self.is_identity() {
             write!(f, "[I]")
         } else {
             self.to_row_major_array().fmt(f)
         }
     }
 }
 
+#[cfg(feature = "mint")]
+impl<T, Src, Dst> From<mint::RowMatrix4<T>> for TypedTransform3D<T, Src, Dst> {
+    fn from(m: mint::RowMatrix4<T>) -> Self {
+        TypedTransform3D {
+            m11: m.x.x, m12: m.x.y, m13: m.x.z, m14: m.x.w,
+            m21: m.y.x, m22: m.y.y, m23: m.y.z, m24: m.y.w,
+            m31: m.z.x, m32: m.z.y, m33: m.z.z, m34: m.z.w,
+            m41: m.w.x, m42: m.w.y, m43: m.w.z, m44: m.w.w,
+            _unit: PhantomData,
+        }
+    }
+}
+#[cfg(feature = "mint")]
+impl<T, Src, Dst> Into<mint::RowMatrix4<T>> for TypedTransform3D<T, Src, Dst> {
+    fn into(self) -> mint::RowMatrix4<T> {
+        mint::RowMatrix4 {
+            x: mint::Vector4 { x: self.m11, y: self.m12, z: self.m13, w: self.m14 },
+            y: mint::Vector4 { x: self.m21, y: self.m22, z: self.m23, w: self.m24 },
+            z: mint::Vector4 { x: self.m31, y: self.m32, z: self.m33, w: self.m34 },
+            w: mint::Vector4 { x: self.m41, y: self.m42, z: self.m43, w: self.m44 },
+        }
+    }
+}
+
+
 #[cfg(test)]
 mod tests {
     use approxeq::ApproxEq;
     use transform2d::Transform2D;
     use point::{point2, point3};
     use Angle;
     use super::*;
 
@@ -1016,9 +1043,19 @@ mod tests {
         let mut m = Mf32::identity();
         assert!(m.transform_point2d(&p).is_some());
         m.m44 = 0.0;
         assert_eq!(None, m.transform_point2d(&p));
         m.m44 = 1.0;
         m.m24 = -1.0;
         assert_eq!(None, m.transform_point2d(&p));
     }
+
+    #[cfg(feature = "mint")]
+    #[test]
+    pub fn test_mint() {
+        let m1 = Mf32::create_rotation(0.0, 0.0, 1.0, rad(FRAC_PI_2));
+        let mm: mint::RowMatrix4<_> = m1.into();
+        let m2 = Mf32::from(mm);
+
+        assert_eq!(m1, m2);
+    }
 }
new file mode 100644
--- /dev/null
+++ b/third_party/rust/euclid/src/translation.rs
@@ -0,0 +1,474 @@
+// Copyright 2018 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 {TypedVector2D, TypedPoint2D, TypedVector3D, TypedPoint3D, TypedTransform2D, TypedTransform3D};
+use {TypedSize2D, TypedRect, vec2, point2, vec3, point3};
+use num::*;
+use trig::Trig;
+use core::ops::{Add, Sub, Neg, Mul, Div};
+use core::marker::PhantomData;
+use core::fmt;
+
+define_matrix! {
+    /// A 2d transformation from a space to another that can only express translations.
+    ///
+    /// The main benefit of this type over a TypedVector2D is the ability to cast
+    /// between a source and a destination spaces.
+    ///
+    /// Example:
+    ///
+    /// ```
+    /// use euclid::{TypedTranslation2D, TypedPoint2D, point2};
+    /// struct ParentSpace;
+    /// struct ChildSpace;
+    /// type ScrollOffset = TypedTranslation2D<i32, ParentSpace, ChildSpace>;
+    /// type ParentPoint = TypedPoint2D<i32, ParentSpace>;
+    /// type ChildPoint = TypedPoint2D<i32, ChildSpace>;
+    ///
+    /// let scrolling = ScrollOffset::new(0, 100);
+    /// let p1: ParentPoint = point2(0, 0);
+    /// let p2: ChildPoint = scrolling.transform_point(&p1);
+    /// ```
+    ///
+    pub struct TypedTranslation2D<T, Src, Dst> {
+        pub x: T,
+        pub y: T,
+    }
+}
+
+impl<T, Src, Dst> TypedTranslation2D<T, Src, Dst> {
+    #[inline]
+    pub fn new(x: T, y: T) -> Self {
+        TypedTranslation2D {
+            x,
+            y,
+            _unit: PhantomData,
+        }
+    }
+}
+
+impl<T, Src, Dst> TypedTranslation2D<T, Src, Dst>
+where
+    T : Copy
+{
+    #[inline]
+    pub fn to_array(&self) -> [T; 2] {
+        [self.x, self.y]
+    }
+}
+
+impl<T, Src, Dst> TypedTranslation2D<T, Src, Dst>
+where
+    T : Copy + Zero
+{
+    #[inline]
+    pub fn identity() -> Self {
+        let _0 = T::zero();
+        TypedTranslation2D::new(_0, _0)
+    }
+}
+
+impl<T, Src, Dst> TypedTranslation2D<T, Src, Dst>
+where
+    T: Zero + PartialEq
+{
+    #[inline]
+    pub fn is_identity(&self) -> bool {
+        self.x == T::zero() && self.y == T::zero()
+    }
+}
+
+impl<T, Src, Dst> TypedTranslation2D<T, Src, Dst>
+where
+    T: Copy + Add<T, Output = T>
+{
+    /// Translate a point and cast its unit.
+    #[inline]
+    pub fn transform_point(&self, p: &TypedPoint2D<T, Src>) -> TypedPoint2D<T, Dst> {
+        point2(p.x + self.x, p.y + self.y)
+    }
+
+    /// Translate a rectangle and cast its unit.
+    #[inline]
+    pub fn transform_rect(&self, r: &TypedRect<T, Src>) -> TypedRect<T, Dst> {
+        TypedRect {
+            origin: self.transform_point(&r.origin),
+            size: self.transform_size(&r.size),
+        }
+    }
+
+    /// No-op, just cast the unit.
+    #[inline]
+    pub fn transform_size(&self, s: &TypedSize2D<T, Src>) -> TypedSize2D<T, Dst> {
+        TypedSize2D::new(s.width, s.height)
+    }
+
+    /// Cast into a 2D vector.
+    pub fn to_vector(&self) -> TypedVector2D<T, Src> {
+        vec2(self.x, self.y)
+    }
+}
+
+impl<T, Src, Dst> TypedTranslation2D<T, Src, Dst>
+where
+    T: Copy + Neg<Output = T>
+{
+    /// Return the inverse transformation.
+    #[inline]
+    pub fn inverse(&self) -> TypedTranslation2D<T, Dst, Src> {
+        TypedTranslation2D::new(-self.x, -self.y)
+    }
+}
+
+impl<T, Src, Dst1, Dst2> Add<TypedTranslation2D<T, Dst1, Dst2>>
+for TypedTranslation2D<T, Src, Dst1>
+where
+    T: Copy + Add<T, Output = T>
+{
+    type Output = TypedTranslation2D<T, Src, Dst2>;
+    fn add(self, other: TypedTranslation2D<T, Dst1, Dst2>) -> TypedTranslation2D<T, Src, Dst2> {
+        TypedTranslation2D::new(
+            self.x + other.x,
+            self.y + other.y,
+        )
+    }
+}
+
+impl<T, Src, Dst1, Dst2>
+    Sub<TypedTranslation2D<T, Dst1, Dst2>>
+    for TypedTranslation2D<T, Src, Dst2>
+where
+    T: Copy + Sub<T, Output = T>
+{
+    type Output = TypedTranslation2D<T, Src, Dst1>;
+    fn sub(self, other: TypedTranslation2D<T, Dst1, Dst2>) -> TypedTranslation2D<T, Src, Dst1> {
+        TypedTranslation2D::new(
+            self.x - other.x,
+            self.y - other.y,
+        )
+    }
+}
+
+impl<T, Src, Dst> TypedTranslation2D<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 translation.
+    #[inline]
+    pub fn to_transform(&self) -> TypedTransform2D<T, Src, Dst> {
+        TypedTransform2D::create_translation(self.x, self.y)
+    }
+}
+
+impl<T, Src, Dst> From<TypedVector2D<T, Src>> for TypedTranslation2D<T, Src, Dst>
+where
+    T: Copy
+{
+    fn from(v: TypedVector2D<T, Src>) -> Self {
+        TypedTranslation2D::new(v.x, v.y)
+    }
+}
+
+impl<T, Src, Dst> Into<TypedVector2D<T, Src>> for TypedTranslation2D<T, Src, Dst>
+where
+    T: Copy
+{
+    fn into(self) -> TypedVector2D<T, Src> {
+        vec2(self.x, self.y)
+    }
+}
+
+impl<T, Src, Dst> Into<TypedTransform2D<T, Src, Dst>> for TypedTranslation2D<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,
+{
+    fn into(self) -> TypedTransform2D<T, Src, Dst> {
+        self.to_transform()
+    }
+}
+
+impl <T, Src, Dst> Default for TypedTranslation2D<T, Src, Dst>
+    where T: Copy + Zero
+{
+    fn default() -> Self {
+        Self::identity()
+    }
+}
+
+impl<T, Src, Dst> fmt::Debug for TypedTranslation2D<T, Src, Dst>
+where T: Copy + fmt::Debug {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.to_array().fmt(f)
+    }
+}
+
+
+
+define_matrix! {
+    /// A 3d transformation from a space to another that can only express translations.
+    ///
+    /// The main benefit of this type over a TypedVector3D is the ability to cast
+    /// between a source and a destination spaces.
+    pub struct TypedTranslation3D<T, Src, Dst> {
+        pub x: T,
+        pub y: T,
+        pub z: T,
+    }
+}
+
+impl<T, Src, Dst> TypedTranslation3D<T, Src, Dst> {
+    #[inline]
+    pub fn new(x: T, y: T, z: T) -> Self {
+        TypedTranslation3D {
+            x,
+            y,
+            z,
+            _unit: PhantomData,
+        }
+    }
+}
+
+impl<T, Src, Dst> TypedTranslation3D<T, Src, Dst>
+where
+    T: Copy
+{
+    #[inline]
+    pub fn to_array(&self) -> [T; 3] {
+        [self.x, self.y, self.z]
+    }
+}
+
+impl<T, Src, Dst> TypedTranslation3D<T, Src, Dst>
+where
+    T: Copy + Zero
+{
+    #[inline]
+    pub fn identity() -> Self {
+        let _0 = T::zero();
+        TypedTranslation3D::new(_0, _0, _0)
+    }
+}
+
+impl<T, Src, Dst> TypedTranslation3D<T, Src, Dst>
+where
+    T: Zero + PartialEq
+{
+    #[inline]
+    pub fn is_identity(&self) -> bool {
+        self.x == T::zero() && self.y == T::zero() && self.z == T::zero()
+    }
+}
+
+impl<T, Src, Dst> TypedTranslation3D<T, Src, Dst>
+where
+    T: Copy + Add<T, Output = T>
+{
+    /// Translate a point and cast its unit.
+    #[inline]
+    pub fn transform_point3d(&self, p: &TypedPoint3D<T, Src>) -> TypedPoint3D<T, Dst> {
+        point3(p.x + self.x, p.y + self.y, p.z + self.z)
+    }
+
+    /// Translate a point and cast its unit.
+    #[inline]
+    pub fn transform_point2d(&self, p: &TypedPoint2D<T, Src>) -> TypedPoint2D<T, Dst> {
+        point2(p.x + self.x, p.y + self.y)
+    }
+
+    /// Translate a rectangle and cast its unit.
+    #[inline]
+    pub fn transform_rect(&self, r: &TypedRect<T, Src>) -> TypedRect<T, Dst> {
+        TypedRect {
+            origin: self.transform_point2d(&r.origin),
+            size: self.transform_size(&r.size),
+        }
+    }
+
+    /// No-op, just cast the unit.
+    #[inline]
+    pub fn transform_size(&self, s: &TypedSize2D<T, Src>) -> TypedSize2D<T, Dst> {
+        TypedSize2D::new(s.width, s.height)
+    }
+
+    /// Cast into a 3D vector.
+    pub fn to_vector(&self) -> TypedVector3D<T, Src> {
+        vec3(self.x, self.y, self.z)
+    }
+}
+
+impl<T, Src, Dst> TypedTranslation3D<T, Src, Dst>
+where
+    T: Copy + Neg<Output = T>
+{
+    /// Return the inverse transformation.
+    #[inline]
+    pub fn inverse(&self) -> TypedTranslation3D<T, Dst, Src> {
+        TypedTranslation3D::new(-self.x, -self.y, -self.z)
+    }
+}
+
+impl<T, Src, Dst1, Dst2> Add<TypedTranslation3D<T, Dst1, Dst2>>
+for TypedTranslation3D<T, Src, Dst1>
+where
+    T: Copy + Add<T, Output = T>
+{
+    type Output = TypedTranslation3D<T, Src, Dst2>;
+    fn add(self, other: TypedTranslation3D<T, Dst1, Dst2>) -> TypedTranslation3D<T, Src, Dst2> {
+        TypedTranslation3D::new(
+            self.x + other.x,
+            self.y + other.y,
+            self.z + other.z,
+        )
+    }
+}
+
+impl<T, Src, Dst1, Dst2>
+    Sub<TypedTranslation3D<T, Dst1, Dst2>>
+    for TypedTranslation3D<T, Src, Dst2>
+where
+    T: Copy + Sub<T, Output = T>
+{
+    type Output = TypedTranslation3D<T, Src, Dst1>;
+    fn sub(self, other: TypedTranslation3D<T, Dst1, Dst2>) -> TypedTranslation3D<T, Src, Dst1> {
+        TypedTranslation3D::new(
+            self.x - other.x,
+            self.y - other.y,
+            self.z - other.z,
+        )
+    }
+}
+
+impl<T, Src, Dst> TypedTranslation3D<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> +
+        PartialOrd +
+        Trig +
+        One + Zero,
+{
+    /// Returns the matrix representation of this translation.
+    #[inline]
+    pub fn to_transform(&self) -> TypedTransform3D<T, Src, Dst> {
+        TypedTransform3D::create_translation(self.x, self.y, self.z)
+    }
+}
+
+impl<T, Src, Dst> From<TypedVector3D<T, Src>> for TypedTranslation3D<T, Src, Dst>
+where
+    T: Copy
+{
+    fn from(v: TypedVector3D<T, Src>) -> Self {
+        TypedTranslation3D::new(v.x, v.y, v.z)
+    }
+}
+
+impl<T, Src, Dst> Into<TypedVector3D<T, Src>> for TypedTranslation3D<T, Src, Dst>
+where
+    T: Copy
+{
+    fn into(self) -> TypedVector3D<T, Src> {
+        vec3(self.x, self.y, self.z)
+    }
+}
+
+impl<T, Src, Dst> Into<TypedTransform3D<T, Src, Dst>> for TypedTranslation3D<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> +
+        PartialOrd +
+        Trig +
+        One + Zero,
+{
+    fn into(self) -> TypedTransform3D<T, Src, Dst> {
+        self.to_transform()
+    }
+}
+
+impl <T, Src, Dst> Default for TypedTranslation3D<T, Src, Dst>
+    where T: Copy + Zero
+{
+    fn default() -> Self {
+        Self::identity()
+    }
+}
+
+impl<T, Src, Dst> fmt::Debug for TypedTranslation3D<T, Src, Dst>
+where T: Copy + fmt::Debug {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.to_array().fmt(f)
+    }
+}
+
+#[test]
+fn simple_translation2d() {
+    use rect;
+
+    struct A;
+    struct B;
+
+    type Translation = TypedTranslation2D<i32, A, B>;
+    type SrcRect = TypedRect<i32, A>;
+    type DstRect = TypedRect<i32, B>;
+
+    let tx = Translation::new(10, -10);
+    let r1: SrcRect = rect(10, 20, 30, 40);
+    let r2: DstRect = tx.transform_rect(&r1);
+    assert_eq!(r2, rect(20, 10, 30, 40));
+
+    let inv_tx = tx.inverse();
+    assert_eq!(inv_tx.transform_rect(&r2), r1);
+
+    assert!((tx + inv_tx).is_identity());
+}
+
+#[test]
+fn simple_translation3d() {
+    struct A;
+    struct B;
+
+    type Translation = TypedTranslation3D<i32, A, B>;
+    type SrcPoint = TypedPoint3D<i32, A>;
+    type DstPoint = TypedPoint3D<i32, B>;
+
+    let tx = Translation::new(10, -10, 100);
+    let p1: SrcPoint = point3(10, 20, 30);
+    let p2: DstPoint = tx.transform_point3d(&p1);
+    assert_eq!(p2, point3(20, 10, 130));
+
+    let inv_tx = tx.inverse();
+    assert_eq!(inv_tx.transform_point3d(&p2), p1);
+
+    assert!((tx + inv_tx).is_identity());
+}
--- a/third_party/rust/euclid/src/vector.rs
+++ b/third_party/rust/euclid/src/vector.rs
@@ -5,16 +5,18 @@
 // 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;
+#[cfg(feature = "mint")]
+use mint;
 use point::{TypedPoint2D, TypedPoint3D, point2, point3};
 use size::{TypedSize2D, size2};
 use scale::TypedScale;
 use trig::Trig;
 use Angle;
 use num::*;
 use num_traits::{Float, NumCast, Signed};
 use core::fmt;
@@ -23,16 +25,17 @@ use core::marker::PhantomData;
 
 define_matrix! {
     /// A 2d Vector tagged with a unit.
     pub struct TypedVector2D<T, U> {
         pub x: T,
         pub y: T,
     }
 }
+mint_vec!(TypedVector2D[x, y] = Vector2);
 
 /// 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.
@@ -254,16 +257,21 @@ impl<T: Float, U> TypedVector2D<T, U> {
     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))
     }
+
+    #[inline]
+    pub fn clamp(&self, start: Self, end: Self) -> Self {
+        self.max(start).min(end)
+    }
 }
 
 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)
     }
@@ -463,16 +471,17 @@ where
 define_matrix! {
     /// A 3d Vector tagged with a unit.
     pub struct TypedVector3D<T, U> {
         pub x: T,
         pub y: T,
         pub z: T,
     }
 }
+mint_vec!(TypedVector3D[x, y, z] = Vector3);
 
 /// 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 components to zero.
@@ -737,16 +746,21 @@ impl<T: Float, U> TypedVector3D<T, U> {
     #[inline]
     pub fn max(self, other: Self) -> Self {
         vec3(
             self.x.max(other.x),
             self.y.max(other.y),
             self.z.max(other.z),
         )
     }
+
+    #[inline]
+    pub fn clamp(&self, start: Self, end: Self) -> Self {
+        self.max(start).min(end)
+    }
 }
 
 impl<T: Copy + Mul<T, Output = T>, U1, U2> Mul<TypedScale<T, U1, U2>> for TypedVector3D<T, U1> {
     type Output = TypedVector3D<T, U2>;
     #[inline]
     fn mul(self, scale: TypedScale<T, U1, U2>) -> Self::Output {
         vec3(self.x * scale.get(), self.y * scale.get(), self.z * scale.get())
     }
@@ -1175,16 +1189,18 @@ pub fn bvec2(x: bool, y: bool) -> BoolVe
 pub fn bvec3(x: bool, y: bool, z: bool) -> BoolVector3D {
     BoolVector3D { x, y, z }
 }
 
 
 #[cfg(test)]
 mod vector2d {
     use super::{Vector2D, vec2};
+    #[cfg(feature = "mint")]
+    use mint;
     type Vec2 = Vector2D<f32>;
 
     #[test]
     pub fn test_scalar_mul() {
         let p1: Vec2 = vec2(3.0, 5.0);
 
         let result = p1 * 5.0;
 
@@ -1234,30 +1250,39 @@ mod vector2d {
     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));
     }
-
     #[test]
     pub fn test_angle_from_x_axis() {
         use core::f32::consts::FRAC_PI_2;
         use approxeq::ApproxEq;
 
         let right: Vec2 = vec2(10.0, 0.0);
         let down: Vec2 = vec2(0.0, 4.0);
         let up: Vec2 = vec2(0.0, -1.0);
 
         assert!(right.angle_from_x_axis().get().approx_eq(&0.0));
         assert!(down.angle_from_x_axis().get().approx_eq(&FRAC_PI_2));
         assert!(up.angle_from_x_axis().get().approx_eq(&-FRAC_PI_2));
     }
+
+    #[cfg(feature = "mint")]
+    #[test]
+    pub fn test_mint() {
+        let v1 = Vec2::new(1.0, 3.0);
+        let vm: mint::Vector2<_> = v1.into();
+        let v2 = Vec2::from(vm);
+
+        assert_eq!(v1, v2);
+    }
 }
 
 #[cfg(test)]
 mod typedvector2d {
     use super::{TypedVector2D, Vector2D, vec2};
     use scale::TypedScale;
 
     pub enum Mm {}
@@ -1298,16 +1323,18 @@ mod typedvector2d {
     pub fn test_swizzling() {
         let p: Vector2D<i32> = vec2(1, 2);
         assert_eq!(p.yx(), vec2(2, 1));
     }
 }
 
 #[cfg(test)]
 mod vector3d {
+    #[cfg(feature = "mint")]
+    use mint;
     use super::{TypedVector3D, Vector3D, vec2, vec3};
     use scale::TypedScale;
 
     type Vec3 = Vector3D<f32>;
 
     #[test]
     pub fn test_dot() {
         let p1: Vec3 = vec3(7.0, 21.0, 32.0);
@@ -1355,16 +1382,27 @@ mod vector3d {
         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_clamp() {
+        let p1: Vec3 = vec3(1.0, -1.0, 5.0);
+        let p2: Vec3 = vec3(2.0, 5.0, 10.0);
+        let p3: Vec3 = vec3(-1.0, 2.0, 20.0);
+
+        let result = p3.clamp(p1, p2);
+
+        assert_eq!(result, vec3(1.0, 2.0, 10.0));
+    }
+
+    #[test]
     pub fn test_scalar_mul() {
         enum Mm {}
         enum Cm {}
 
         let p1 = TypedVector3D::<f32, Mm>::new(1.0, 2.0, 3.0);
         let cm_per_mm = TypedScale::<f32, Mm, Cm>::new(0.1);
 
         let result: TypedVector3D<f32, Cm> = p1 * cm_per_mm;
@@ -1374,16 +1412,26 @@ mod vector3d {
 
     #[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));
     }
+
+    #[cfg(feature = "mint")]
+    #[test]
+    pub fn test_mint() {
+        let v1 = Vec3::new(1.0, 3.0, 5.0);
+        let vm: mint::Vector3<_> = v1.into();
+        let v2 = Vec3::from(vm);
+
+        assert_eq!(v1, v2);
+    }
 }
 
 #[cfg(test)]
 mod bool_vector {
     use super::*;
     type Vec2 = Vector2D<f32>;
     type Vec3 = Vector3D<f32>;