[ermine] Add rusttype for rendering text

Removal of font-rs will follow in a separate CL once all users of font-rs are moved over.

Testing: manual
Change-Id: Iccacae3b605f93251136935d6464f7b880158755
diff --git a/rustc_deps/Cargo.lock b/rustc_deps/Cargo.lock
index c7dccc3..0c2bf33 100644
--- a/rustc_deps/Cargo.lock
+++ b/rustc_deps/Cargo.lock
@@ -20,6 +20,14 @@
 ]
 
 [[package]]
+name = "approx"
+version = "0.3.0"
+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)",
+]
+
+[[package]]
 name = "arrayref"
 version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -511,6 +519,7 @@
  "rouille 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rust-crypto 0.2.36",
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rusttype 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -982,6 +991,14 @@
 ]
 
 [[package]]
+name = "ordered-float"
+version = "1.0.1"
+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)",
+]
+
+[[package]]
 name = "owning_ref"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1280,6 +1297,17 @@
 ]
 
 [[package]]
+name = "rusttype"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "approx 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "arrayvec 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ordered-float 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "stb_truetype 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "ryu"
 version = "0.2.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1396,6 +1424,14 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "stb_truetype"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "string"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1853,6 +1889,7 @@
 "checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c"
 "checksum aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e"
 "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
+"checksum approx 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f71f10b5c4946a64aad7b8cf65e3406cd3da22fc448595991d22423cf6db67b4"
 "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"
 "checksum arrayvec 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f405cc4c21cd8b784f6c8fc2adf9bc00f59558f0049b5ec21517f875963040cc"
 "checksum ascii 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)" = "97be891acc47ca214468e09425d02cef3af2c94d0d82081cd02061f996802f14"
@@ -1958,6 +1995,7 @@
 "checksum num-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4e96f040177bb3da242b5b1ecf3f54b5d5af3efbbfb18608977a5d2767b22f10"
 "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
 "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
+"checksum ordered-float 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2f0015e9e8e28ee20c581cfbfe47c650cedeb9ed0721090e0b7ebb10b9cdbcc2"
 "checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"
 "checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5"
 "checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c"
@@ -1990,6 +2028,7 @@
 "checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395"
 "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
 "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
+"checksum rusttype 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "436c67ae0d0d24f14e1177c3ed96780ee16db82b405f0fba1bb80b46c9a30625"
 "checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7"
 "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f"
 "checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9"
@@ -2007,6 +2046,7 @@
 "checksum slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d"
 "checksum smallvec 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "622df2d454c29a4d89b30dc3b27b42d7d90d6b9e587dbf8f67652eb7514da484"
 "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
+"checksum stb_truetype 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "48fa7d3136d8645909de1f7c7eb5416cc43057a75ace08fc39ae736bc9da8af1"
 "checksum string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00caf261d6f90f588f8450b8e1230fa0d5be49ee6140fdfbcb55335aff350970"
 "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
 "checksum structopt 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "d77af7242f18c40fd19cb270985930f239ee1646cfb482050bbae9da1d18743b"
diff --git a/rustc_deps/Cargo.toml b/rustc_deps/Cargo.toml
index b821754..f18fc1e 100644
--- a/rustc_deps/Cargo.toml
+++ b/rustc_deps/Cargo.toml
@@ -46,6 +46,7 @@
 rouille = "2.1.0"
 rust-crypto = "0.2"
 rustc-serialize = "0.3"
+rusttype = "0.7.3"
 serde = "1"
 serde_derive = "1"
 serde_json = "1"
diff --git a/rustc_deps/vendor/approx/.cargo-checksum.json b/rustc_deps/vendor/approx/.cargo-checksum.json
new file mode 100644
index 0000000..0ad615c
--- /dev/null
+++ b/rustc_deps/vendor/approx/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"30a7d07b350a74b89c51f9d8e36f7038a26ee8a2a1186f51bf56e0f3880a9716","LICENSE":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","README.md":"5e965438ec90b7ede0a5c93c482a91536759c147e215f7471d8534f121feb244","src/abs_diff_eq.rs":"b71b5f643a5d6163f35994083046da361e7e7d1f3130d1972055b5c96427e835","src/lib.rs":"1c4276160fa54470a4298efef54c63d6f31bf2196ae83077748443172823c0d2","src/macros.rs":"01c0e72ba04adb8780061b326cbb5b787805ba142bd7e66391545a621a811c7b","src/relative_eq.rs":"926b7d6db2bab2c3d04c7826aa34e814cdde03e7e410d60658689d481d975403","src/ulps_eq.rs":"cc1bf0528fa099b5e72ba80a924a8217eb7a0eed121db1737ddcd66e6612982e","tests/abs_diff_eq.rs":"9df9b48842dbc61b04b0328b64f2ce48b6e66e9538178babd58a9e52adeaddaf","tests/macros.rs":"697241db4db66633cb53324bb127c64fd3b544236055bfe1721abb64a1dfab23","tests/relative_eq.rs":"c114edb6af07a2ac126e167682dd5d677d5591217f48bfdba150f866dfe4fdaf","tests/ulps_eq.rs":"ef6d57b98394fc87e724e26de7a3461426444563ec962661f660875b0702aeb6"},"package":"f71f10b5c4946a64aad7b8cf65e3406cd3da22fc448595991d22423cf6db67b4"}
\ No newline at end of file
diff --git a/rustc_deps/vendor/approx/Cargo.toml b/rustc_deps/vendor/approx/Cargo.toml
new file mode 100644
index 0000000..dcad427
--- /dev/null
+++ b/rustc_deps/vendor/approx/Cargo.toml
@@ -0,0 +1,39 @@
+# 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 = "approx"
+version = "0.3.0"
+authors = ["Brendan Zabarauskas <bjzaba@yahoo.com.au>"]
+description = "Approximate floating point equality comparisons and assertions."
+homepage = "https://github.com/brendanzab/approx"
+documentation = "https://docs.rs/approx"
+readme = "README.md"
+keywords = ["approximate", "assert", "comparison", "equality", "float"]
+license = "Apache-2.0"
+repository = "https://github.com/brendanzab/approx"
+[package.metadata.docs.rs]
+features = ["std", "num-complex"]
+
+[lib]
+name = "approx"
+[dependencies.num-complex]
+version = "0.2.0"
+optional = true
+
+[dependencies.num-traits]
+version = "0.2.0"
+default_features = false
+
+[features]
+default = ["std"]
+std = []
diff --git a/rustc_deps/vendor/approx/LICENSE b/rustc_deps/vendor/approx/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/rustc_deps/vendor/approx/LICENSE
@@ -0,0 +1,202 @@
+
+                                 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.
diff --git a/rustc_deps/vendor/approx/README.md b/rustc_deps/vendor/approx/README.md
new file mode 100644
index 0000000..601cc3c
--- /dev/null
+++ b/rustc_deps/vendor/approx/README.md
@@ -0,0 +1,20 @@
+# approx
+
+[![Build Status][travis_badge]][travis_url]
+[![Version][version_badge]][crate_url]
+[![Documentation][docs_badge]][docs_url]
+[![Downloads][downloads_badge]][crate_url]
+[![License][license_badge]][license_url]
+
+[travis_badge]: https://travis-ci.org/brendanzab/approx.svg?branch=master
+[docs_badge]: https://docs.rs/approx/badge.svg
+[version_badge]: https://img.shields.io/crates/v/approx.svg
+[license_badge]: https://img.shields.io/crates/l/approx.svg
+[downloads_badge]: https://img.shields.io/crates/d/approx.svg
+
+[travis_url]: https://travis-ci.org/brendanzab/approx
+[docs_url]: https://docs.rs/approx
+[crate_url]: https://crates.io/crates/approx
+[license_url]: https://github.com/brendanzab/approx/blob/master/LICENSE
+
+Approximate floating point equality comparisons and assertions for the Rust Programming Language.
diff --git a/rustc_deps/vendor/approx/src/abs_diff_eq.rs b/rustc_deps/vendor/approx/src/abs_diff_eq.rs
new file mode 100644
index 0000000..cf13ec3
--- /dev/null
+++ b/rustc_deps/vendor/approx/src/abs_diff_eq.rs
@@ -0,0 +1,181 @@
+#[cfg(feature = "num-complex")]
+use num_complex::Complex;
+#[cfg(not(feature = "std"))]
+use num_traits::float::FloatCore;
+use std::{cell, f32, f64};
+
+/// Equality that is defined using the absolute difference of two numbers.
+pub trait AbsDiffEq: PartialEq {
+    /// Used for specifying relative comparisons.
+    type Epsilon;
+
+    /// The default tolerance to use when testing values that are close together.
+    ///
+    /// This is used when no `epsilon` value is supplied to the `abs_diff_eq!`, `relative_eq!`, or
+    /// `ulps_eq!` macros.
+    fn default_epsilon() -> Self::Epsilon;
+
+    /// A test for equality that uses the absolute difference to compute the approximate
+    /// equality of two numbers.
+    fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool;
+
+    /// The inverse of `ApproxEq::abs_diff_eq`.
+    fn abs_diff_ne(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
+        !Self::abs_diff_eq(self, other, epsilon)
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Base implementations
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+macro_rules! impl_unsigned_abs_diff_eq {
+    ($T:ident, $default_epsilon:expr) => {
+        impl AbsDiffEq for $T {
+            type Epsilon = $T;
+
+            #[inline]
+            fn default_epsilon() -> $T {
+                $default_epsilon
+            }
+
+            #[inline]
+            fn abs_diff_eq(&self, other: &$T, epsilon: $T) -> bool {
+                (if self > other {
+                    self - other
+                } else {
+                    other - self
+                }) <= epsilon
+            }
+        }
+    };
+}
+
+impl_unsigned_abs_diff_eq!(u8, 0);
+impl_unsigned_abs_diff_eq!(u16, 0);
+impl_unsigned_abs_diff_eq!(u32, 0);
+impl_unsigned_abs_diff_eq!(u64, 0);
+impl_unsigned_abs_diff_eq!(usize, 0);
+
+macro_rules! impl_signed_abs_diff_eq {
+    ($T:ident, $default_epsilon:expr) => {
+        impl AbsDiffEq for $T {
+            type Epsilon = $T;
+
+            #[inline]
+            fn default_epsilon() -> $T {
+                $default_epsilon
+            }
+
+            #[inline]
+            fn abs_diff_eq(&self, other: &$T, epsilon: $T) -> bool {
+                $T::abs(self - other) <= epsilon
+            }
+        }
+    };
+}
+
+impl_signed_abs_diff_eq!(i8, 0);
+impl_signed_abs_diff_eq!(i16, 0);
+impl_signed_abs_diff_eq!(i32, 0);
+impl_signed_abs_diff_eq!(i64, 0);
+impl_signed_abs_diff_eq!(isize, 0);
+impl_signed_abs_diff_eq!(f32, f32::EPSILON);
+impl_signed_abs_diff_eq!(f64, f64::EPSILON);
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Derived implementations
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+impl<'a, T: AbsDiffEq + ?Sized> AbsDiffEq for &'a T {
+    type Epsilon = T::Epsilon;
+
+    #[inline]
+    fn default_epsilon() -> T::Epsilon {
+        T::default_epsilon()
+    }
+
+    #[inline]
+    fn abs_diff_eq(&self, other: &&'a T, epsilon: T::Epsilon) -> bool {
+        T::abs_diff_eq(*self, *other, epsilon)
+    }
+}
+
+impl<'a, T: AbsDiffEq + ?Sized> AbsDiffEq for &'a mut T {
+    type Epsilon = T::Epsilon;
+
+    #[inline]
+    fn default_epsilon() -> T::Epsilon {
+        T::default_epsilon()
+    }
+
+    #[inline]
+    fn abs_diff_eq(&self, other: &&'a mut T, epsilon: T::Epsilon) -> bool {
+        T::abs_diff_eq(*self, *other, epsilon)
+    }
+}
+
+impl<T: AbsDiffEq + Copy> AbsDiffEq for cell::Cell<T> {
+    type Epsilon = T::Epsilon;
+
+    #[inline]
+    fn default_epsilon() -> T::Epsilon {
+        T::default_epsilon()
+    }
+
+    #[inline]
+    fn abs_diff_eq(&self, other: &cell::Cell<T>, epsilon: T::Epsilon) -> bool {
+        T::abs_diff_eq(&self.get(), &other.get(), epsilon)
+    }
+}
+
+impl<T: AbsDiffEq + ?Sized> AbsDiffEq for cell::RefCell<T> {
+    type Epsilon = T::Epsilon;
+
+    #[inline]
+    fn default_epsilon() -> T::Epsilon {
+        T::default_epsilon()
+    }
+
+    #[inline]
+    fn abs_diff_eq(&self, other: &cell::RefCell<T>, epsilon: T::Epsilon) -> bool {
+        T::abs_diff_eq(&self.borrow(), &other.borrow(), epsilon)
+    }
+}
+
+impl<T: AbsDiffEq> AbsDiffEq for [T]
+where
+    T::Epsilon: Clone,
+{
+    type Epsilon = T::Epsilon;
+
+    #[inline]
+    fn default_epsilon() -> T::Epsilon {
+        T::default_epsilon()
+    }
+
+    #[inline]
+    fn abs_diff_eq(&self, other: &[T], epsilon: T::Epsilon) -> bool {
+        self.len() == other.len()
+            && Iterator::zip(self.iter(), other).all(|(x, y)| T::abs_diff_eq(x, y, epsilon.clone()))
+    }
+}
+
+#[cfg(feature = "num-complex")]
+impl<T: AbsDiffEq> AbsDiffEq for Complex<T>
+where
+    T::Epsilon: Clone,
+{
+    type Epsilon = T::Epsilon;
+
+    #[inline]
+    fn default_epsilon() -> T::Epsilon {
+        T::default_epsilon()
+    }
+
+    #[inline]
+    fn abs_diff_eq(&self, other: &Complex<T>, epsilon: T::Epsilon) -> bool {
+        T::abs_diff_eq(&self.re, &other.re, epsilon.clone())
+            && T::abs_diff_eq(&self.im, &other.im, epsilon.clone())
+    }
+}
diff --git a/rustc_deps/vendor/approx/src/lib.rs b/rustc_deps/vendor/approx/src/lib.rs
new file mode 100644
index 0000000..6e45373
--- /dev/null
+++ b/rustc_deps/vendor/approx/src/lib.rs
@@ -0,0 +1,354 @@
+// Copyright 2015 Brendan Zabarauskas
+//
+// 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.
+
+//! A crate that provides facilities for testing the approximate equality of floating-point
+//! based types, using either relative difference, or units in the last place (ULPs)
+//! comparisons.
+//!
+//! You can also use the `approx_{eq, ne}!` `assert_approx_{eq, ne}!` macros to test for equality
+//! using a more positional style.
+//!
+//! ```rust
+//! #[macro_use]
+//! extern crate approx;
+//!
+//! use std::f64;
+//!
+//! # fn main() {
+//! abs_diff_eq!(1.0, 1.0);
+//! abs_diff_eq!(1.0, 1.0, epsilon = f64::EPSILON);
+//!
+//! relative_eq!(1.0, 1.0);
+//! relative_eq!(1.0, 1.0, epsilon = f64::EPSILON);
+//! relative_eq!(1.0, 1.0, max_relative = 1.0);
+//! relative_eq!(1.0, 1.0, epsilon = f64::EPSILON, max_relative = 1.0);
+//! relative_eq!(1.0, 1.0, max_relative = 1.0, epsilon = f64::EPSILON);
+//!
+//! ulps_eq!(1.0, 1.0);
+//! ulps_eq!(1.0, 1.0, epsilon = f64::EPSILON);
+//! ulps_eq!(1.0, 1.0, max_ulps = 4);
+//! ulps_eq!(1.0, 1.0, epsilon = f64::EPSILON, max_ulps = 4);
+//! ulps_eq!(1.0, 1.0, max_ulps = 4, epsilon = f64::EPSILON);
+//! # }
+//! ```
+//!
+//! # Implementing approximate equality for custom types
+//!
+//! The `ApproxEq` trait allows approximate equalities to be implemented on types, based on the
+//! fundamental floating point implementations.
+//!
+//! For example, we might want to be able to do approximate assertions on a complex number type:
+//!
+//! ```rust
+//! #[macro_use]
+//! extern crate approx;
+//! # use approx::{AbsDiffEq, RelativeEq, UlpsEq};
+//!
+//! #[derive(Debug, PartialEq)]
+//! struct Complex<T> {
+//!     x: T,
+//!     i: T,
+//! }
+//! # impl<T: AbsDiffEq> AbsDiffEq for Complex<T> where T::Epsilon: Copy {
+//! #     type Epsilon = T::Epsilon;
+//! #     fn default_epsilon() -> T::Epsilon { T::default_epsilon() }
+//! #     fn abs_diff_eq(&self, other: &Self, epsilon: T::Epsilon) -> bool {
+//! #         T::abs_diff_eq(&self.x, &other.x, epsilon) &&
+//! #         T::abs_diff_eq(&self.i, &other.i, epsilon)
+//! #     }
+//! # }
+//! # impl<T: RelativeEq> RelativeEq for Complex<T> where T::Epsilon: Copy {
+//! #     fn default_max_relative() -> T::Epsilon { T::default_max_relative() }
+//! #     fn relative_eq(&self, other: &Self, epsilon: T::Epsilon, max_relative: T::Epsilon)
+//! #                   -> bool {
+//! #         T::relative_eq(&self.x, &other.x, epsilon, max_relative) &&
+//! #         T::relative_eq(&self.i, &other.i, epsilon, max_relative)
+//! #     }
+//! # }
+//! # impl<T: UlpsEq> UlpsEq for Complex<T> where T::Epsilon: Copy {
+//! #     fn default_max_ulps() -> u32 { T::default_max_ulps() }
+//! #     fn ulps_eq(&self, other: &Self, epsilon: T::Epsilon, max_ulps: u32) -> bool {
+//! #         T::ulps_eq(&self.x, &other.x, epsilon, max_ulps) &&
+//! #         T::ulps_eq(&self.i, &other.i, epsilon, max_ulps)
+//! #     }
+//! # }
+//!
+//! # fn main() {
+//! let x = Complex { x: 1.2, i: 2.3 };
+//!
+//! assert_relative_eq!(x, x);
+//! assert_ulps_eq!(x, x, max_ulps = 4);
+//! # }
+//! ```
+//!
+//! To do this we can implement `AbsDiffEq`, `RelativeEq` and `UlpsEq` generically in terms of a
+//! type parameter that also implements `ApproxEq`, `RelativeEq` and `UlpsEq` respectively. This
+//! means that we can make comparisons for either `Complex<f32>` or `Complex<f64>`:
+//!
+//! ```rust
+//! # use approx::{AbsDiffEq, RelativeEq, UlpsEq};
+//! # #[derive(Debug, PartialEq)]
+//! # struct Complex<T> { x: T, i: T, }
+//! #
+//! impl<T: AbsDiffEq> AbsDiffEq for Complex<T> where
+//!     T::Epsilon: Copy,
+//! {
+//!     type Epsilon = T::Epsilon;
+//!
+//!     fn default_epsilon() -> T::Epsilon {
+//!         T::default_epsilon()
+//!     }
+//!
+//!     fn abs_diff_eq(&self, other: &Self, epsilon: T::Epsilon) -> bool {
+//!         T::abs_diff_eq(&self.x, &other.x, epsilon) &&
+//!         T::abs_diff_eq(&self.i, &other.i, epsilon)
+//!     }
+//! }
+//!
+//! impl<T: RelativeEq> RelativeEq for Complex<T> where
+//!     T::Epsilon: Copy,
+//! {
+//!     fn default_max_relative() -> T::Epsilon {
+//!         T::default_max_relative()
+//!     }
+//!
+//!     fn relative_eq(&self, other: &Self, epsilon: T::Epsilon, max_relative: T::Epsilon) -> bool {
+//!         T::relative_eq(&self.x, &other.x, epsilon, max_relative) &&
+//!         T::relative_eq(&self.i, &other.i, epsilon, max_relative)
+//!     }
+//! }
+//!
+//! impl<T: UlpsEq> UlpsEq for Complex<T> where
+//!     T::Epsilon: Copy,
+//! {
+//!     fn default_max_ulps() -> u32 {
+//!         T::default_max_ulps()
+//!     }
+//!
+//!     fn ulps_eq(&self, other: &Self, epsilon: T::Epsilon, max_ulps: u32) -> bool {
+//!         T::ulps_eq(&self.x, &other.x, epsilon, max_ulps) &&
+//!         T::ulps_eq(&self.i, &other.i, epsilon, max_ulps)
+//!     }
+//! }
+//! ```
+//!
+//! # References
+//!
+//! Floating point is hard! Thanks goes to these links for helping to make things a _little_
+//! easier to understand:
+//!
+//! - [Comparing Floating Point Numbers, 2012 Edition]
+//!   (https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/)
+//! - [The Floating Point Guide - Comparison](http://floating-point-gui.de/errors/comparison/)
+//! - [What Every Computer Scientist Should Know About Floating-Point Arithmetic]
+//!   (https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html)
+
+#![cfg_attr(not(feature = "std"), no_std)]
+
+#[cfg(feature = "num-complex")]
+extern crate num_complex;
+extern crate num_traits;
+
+#[cfg(not(feature = "std"))]
+use core as std;
+
+mod abs_diff_eq;
+mod relative_eq;
+mod ulps_eq;
+
+mod macros;
+
+pub use abs_diff_eq::AbsDiffEq;
+pub use relative_eq::RelativeEq;
+pub use ulps_eq::UlpsEq;
+
+/// The requisite parameters for testing for approximate equality using a
+/// absolute difference based comparison.
+///
+/// This is not normally used directly, rather via the
+/// `assert_abs_diff_{eq|ne}!` and `abs_diff_{eq|ne}!` macros.
+///
+/// # Example
+///
+/// ```rust
+/// use std::f64;
+/// use approx::AbsDiff;
+///
+/// AbsDiff::default().eq(&1.0, &1.0);
+/// AbsDiff::default().epsilon(f64::EPSILON).eq(&1.0, &1.0);
+/// ```
+pub struct AbsDiff<T: AbsDiffEq + ?Sized> {
+    /// The tolerance to use when testing values that are close together.
+    pub epsilon: T::Epsilon,
+}
+
+impl<T: AbsDiffEq + ?Sized> Default for AbsDiff<T> {
+    #[inline]
+    fn default() -> AbsDiff<T> {
+        AbsDiff {
+            epsilon: T::default_epsilon(),
+        }
+    }
+}
+
+impl<T> AbsDiff<T>
+where
+    T: AbsDiffEq + ?Sized,
+{
+    /// Replace the epsilon value with the one specified.
+    #[inline]
+    pub fn epsilon(self, epsilon: T::Epsilon) -> AbsDiff<T> {
+        AbsDiff { epsilon, ..self }
+    }
+
+    /// Peform the equality comparison
+    #[inline]
+    pub fn eq(self, lhs: &T, rhs: &T) -> bool {
+        T::abs_diff_eq(lhs, rhs, self.epsilon)
+    }
+
+    /// Peform the inequality comparison
+    #[inline]
+    pub fn ne(self, lhs: &T, rhs: &T) -> bool {
+        T::abs_diff_ne(lhs, rhs, self.epsilon)
+    }
+}
+
+/// The requisite parameters for testing for approximate equality using a
+/// relative based comparison.
+///
+/// This is not normally used directly, rather via the
+/// `assert_relative_{eq|ne}!` and `relative_{eq|ne}!` macros.
+///
+/// # Example
+///
+/// ```rust
+/// use std::f64;
+/// use approx::Relative;
+///
+/// Relative::default().eq(&1.0, &1.0);
+/// Relative::default().epsilon(f64::EPSILON).eq(&1.0, &1.0);
+/// Relative::default().max_relative(1.0).eq(&1.0, &1.0);
+/// Relative::default().epsilon(f64::EPSILON).max_relative(1.0).eq(&1.0, &1.0);
+/// Relative::default().max_relative(1.0).epsilon(f64::EPSILON).eq(&1.0, &1.0);
+/// ```
+pub struct Relative<T: RelativeEq + ?Sized> {
+    /// The tolerance to use when testing values that are close together.
+    pub epsilon: T::Epsilon,
+    /// The relative tolerance for testing values that are far-apart.
+    pub max_relative: T::Epsilon,
+}
+
+impl<T: RelativeEq + ?Sized> Default for Relative<T> {
+    #[inline]
+    fn default() -> Relative<T> {
+        Relative {
+            epsilon: T::default_epsilon(),
+            max_relative: T::default_max_relative(),
+        }
+    }
+}
+
+impl<T: RelativeEq + ?Sized> Relative<T> {
+    /// Replace the epsilon value with the one specified.
+    #[inline]
+    pub fn epsilon(self, epsilon: T::Epsilon) -> Relative<T> {
+        Relative { epsilon, ..self }
+    }
+
+    /// Replace the maximum relative value with the one specified.
+    #[inline]
+    pub fn max_relative(self, max_relative: T::Epsilon) -> Relative<T> {
+        Relative {
+            max_relative,
+            ..self
+        }
+    }
+
+    /// Peform the equality comparison
+    #[inline]
+    pub fn eq(self, lhs: &T, rhs: &T) -> bool {
+        T::relative_eq(lhs, rhs, self.epsilon, self.max_relative)
+    }
+
+    /// Peform the inequality comparison
+    #[inline]
+    pub fn ne(self, lhs: &T, rhs: &T) -> bool {
+        T::relative_ne(lhs, rhs, self.epsilon, self.max_relative)
+    }
+}
+
+/// The requisite parameters for testing for approximate equality using an ULPs
+/// based comparison.
+///
+/// This is not normally used directly, rather via the `assert_ulps_{eq|ne}!`
+/// and `ulps_{eq|ne}!` macros.
+///
+/// # Example
+///
+/// ```rust
+/// use std::f64;
+/// use approx::Ulps;
+///
+/// Ulps::default().eq(&1.0, &1.0);
+/// Ulps::default().epsilon(f64::EPSILON).eq(&1.0, &1.0);
+/// Ulps::default().max_ulps(4).eq(&1.0, &1.0);
+/// Ulps::default().epsilon(f64::EPSILON).max_ulps(4).eq(&1.0, &1.0);
+/// Ulps::default().max_ulps(4).epsilon(f64::EPSILON).eq(&1.0, &1.0);
+/// ```
+pub struct Ulps<T: UlpsEq + ?Sized> {
+    /// The tolerance to use when testing values that are close together.
+    pub epsilon: T::Epsilon,
+    /// The ULPs to tolerate when testing values that are far-apart.
+    pub max_ulps: u32,
+}
+
+impl<T: UlpsEq + ?Sized> Default for Ulps<T>
+where
+    T: UlpsEq,
+{
+    #[inline]
+    fn default() -> Ulps<T> {
+        Ulps {
+            epsilon: T::default_epsilon(),
+            max_ulps: T::default_max_ulps(),
+        }
+    }
+}
+
+impl<T: UlpsEq + ?Sized> Ulps<T> {
+    /// Replace the epsilon value with the one specified.
+    #[inline]
+    pub fn epsilon(self, epsilon: T::Epsilon) -> Ulps<T> {
+        Ulps { epsilon, ..self }
+    }
+
+    /// Replace the max ulps value with the one specified.
+    #[inline]
+    pub fn max_ulps(self, max_ulps: u32) -> Ulps<T> {
+        Ulps { max_ulps, ..self }
+    }
+
+    /// Peform the equality comparison
+    #[inline]
+    pub fn eq(self, lhs: &T, rhs: &T) -> bool {
+        T::ulps_eq(lhs, rhs, self.epsilon, self.max_ulps)
+    }
+
+    /// Peform the inequality comparison
+    #[inline]
+    pub fn ne(self, lhs: &T, rhs: &T) -> bool {
+        T::ulps_ne(lhs, rhs, self.epsilon, self.max_ulps)
+    }
+}
diff --git a/rustc_deps/vendor/approx/src/macros.rs b/rustc_deps/vendor/approx/src/macros.rs
new file mode 100644
index 0000000..bcd1fbf
--- /dev/null
+++ b/rustc_deps/vendor/approx/src/macros.rs
@@ -0,0 +1,187 @@
+// Copyright 2015 Brendan Zabarauskas
+//
+// 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.
+
+/// Approximate equality of using the absolute difference.
+#[macro_export]
+macro_rules! abs_diff_eq {
+    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*) => {
+        $crate::AbsDiff::default()$(.$opt($val))*.eq(&$lhs, &$rhs)
+    };
+    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*,) => {
+        $crate::AbsDiff::default()$(.$opt($val))*.eq(&$lhs, &$rhs)
+    };
+}
+
+/// Approximate inequality of using the absolute difference.
+#[macro_export]
+macro_rules! abs_diff_ne {
+    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*) => {
+        $crate::AbsDiff::default()$(.$opt($val))*.ne(&$lhs, &$rhs)
+    };
+    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*,) => {
+        $crate::AbsDiff::default()$(.$opt($val))*.ne(&$lhs, &$rhs)
+    };
+}
+
+/// Approximate equality using both the absolute difference and relative based comparisons.
+#[macro_export]
+macro_rules! relative_eq {
+    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*) => {
+        $crate::Relative::default()$(.$opt($val))*.eq(&$lhs, &$rhs)
+    };
+    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*,) => {
+        $crate::Relative::default()$(.$opt($val))*.eq(&$lhs, &$rhs)
+    };
+}
+
+/// Approximate inequality using both the absolute difference and relative based comparisons.
+#[macro_export]
+macro_rules! relative_ne {
+    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*) => {
+        $crate::Relative::default()$(.$opt($val))*.ne(&$lhs, &$rhs)
+    };
+    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*,) => {
+        $crate::Relative::default()$(.$opt($val))*.ne(&$lhs, &$rhs)
+    };
+}
+
+/// Approximate equality using both the absolute difference and ULPs (Units in Last Place).
+#[macro_export]
+macro_rules! ulps_eq {
+    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*) => {
+        $crate::Ulps::default()$(.$opt($val))*.eq(&$lhs, &$rhs)
+    };
+    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*,) => {
+        $crate::Ulps::default()$(.$opt($val))*.eq(&$lhs, &$rhs)
+    };
+}
+
+/// Approximate inequality using both the absolute difference and ULPs (Units in Last Place).
+#[macro_export]
+macro_rules! ulps_ne {
+    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*) => {
+        $crate::Ulps::default()$(.$opt($val))*.ne(&$lhs, &$rhs)
+    };
+    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*,) => {
+        $crate::Ulps::default()$(.$opt($val))*.ne(&$lhs, &$rhs)
+    };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __assert_approx {
+    ($eq:ident, $given:expr, $expected:expr) => {{
+        let (given, expected) = (&($given), &($expected));
+
+        if !$eq!(*given, *expected) {
+            panic!(
+"assert_{}!({}, {})
+
+    left  = {:?}
+    right = {:?}
+
+",
+                stringify!($eq),
+                stringify!($given),
+                stringify!($expected),
+                given, expected,
+            );
+        }
+    }};
+    ($eq:ident, $given:expr, $expected:expr, $($opt:ident = $val:expr),+) => {{
+        let (given, expected) = (&($given), &($expected));
+
+        if !$eq!(*given, *expected, $($opt = $val),+) {
+            panic!(
+"assert_{}!({}, {}, {})
+
+    left  = {:?}
+    right = {:?}
+
+",
+                stringify!($eq),
+                stringify!($given),
+                stringify!($expected),
+                stringify!($($opt = $val),+),
+                given, expected,
+            );
+        }
+    }};
+}
+
+/// An assertion that delegates to `abs_diff_eq!`, and panics with a helpful error on failure.
+#[macro_export]
+macro_rules! assert_abs_diff_eq {
+    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*) => {
+        __assert_approx!(abs_diff_eq, $given, $expected $(, $opt = $val)*)
+    };
+    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*,) => {
+        __assert_approx!(abs_diff_eq, $given, $expected $(, $opt = $val)*)
+    };
+}
+
+/// An assertion that delegates to `abs_diff_ne!`, and panics with a helpful error on failure.
+#[macro_export]
+macro_rules! assert_abs_diff_ne {
+    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*) => {
+        __assert_approx!(abs_diff_ne, $given, $expected $(, $opt = $val)*)
+    };
+    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*,) => {
+        __assert_approx!(abs_diff_ne, $given, $expected $(, $opt = $val)*)
+    };
+}
+
+/// An assertion that delegates to `relative_eq!`, and panics with a helpful error on failure.
+#[macro_export]
+macro_rules! assert_relative_eq {
+    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*) => {
+        __assert_approx!(relative_eq, $given, $expected $(, $opt = $val)*)
+    };
+    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*,) => {
+        __assert_approx!(relative_eq, $given, $expected $(, $opt = $val)*)
+    };
+}
+
+/// An assertion that delegates to `relative_ne!`, and panics with a helpful error on failure.
+#[macro_export]
+macro_rules! assert_relative_ne {
+    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*) => {
+        __assert_approx!(relative_ne, $given, $expected $(, $opt = $val)*)
+    };
+    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*,) => {
+        __assert_approx!(relative_ne, $given, $expected $(, $opt = $val)*)
+    };
+}
+
+/// An assertion that delegates to `ulps_eq!`, and panics with a helpful error on failure.
+#[macro_export]
+macro_rules! assert_ulps_eq {
+    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*) => {
+        __assert_approx!(ulps_eq, $given, $expected $(, $opt = $val)*)
+    };
+    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*,) => {
+        __assert_approx!(ulps_eq, $given, $expected $(, $opt = $val)*)
+    };
+}
+
+/// An assertion that delegates to `ulps_ne!`, and panics with a helpful error on failure.
+#[macro_export]
+macro_rules! assert_ulps_ne {
+    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*) => {
+        __assert_approx!(ulps_ne, $given, $expected $(, $opt = $val)*)
+    };
+    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*,) => {
+        __assert_approx!(ulps_ne, $given, $expected $(, $opt = $val)*)
+    };
+}
diff --git a/rustc_deps/vendor/approx/src/relative_eq.rs b/rustc_deps/vendor/approx/src/relative_eq.rs
new file mode 100644
index 0000000..52c1333
--- /dev/null
+++ b/rustc_deps/vendor/approx/src/relative_eq.rs
@@ -0,0 +1,192 @@
+#[cfg(feature = "num-complex")]
+use num_complex::Complex;
+#[cfg(not(feature = "std"))]
+use num_traits::float::FloatCore;
+use std::{cell, f32, f64};
+
+use AbsDiffEq;
+
+/// Equality comparisons between two numbers using both the absolute difference and
+/// relative based comparisons.
+pub trait RelativeEq: AbsDiffEq {
+    /// The default relative tolerance for testing values that are far-apart.
+    ///
+    /// This is used when no `max_relative` value is supplied to the `relative_eq` macro.
+    fn default_max_relative() -> Self::Epsilon;
+
+    /// A test for equality that uses a relative comparison if the values are far apart.
+    fn relative_eq(
+        &self,
+        other: &Self,
+        epsilon: Self::Epsilon,
+        max_relative: Self::Epsilon,
+    ) -> bool;
+
+    /// The inverse of `ApproxEq::relative_eq`.
+    fn relative_ne(
+        &self,
+        other: &Self,
+        epsilon: Self::Epsilon,
+        max_relative: Self::Epsilon,
+    ) -> bool {
+        !Self::relative_eq(self, other, epsilon, max_relative)
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Base implementations
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+// Implementation based on: [Comparing Floating Point Numbers, 2012 Edition]
+// (https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/)
+macro_rules! impl_relative_eq {
+    ($T:ident, $U:ident) => {
+        impl RelativeEq for $T {
+            #[inline]
+            fn default_max_relative() -> $T {
+                $T::EPSILON
+            }
+
+            #[inline]
+            fn relative_eq(&self, other: &$T, epsilon: $T, max_relative: $T) -> bool {
+                // Handle same infinities
+                if self == other {
+                    return true;
+                }
+
+                // Handle remaining infinities
+                if $T::is_infinite(*self) || $T::is_infinite(*other) {
+                    return false;
+                }
+
+                let abs_diff = $T::abs(self - other);
+
+                // For when the numbers are really close together
+                if abs_diff <= epsilon {
+                    return true;
+                }
+
+                let abs_self = $T::abs(*self);
+                let abs_other = $T::abs(*other);
+
+                let largest = if abs_other > abs_self {
+                    abs_other
+                } else {
+                    abs_self
+                };
+
+                // Use a relative difference comparison
+                abs_diff <= largest * max_relative
+            }
+        }
+    };
+}
+
+impl_relative_eq!(f32, i32);
+impl_relative_eq!(f64, i64);
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Derived implementations
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+impl<'a, T: RelativeEq + ?Sized> RelativeEq for &'a T {
+    #[inline]
+    fn default_max_relative() -> T::Epsilon {
+        T::default_max_relative()
+    }
+
+    #[inline]
+    fn relative_eq(&self, other: &&'a T, epsilon: T::Epsilon, max_relative: T::Epsilon) -> bool {
+        T::relative_eq(*self, *other, epsilon, max_relative)
+    }
+}
+
+impl<'a, T: RelativeEq + ?Sized> RelativeEq for &'a mut T {
+    #[inline]
+    fn default_max_relative() -> T::Epsilon {
+        T::default_max_relative()
+    }
+
+    #[inline]
+    fn relative_eq(
+        &self,
+        other: &&'a mut T,
+        epsilon: T::Epsilon,
+        max_relative: T::Epsilon,
+    ) -> bool {
+        T::relative_eq(*self, *other, epsilon, max_relative)
+    }
+}
+
+impl<T: RelativeEq + Copy> RelativeEq for cell::Cell<T> {
+    #[inline]
+    fn default_max_relative() -> T::Epsilon {
+        T::default_max_relative()
+    }
+
+    #[inline]
+    fn relative_eq(
+        &self,
+        other: &cell::Cell<T>,
+        epsilon: T::Epsilon,
+        max_relative: T::Epsilon,
+    ) -> bool {
+        T::relative_eq(&self.get(), &other.get(), epsilon, max_relative)
+    }
+}
+
+impl<T: RelativeEq + ?Sized> RelativeEq for cell::RefCell<T> {
+    #[inline]
+    fn default_max_relative() -> T::Epsilon {
+        T::default_max_relative()
+    }
+
+    #[inline]
+    fn relative_eq(
+        &self,
+        other: &cell::RefCell<T>,
+        epsilon: T::Epsilon,
+        max_relative: T::Epsilon,
+    ) -> bool {
+        T::relative_eq(&self.borrow(), &other.borrow(), epsilon, max_relative)
+    }
+}
+
+impl<T: RelativeEq> RelativeEq for [T]
+where
+    T::Epsilon: Clone,
+{
+    #[inline]
+    fn default_max_relative() -> T::Epsilon {
+        T::default_max_relative()
+    }
+
+    #[inline]
+    fn relative_eq(&self, other: &[T], epsilon: T::Epsilon, max_relative: T::Epsilon) -> bool {
+        self.len() == other.len()
+            && Iterator::zip(self.iter(), other)
+                .all(|(x, y)| T::relative_eq(x, y, epsilon.clone(), max_relative.clone()))
+    }
+}
+
+#[cfg(feature = "num-complex")]
+impl<T: RelativeEq> RelativeEq for Complex<T>
+where
+    T::Epsilon: Clone,
+{
+    #[inline]
+    fn default_max_relative() -> T::Epsilon {
+        T::default_max_relative()
+    }
+
+    #[inline]
+    fn relative_eq(
+        &self,
+        other: &Complex<T>,
+        epsilon: T::Epsilon,
+        max_relative: T::Epsilon,
+    ) -> bool {
+        T::relative_eq(&self.re, &other.re, epsilon.clone(), max_relative.clone())
+            && T::relative_eq(&self.im, &other.im, epsilon.clone(), max_relative.clone())
+    }
+}
diff --git a/rustc_deps/vendor/approx/src/ulps_eq.rs b/rustc_deps/vendor/approx/src/ulps_eq.rs
new file mode 100644
index 0000000..132abff
--- /dev/null
+++ b/rustc_deps/vendor/approx/src/ulps_eq.rs
@@ -0,0 +1,149 @@
+#[cfg(feature = "num-complex")]
+use num_complex::Complex;
+#[cfg(not(feature = "std"))]
+use num_traits::float::FloatCore;
+use std::{cell, mem};
+
+use AbsDiffEq;
+
+/// Equality comparisons between two numbers using both the absolute difference and ULPs
+/// (Units in Last Place) based comparisons.
+pub trait UlpsEq: AbsDiffEq {
+    /// The default ULPs to tolerate when testing values that are far-apart.
+    ///
+    /// This is used when no `max_ulps` value is supplied to the `ulps_eq` macro.
+    fn default_max_ulps() -> u32;
+
+    /// A test for equality that uses units in the last place (ULP) if the values are far apart.
+    fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool;
+
+    /// The inverse of `ApproxEq::ulps_eq`.
+    fn ulps_ne(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
+        !Self::ulps_eq(self, other, epsilon, max_ulps)
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Base implementations
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+// Implementation based on: [Comparing Floating Point Numbers, 2012 Edition]
+// (https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/)
+macro_rules! impl_ulps_eq {
+    ($T:ident, $U:ident) => {
+        impl UlpsEq for $T {
+            #[inline]
+            fn default_max_ulps() -> u32 {
+                4
+            }
+
+            #[inline]
+            fn ulps_eq(&self, other: &$T, epsilon: $T, max_ulps: u32) -> bool {
+                // For when the numbers are really close together
+                if $T::abs_diff_eq(self, other, epsilon) {
+                    return true;
+                }
+
+                // Trivial negative sign check
+                if self.signum() != other.signum() {
+                    return false;
+                }
+
+                // ULPS difference comparison
+                let int_self: $U = unsafe { mem::transmute(*self) };
+                let int_other: $U = unsafe { mem::transmute(*other) };
+
+                $U::abs(int_self - int_other) <= max_ulps as $U
+            }
+        }
+    };
+}
+
+impl_ulps_eq!(f32, i32);
+impl_ulps_eq!(f64, i64);
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Derived implementations
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+impl<'a, T: UlpsEq + ?Sized> UlpsEq for &'a T {
+    #[inline]
+    fn default_max_ulps() -> u32 {
+        T::default_max_ulps()
+    }
+
+    #[inline]
+    fn ulps_eq(&self, other: &&'a T, epsilon: T::Epsilon, max_ulps: u32) -> bool {
+        T::ulps_eq(*self, *other, epsilon, max_ulps)
+    }
+}
+
+impl<'a, T: UlpsEq + ?Sized> UlpsEq for &'a mut T {
+    #[inline]
+    fn default_max_ulps() -> u32 {
+        T::default_max_ulps()
+    }
+
+    #[inline]
+    fn ulps_eq(&self, other: &&'a mut T, epsilon: T::Epsilon, max_ulps: u32) -> bool {
+        T::ulps_eq(*self, *other, epsilon, max_ulps)
+    }
+}
+
+impl<T: UlpsEq + Copy> UlpsEq for cell::Cell<T> {
+    #[inline]
+    fn default_max_ulps() -> u32 {
+        T::default_max_ulps()
+    }
+
+    #[inline]
+    fn ulps_eq(&self, other: &cell::Cell<T>, epsilon: T::Epsilon, max_ulps: u32) -> bool {
+        T::ulps_eq(&self.get(), &other.get(), epsilon, max_ulps)
+    }
+}
+
+impl<T: UlpsEq + ?Sized> UlpsEq for cell::RefCell<T> {
+    #[inline]
+    fn default_max_ulps() -> u32 {
+        T::default_max_ulps()
+    }
+
+    #[inline]
+    fn ulps_eq(&self, other: &cell::RefCell<T>, epsilon: T::Epsilon, max_ulps: u32) -> bool {
+        T::ulps_eq(&self.borrow(), &other.borrow(), epsilon, max_ulps)
+    }
+}
+
+impl<T: UlpsEq> UlpsEq for [T]
+where
+    T::Epsilon: Clone,
+{
+    #[inline]
+    fn default_max_ulps() -> u32 {
+        T::default_max_ulps()
+    }
+
+    #[inline]
+    fn ulps_eq(&self, other: &[T], epsilon: T::Epsilon, max_ulps: u32) -> bool {
+        self.len() == other.len()
+            && Iterator::zip(self.iter(), other)
+                .all(|(x, y)| T::ulps_eq(x, y, epsilon.clone(), max_ulps.clone()))
+    }
+}
+
+#[cfg(feature = "num-complex")]
+impl<T: UlpsEq> UlpsEq for Complex<T>
+where
+    T::Epsilon: Clone,
+{
+    #[inline]
+    fn default_max_ulps() -> u32 {
+        T::default_max_ulps()
+    }
+
+    #[inline]
+    fn ulps_eq(&self, other: &Complex<T>, epsilon: T::Epsilon, max_ulps: u32) -> bool {
+        T::ulps_eq(&self.re, &other.re, epsilon.clone(), max_ulps)
+            && T::ulps_eq(&self.im, &other.im, epsilon.clone(), max_ulps)
+    }
+}
diff --git a/rustc_deps/vendor/approx/tests/abs_diff_eq.rs b/rustc_deps/vendor/approx/tests/abs_diff_eq.rs
new file mode 100644
index 0000000..defe599
--- /dev/null
+++ b/rustc_deps/vendor/approx/tests/abs_diff_eq.rs
@@ -0,0 +1,442 @@
+// Copyright 2015 Brendan Zabarauskas
+//
+// 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.
+
+// Test cases derived from:
+// https://github.com/Pybonacci/puntoflotante.org/blob/master/content/errors/NearlyEqualsTest.java
+
+#[macro_use]
+extern crate approx;
+
+mod test_f32 {
+    use std::f32;
+
+    #[test]
+    fn test_basic() {
+        assert_abs_diff_eq!(1.0f32, 1.0f32);
+        assert_abs_diff_ne!(1.0f32, 2.0f32);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_basic_panic_eq() {
+        assert_abs_diff_eq!(1.0f32, 2.0f32);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_basic_panic_ne() {
+        assert_abs_diff_ne!(1.0f32, 1.0f32);
+    }
+
+    #[test]
+    fn test_big() {
+        assert_abs_diff_eq!(100000000.0f32, 100000001.0f32);
+        assert_abs_diff_eq!(100000001.0f32, 100000000.0f32);
+        assert_abs_diff_ne!(10000.0f32, 10001.0f32);
+        assert_abs_diff_ne!(10001.0f32, 10000.0f32);
+    }
+
+    #[test]
+    fn test_big_neg() {
+        assert_abs_diff_eq!(-100000000.0f32, -100000001.0f32);
+        assert_abs_diff_eq!(-100000001.0f32, -100000000.0f32);
+        assert_abs_diff_ne!(-10000.0f32, -10001.0f32);
+        assert_abs_diff_ne!(-10001.0f32, -10000.0f32);
+    }
+
+    #[test]
+    fn test_mid() {
+        assert_abs_diff_eq!(1.0000001f32, 1.0000002f32);
+        assert_abs_diff_eq!(1.0000002f32, 1.0000001f32);
+        assert_abs_diff_ne!(1.000001f32, 1.000002f32);
+        assert_abs_diff_ne!(1.000002f32, 1.000001f32);
+    }
+
+    #[test]
+    fn test_mid_neg() {
+        assert_abs_diff_eq!(-1.0000001f32, -1.0000002f32);
+        assert_abs_diff_eq!(-1.0000002f32, -1.0000001f32);
+        assert_abs_diff_ne!(-1.000001f32, -1.000002f32);
+        assert_abs_diff_ne!(-1.000002f32, -1.000001f32);
+    }
+
+    #[test]
+    fn test_small() {
+        assert_abs_diff_eq!(0.000010001f32, 0.000010002f32);
+        assert_abs_diff_eq!(0.000010002f32, 0.000010001f32);
+        assert_abs_diff_ne!(0.000001002f32, 0.0000001001f32);
+        assert_abs_diff_ne!(0.000001001f32, 0.0000001002f32);
+    }
+
+    #[test]
+    fn test_small_neg() {
+        assert_abs_diff_eq!(-0.000010001f32, -0.000010002f32);
+        assert_abs_diff_eq!(-0.000010002f32, -0.000010001f32);
+        assert_abs_diff_ne!(-0.000001002f32, -0.0000001001f32);
+        assert_abs_diff_ne!(-0.000001001f32, -0.0000001002f32);
+    }
+
+    #[test]
+    fn test_zero() {
+        assert_abs_diff_eq!(0.0f32, 0.0f32);
+        assert_abs_diff_eq!(0.0f32, -0.0f32);
+        assert_abs_diff_eq!(-0.0f32, -0.0f32);
+
+        assert_abs_diff_ne!(0.000001f32, 0.0f32);
+        assert_abs_diff_ne!(0.0f32, 0.000001f32);
+        assert_abs_diff_ne!(-0.000001f32, 0.0f32);
+        assert_abs_diff_ne!(0.0f32, -0.000001f32);
+    }
+
+    #[test]
+    fn test_epsilon() {
+        assert_abs_diff_eq!(0.0f32, 1e-40f32, epsilon = 1e-40f32);
+        assert_abs_diff_eq!(1e-40f32, 0.0f32, epsilon = 1e-40f32);
+        assert_abs_diff_eq!(0.0f32, -1e-40f32, epsilon = 1e-40f32);
+        assert_abs_diff_eq!(-1e-40f32, 0.0f32, epsilon = 1e-40f32);
+
+        assert_abs_diff_ne!(1e-40f32, 0.0f32, epsilon = 1e-41f32);
+        assert_abs_diff_ne!(0.0f32, 1e-40f32, epsilon = 1e-41f32);
+        assert_abs_diff_ne!(-1e-40f32, 0.0f32, epsilon = 1e-41f32);
+        assert_abs_diff_ne!(0.0f32, -1e-40f32, epsilon = 1e-41f32);
+    }
+
+    #[test]
+    fn test_max() {
+        assert_abs_diff_eq!(f32::MAX, f32::MAX);
+        assert_abs_diff_ne!(f32::MAX, -f32::MAX);
+        assert_abs_diff_ne!(-f32::MAX, f32::MAX);
+        assert_abs_diff_ne!(f32::MAX, f32::MAX / 2.0);
+        assert_abs_diff_ne!(f32::MAX, -f32::MAX / 2.0);
+        assert_abs_diff_ne!(-f32::MAX, f32::MAX / 2.0);
+    }
+
+    // NOTE: abs_diff_eq fails as numbers begin to get very large
+
+    // #[test]
+    // fn test_infinity() {
+    //     assert_abs_diff_eq!(f32::INFINITY, f32::INFINITY);
+    //     assert_abs_diff_eq!(f32::NEG_INFINITY, f32::NEG_INFINITY);
+    //     assert_abs_diff_ne!(f32::NEG_INFINITY, f32::INFINITY);
+    //     assert_abs_diff_eq!(f32::INFINITY, f32::MAX);
+    //     assert_abs_diff_eq!(f32::NEG_INFINITY, -f32::MAX);
+    // }
+
+    #[test]
+    fn test_nan() {
+        assert_abs_diff_ne!(f32::NAN, f32::NAN);
+
+        assert_abs_diff_ne!(f32::NAN, 0.0);
+        assert_abs_diff_ne!(-0.0, f32::NAN);
+        assert_abs_diff_ne!(f32::NAN, -0.0);
+        assert_abs_diff_ne!(0.0, f32::NAN);
+
+        assert_abs_diff_ne!(f32::NAN, f32::INFINITY);
+        assert_abs_diff_ne!(f32::INFINITY, f32::NAN);
+        assert_abs_diff_ne!(f32::NAN, f32::NEG_INFINITY);
+        assert_abs_diff_ne!(f32::NEG_INFINITY, f32::NAN);
+
+        assert_abs_diff_ne!(f32::NAN, f32::MAX);
+        assert_abs_diff_ne!(f32::MAX, f32::NAN);
+        assert_abs_diff_ne!(f32::NAN, -f32::MAX);
+        assert_abs_diff_ne!(-f32::MAX, f32::NAN);
+
+        assert_abs_diff_ne!(f32::NAN, f32::MIN_POSITIVE);
+        assert_abs_diff_ne!(f32::MIN_POSITIVE, f32::NAN);
+        assert_abs_diff_ne!(f32::NAN, -f32::MIN_POSITIVE);
+        assert_abs_diff_ne!(-f32::MIN_POSITIVE, f32::NAN);
+    }
+
+    #[test]
+    fn test_opposite_signs() {
+        assert_abs_diff_ne!(1.000000001f32, -1.0f32);
+        assert_abs_diff_ne!(-1.0f32, 1.000000001f32);
+        assert_abs_diff_ne!(-1.000000001f32, 1.0f32);
+        assert_abs_diff_ne!(1.0f32, -1.000000001f32);
+
+        assert_abs_diff_eq!(10.0 * f32::MIN_POSITIVE, 10.0 * -f32::MIN_POSITIVE);
+    }
+
+    #[test]
+    fn test_close_to_zero() {
+        assert_abs_diff_eq!(f32::MIN_POSITIVE, f32::MIN_POSITIVE);
+        assert_abs_diff_eq!(f32::MIN_POSITIVE, -f32::MIN_POSITIVE);
+        assert_abs_diff_eq!(-f32::MIN_POSITIVE, f32::MIN_POSITIVE);
+
+        assert_abs_diff_eq!(f32::MIN_POSITIVE, 0.0f32);
+        assert_abs_diff_eq!(0.0f32, f32::MIN_POSITIVE);
+        assert_abs_diff_eq!(-f32::MIN_POSITIVE, 0.0f32);
+        assert_abs_diff_eq!(0.0f32, -f32::MIN_POSITIVE);
+
+        assert_abs_diff_ne!(0.000001f32, -f32::MIN_POSITIVE);
+        assert_abs_diff_ne!(0.000001f32, f32::MIN_POSITIVE);
+        assert_abs_diff_ne!(f32::MIN_POSITIVE, 0.000001f32);
+        assert_abs_diff_ne!(-f32::MIN_POSITIVE, 0.000001f32);
+    }
+}
+
+#[cfg(test)]
+mod test_f64 {
+    use std::f64;
+
+    #[test]
+    fn test_basic() {
+        assert_abs_diff_eq!(1.0f64, 1.0f64);
+        assert_abs_diff_ne!(1.0f64, 2.0f64);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_basic_panic_eq() {
+        assert_abs_diff_eq!(1.0f64, 2.0f64);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_basic_panic_ne() {
+        assert_abs_diff_ne!(1.0f64, 1.0f64);
+    }
+
+    #[test]
+    fn test_big() {
+        assert_abs_diff_eq!(10000000000000000.0f64, 10000000000000001.0f64);
+        assert_abs_diff_eq!(10000000000000001.0f64, 10000000000000000.0f64);
+        assert_abs_diff_ne!(1000000000000000.0f64, 1000000000000001.0f64);
+        assert_abs_diff_ne!(1000000000000001.0f64, 1000000000000000.0f64);
+    }
+
+    #[test]
+    fn test_big_neg() {
+        assert_abs_diff_eq!(-10000000000000000.0f64, -10000000000000001.0f64);
+        assert_abs_diff_eq!(-10000000000000001.0f64, -10000000000000000.0f64);
+        assert_abs_diff_ne!(-1000000000000000.0f64, -1000000000000001.0f64);
+        assert_abs_diff_ne!(-1000000000000001.0f64, -1000000000000000.0f64);
+    }
+
+    #[test]
+    fn test_mid() {
+        assert_abs_diff_eq!(1.0000000000000001f64, 1.0000000000000002f64);
+        assert_abs_diff_eq!(1.0000000000000002f64, 1.0000000000000001f64);
+        assert_abs_diff_ne!(1.000000000000001f64, 1.000000000000002f64);
+        assert_abs_diff_ne!(1.000000000000002f64, 1.000000000000001f64);
+    }
+
+    #[test]
+    fn test_mid_neg() {
+        assert_abs_diff_eq!(-1.0000000000000001f64, -1.0000000000000002f64);
+        assert_abs_diff_eq!(-1.0000000000000002f64, -1.0000000000000001f64);
+        assert_abs_diff_ne!(-1.000000000000001f64, -1.000000000000002f64);
+        assert_abs_diff_ne!(-1.000000000000002f64, -1.000000000000001f64);
+    }
+
+    #[test]
+    fn test_small() {
+        assert_abs_diff_eq!(0.0000000100000001f64, 0.0000000100000002f64);
+        assert_abs_diff_eq!(0.0000000100000002f64, 0.0000000100000001f64);
+        assert_abs_diff_ne!(0.0000000100000001f64, 0.0000000010000002f64);
+        assert_abs_diff_ne!(0.0000000100000002f64, 0.0000000010000001f64);
+    }
+
+    #[test]
+    fn test_small_neg() {
+        assert_abs_diff_eq!(-0.0000000100000001f64, -0.0000000100000002f64);
+        assert_abs_diff_eq!(-0.0000000100000002f64, -0.0000000100000001f64);
+        assert_abs_diff_ne!(-0.0000000100000001f64, -0.0000000010000002f64);
+        assert_abs_diff_ne!(-0.0000000100000002f64, -0.0000000010000001f64);
+    }
+
+    #[test]
+    fn test_zero() {
+        assert_abs_diff_eq!(0.0f64, 0.0f64);
+        assert_abs_diff_eq!(0.0f64, -0.0f64);
+        assert_abs_diff_eq!(-0.0f64, -0.0f64);
+
+        assert_abs_diff_ne!(0.000000000000001f64, 0.0f64);
+        assert_abs_diff_ne!(0.0f64, 0.000000000000001f64);
+        assert_abs_diff_ne!(-0.000000000000001f64, 0.0f64);
+        assert_abs_diff_ne!(0.0f64, -0.000000000000001f64);
+    }
+
+    #[test]
+    fn test_epsilon() {
+        assert_abs_diff_eq!(0.0f64, 1e-40f64, epsilon = 1e-40f64);
+        assert_abs_diff_eq!(1e-40f64, 0.0f64, epsilon = 1e-40f64);
+        assert_abs_diff_eq!(0.0f64, -1e-40f64, epsilon = 1e-40f64);
+        assert_abs_diff_eq!(-1e-40f64, 0.0f64, epsilon = 1e-40f64);
+
+        assert_abs_diff_ne!(1e-40f64, 0.0f64, epsilon = 1e-41f64);
+        assert_abs_diff_ne!(0.0f64, 1e-40f64, epsilon = 1e-41f64);
+        assert_abs_diff_ne!(-1e-40f64, 0.0f64, epsilon = 1e-41f64);
+        assert_abs_diff_ne!(0.0f64, -1e-40f64, epsilon = 1e-41f64);
+    }
+
+    #[test]
+    fn test_max() {
+        assert_abs_diff_eq!(f64::MAX, f64::MAX);
+        assert_abs_diff_ne!(f64::MAX, -f64::MAX);
+        assert_abs_diff_ne!(-f64::MAX, f64::MAX);
+        assert_abs_diff_ne!(f64::MAX, f64::MAX / 2.0);
+        assert_abs_diff_ne!(f64::MAX, -f64::MAX / 2.0);
+        assert_abs_diff_ne!(-f64::MAX, f64::MAX / 2.0);
+    }
+
+    // NOTE: abs_diff_eq fails as numbers begin to get very large
+
+    // #[test]
+    // fn test_infinity() {
+    //     assert_abs_diff_eq!(f64::INFINITY, f64::INFINITY);
+    //     assert_abs_diff_eq!(f64::NEG_INFINITY, f64::NEG_INFINITY);
+    //     assert_abs_diff_ne!(f64::NEG_INFINITY, f64::INFINITY);
+    //     assert_abs_diff_eq!(f64::INFINITY, f64::MAX);
+    //     assert_abs_diff_eq!(f64::NEG_INFINITY, -f64::MAX);
+    // }
+
+    #[test]
+    fn test_nan() {
+        assert_abs_diff_ne!(f64::NAN, f64::NAN);
+
+        assert_abs_diff_ne!(f64::NAN, 0.0);
+        assert_abs_diff_ne!(-0.0, f64::NAN);
+        assert_abs_diff_ne!(f64::NAN, -0.0);
+        assert_abs_diff_ne!(0.0, f64::NAN);
+
+        assert_abs_diff_ne!(f64::NAN, f64::INFINITY);
+        assert_abs_diff_ne!(f64::INFINITY, f64::NAN);
+        assert_abs_diff_ne!(f64::NAN, f64::NEG_INFINITY);
+        assert_abs_diff_ne!(f64::NEG_INFINITY, f64::NAN);
+
+        assert_abs_diff_ne!(f64::NAN, f64::MAX);
+        assert_abs_diff_ne!(f64::MAX, f64::NAN);
+        assert_abs_diff_ne!(f64::NAN, -f64::MAX);
+        assert_abs_diff_ne!(-f64::MAX, f64::NAN);
+
+        assert_abs_diff_ne!(f64::NAN, f64::MIN_POSITIVE);
+        assert_abs_diff_ne!(f64::MIN_POSITIVE, f64::NAN);
+        assert_abs_diff_ne!(f64::NAN, -f64::MIN_POSITIVE);
+        assert_abs_diff_ne!(-f64::MIN_POSITIVE, f64::NAN);
+    }
+
+    #[test]
+    fn test_opposite_signs() {
+        assert_abs_diff_ne!(1.000000001f64, -1.0f64);
+        assert_abs_diff_ne!(-1.0f64, 1.000000001f64);
+        assert_abs_diff_ne!(-1.000000001f64, 1.0f64);
+        assert_abs_diff_ne!(1.0f64, -1.000000001f64);
+
+        assert_abs_diff_eq!(10.0 * f64::MIN_POSITIVE, 10.0 * -f64::MIN_POSITIVE);
+    }
+
+    #[test]
+    fn test_close_to_zero() {
+        assert_abs_diff_eq!(f64::MIN_POSITIVE, f64::MIN_POSITIVE);
+        assert_abs_diff_eq!(f64::MIN_POSITIVE, -f64::MIN_POSITIVE);
+        assert_abs_diff_eq!(-f64::MIN_POSITIVE, f64::MIN_POSITIVE);
+
+        assert_abs_diff_eq!(f64::MIN_POSITIVE, 0.0f64);
+        assert_abs_diff_eq!(0.0f64, f64::MIN_POSITIVE);
+        assert_abs_diff_eq!(-f64::MIN_POSITIVE, 0.0f64);
+        assert_abs_diff_eq!(0.0f64, -f64::MIN_POSITIVE);
+
+        assert_abs_diff_ne!(0.000000000000001f64, -f64::MIN_POSITIVE);
+        assert_abs_diff_ne!(0.000000000000001f64, f64::MIN_POSITIVE);
+        assert_abs_diff_ne!(f64::MIN_POSITIVE, 0.000000000000001f64);
+        assert_abs_diff_ne!(-f64::MIN_POSITIVE, 0.000000000000001f64);
+    }
+}
+
+mod test_ref {
+    mod test_f32 {
+        #[test]
+        fn test_basic() {
+            assert_abs_diff_eq!(&1.0f32, &1.0f32);
+            assert_abs_diff_ne!(&1.0f32, &2.0f32);
+        }
+    }
+
+    mod test_f64 {
+        #[test]
+        fn test_basic() {
+            assert_abs_diff_eq!(&1.0f64, &1.0f64);
+            assert_abs_diff_ne!(&1.0f64, &2.0f64);
+        }
+    }
+}
+
+mod test_slice {
+    mod test_f32 {
+        #[test]
+        fn test_basic() {
+            assert_abs_diff_eq!([1.0f32, 2.0f32][..], [1.0f32, 2.0f32][..]);
+            assert_abs_diff_ne!([1.0f32, 2.0f32][..], [2.0f32, 1.0f32][..]);
+        }
+    }
+
+    mod test_f64 {
+        #[test]
+        fn test_basic() {
+            assert_abs_diff_eq!([1.0f64, 2.0f64][..], [1.0f64, 2.0f64][..]);
+            assert_abs_diff_ne!([1.0f64, 2.0f64][..], [2.0f64, 1.0f64][..]);
+        }
+    }
+}
+
+#[cfg(feature = "num-complex")]
+mod test_complex {
+    extern crate num_complex;
+    pub use self::num_complex::Complex;
+
+    mod test_f32 {
+        use super::Complex;
+
+        #[test]
+        fn test_basic() {
+            assert_abs_diff_eq!(Complex::new(1.0f32, 2.0f32), Complex::new(1.0f32, 2.0f32));
+            assert_abs_diff_ne!(Complex::new(1.0f32, 2.0f32), Complex::new(2.0f32, 1.0f32));
+        }
+
+        #[test]
+        #[should_panic]
+        fn test_basic_panic_eq() {
+            assert_abs_diff_eq!(Complex::new(1.0f32, 2.0f32), Complex::new(2.0f32, 1.0f32));
+        }
+
+        #[test]
+        #[should_panic]
+        fn test_basic_panic_ne() {
+            assert_abs_diff_ne!(Complex::new(1.0f32, 2.0f32), Complex::new(1.0f32, 2.0f32));
+        }
+    }
+
+    mod test_f64 {
+        use super::Complex;
+
+        #[test]
+        fn test_basic() {
+            assert_abs_diff_eq!(Complex::new(1.0f64, 2.0f64), Complex::new(1.0f64, 2.0f64));
+            assert_abs_diff_ne!(Complex::new(1.0f64, 2.0f64), Complex::new(2.0f64, 1.0f64));
+        }
+
+        #[test]
+        #[should_panic]
+        fn test_basic_panic_eq() {
+            assert_abs_diff_eq!(Complex::new(1.0f64, 2.0f64), Complex::new(2.0f64, 1.0f64));
+        }
+
+        #[test]
+        #[should_panic]
+        fn test_basic_panic_ne() {
+            assert_abs_diff_ne!(Complex::new(1.0f64, 2.0f64), Complex::new(1.0f64, 2.0f64));
+        }
+    }
+}
diff --git a/rustc_deps/vendor/approx/tests/macros.rs b/rustc_deps/vendor/approx/tests/macros.rs
new file mode 100644
index 0000000..865da16
--- /dev/null
+++ b/rustc_deps/vendor/approx/tests/macros.rs
@@ -0,0 +1,98 @@
+// Copyright 2015 Brendan Zabarauskas
+//
+// 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.
+
+//! Macro instantiation tests
+
+#[macro_use]
+extern crate approx;
+
+#[test]
+fn test_abs_diff_eq() {
+    let _: bool = abs_diff_eq!(1.0, 1.0);
+    let _: bool = abs_diff_eq!(1.0, 1.0, epsilon = 1.0);
+}
+
+#[test]
+fn test_abs_diff_eq_trailing_commas() {
+    let _: bool = abs_diff_eq!(1.0, 1.0,);
+    let _: bool = abs_diff_eq!(1.0, 1.0, epsilon = 1.0,);
+}
+
+#[test]
+fn test_abs_diff_ne() {
+    let _: bool = abs_diff_ne!(1.0, 1.0);
+    let _: bool = abs_diff_ne!(1.0, 1.0, epsilon = 1.0);
+}
+
+#[test]
+fn test_abs_diff_ne_trailing_commas() {
+    let _: bool = abs_diff_ne!(1.0, 1.0,);
+    let _: bool = abs_diff_ne!(1.0, 1.0, epsilon = 1.0,);
+}
+
+#[test]
+fn test_relative_eq() {
+    let _: bool = relative_eq!(1.0, 1.0);
+    let _: bool = relative_eq!(1.0, 1.0, epsilon = 1.0);
+    let _: bool = relative_eq!(1.0, 1.0, max_relative = 1.0);
+    let _: bool = relative_eq!(1.0, 1.0, epsilon = 1.0, max_relative = 1.0);
+}
+
+#[test]
+fn test_relative_eq_trailing_commas() {
+    let _: bool = relative_eq!(1.0, 1.0,);
+    let _: bool = relative_eq!(1.0, 1.0, epsilon = 1.0, max_relative = 1.0,);
+}
+
+#[test]
+fn test_relative_ne() {
+    let _: bool = relative_ne!(1.0, 1.0);
+    let _: bool = relative_ne!(1.0, 1.0, epsilon = 1.0);
+    let _: bool = relative_ne!(1.0, 1.0, max_relative = 1.0);
+    let _: bool = relative_ne!(1.0, 1.0, epsilon = 1.0, max_relative = 1.0);
+}
+
+#[test]
+fn test_relative_ne_trailing_commas() {
+    let _: bool = relative_ne!(1.0, 1.0,);
+    let _: bool = relative_ne!(1.0, 1.0, epsilon = 1.0, max_relative = 1.0,);
+}
+
+#[test]
+fn test_ulps_eq() {
+    let _: bool = ulps_eq!(1.0, 1.0);
+    let _: bool = ulps_eq!(1.0, 1.0, epsilon = 1.0);
+    let _: bool = ulps_eq!(1.0, 1.0, max_ulps = 1);
+    let _: bool = ulps_eq!(1.0, 1.0, epsilon = 1.0, max_ulps = 1);
+}
+
+#[test]
+fn test_ulps_eq_trailing_commas() {
+    let _: bool = ulps_eq!(1.0, 1.0,);
+    let _: bool = ulps_eq!(1.0, 1.0, epsilon = 1.0, max_ulps = 1,);
+}
+
+#[test]
+fn test_ulps_ne() {
+    let _: bool = ulps_ne!(1.0, 1.0);
+    let _: bool = ulps_ne!(1.0, 1.0, epsilon = 1.0);
+    let _: bool = ulps_ne!(1.0, 1.0, max_ulps = 1);
+    let _: bool = ulps_ne!(1.0, 1.0, epsilon = 1.0, max_ulps = 1);
+}
+
+#[test]
+fn test_ulps_ne_trailing_commas() {
+    let _: bool = ulps_ne!(1.0, 1.0,);
+    let _: bool = ulps_ne!(1.0, 1.0, epsilon = 1.0, max_ulps = 1,);
+}
diff --git a/rustc_deps/vendor/approx/tests/relative_eq.rs b/rustc_deps/vendor/approx/tests/relative_eq.rs
new file mode 100644
index 0000000..c44c19c
--- /dev/null
+++ b/rustc_deps/vendor/approx/tests/relative_eq.rs
@@ -0,0 +1,440 @@
+// Copyright 2015 Brendan Zabarauskas
+//
+// 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.
+
+// Test cases derived from:
+// https://github.com/Pybonacci/puntoflotante.org/blob/master/content/errors/NearlyEqualsTest.java
+
+#[macro_use]
+extern crate approx;
+
+mod test_f32 {
+    use std::f32;
+
+    #[test]
+    fn test_basic() {
+        assert_relative_eq!(1.0f32, 1.0f32);
+        assert_relative_ne!(1.0f32, 2.0f32);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_basic_panic_eq() {
+        assert_relative_eq!(1.0f32, 2.0f32);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_basic_panic_ne() {
+        assert_relative_ne!(1.0f32, 1.0f32);
+    }
+
+    #[test]
+    fn test_big() {
+        assert_relative_eq!(100000000.0f32, 100000001.0f32);
+        assert_relative_eq!(100000001.0f32, 100000000.0f32);
+        assert_relative_ne!(10000.0f32, 10001.0f32);
+        assert_relative_ne!(10001.0f32, 10000.0f32);
+    }
+
+    #[test]
+    fn test_big_neg() {
+        assert_relative_eq!(-100000000.0f32, -100000001.0f32);
+        assert_relative_eq!(-100000001.0f32, -100000000.0f32);
+        assert_relative_ne!(-10000.0f32, -10001.0f32);
+        assert_relative_ne!(-10001.0f32, -10000.0f32);
+    }
+
+    #[test]
+    fn test_mid() {
+        assert_relative_eq!(1.0000001f32, 1.0000002f32);
+        assert_relative_eq!(1.0000002f32, 1.0000001f32);
+        assert_relative_ne!(1.000001f32, 1.000002f32);
+        assert_relative_ne!(1.000002f32, 1.000001f32);
+    }
+
+    #[test]
+    fn test_mid_neg() {
+        assert_relative_eq!(-1.0000001f32, -1.0000002f32);
+        assert_relative_eq!(-1.0000002f32, -1.0000001f32);
+        assert_relative_ne!(-1.000001f32, -1.000002f32);
+        assert_relative_ne!(-1.000002f32, -1.000001f32);
+    }
+
+    #[test]
+    fn test_small() {
+        assert_relative_eq!(0.000010001f32, 0.000010002f32);
+        assert_relative_eq!(0.000010002f32, 0.000010001f32);
+        assert_relative_ne!(0.000001002f32, 0.0000001001f32);
+        assert_relative_ne!(0.000001001f32, 0.0000001002f32);
+    }
+
+    #[test]
+    fn test_small_neg() {
+        assert_relative_eq!(-0.000010001f32, -0.000010002f32);
+        assert_relative_eq!(-0.000010002f32, -0.000010001f32);
+        assert_relative_ne!(-0.000001002f32, -0.0000001001f32);
+        assert_relative_ne!(-0.000001001f32, -0.0000001002f32);
+    }
+
+    #[test]
+    fn test_zero() {
+        assert_relative_eq!(0.0f32, 0.0f32);
+        assert_relative_eq!(0.0f32, -0.0f32);
+        assert_relative_eq!(-0.0f32, -0.0f32);
+
+        assert_relative_ne!(0.000001f32, 0.0f32);
+        assert_relative_ne!(0.0f32, 0.000001f32);
+        assert_relative_ne!(-0.000001f32, 0.0f32);
+        assert_relative_ne!(0.0f32, -0.000001f32);
+    }
+
+    #[test]
+    fn test_epsilon() {
+        assert_relative_eq!(0.0f32, 1e-40f32, epsilon = 1e-40f32);
+        assert_relative_eq!(1e-40f32, 0.0f32, epsilon = 1e-40f32);
+        assert_relative_eq!(0.0f32, -1e-40f32, epsilon = 1e-40f32);
+        assert_relative_eq!(-1e-40f32, 0.0f32, epsilon = 1e-40f32);
+
+        assert_relative_ne!(1e-40f32, 0.0f32, epsilon = 1e-41f32);
+        assert_relative_ne!(0.0f32, 1e-40f32, epsilon = 1e-41f32);
+        assert_relative_ne!(-1e-40f32, 0.0f32, epsilon = 1e-41f32);
+        assert_relative_ne!(0.0f32, -1e-40f32, epsilon = 1e-41f32);
+    }
+
+    #[test]
+    fn test_max() {
+        assert_relative_eq!(f32::MAX, f32::MAX);
+        assert_relative_ne!(f32::MAX, -f32::MAX);
+        assert_relative_ne!(-f32::MAX, f32::MAX);
+        assert_relative_ne!(f32::MAX, f32::MAX / 2.0);
+        assert_relative_ne!(f32::MAX, -f32::MAX / 2.0);
+        assert_relative_ne!(-f32::MAX, f32::MAX / 2.0);
+    }
+
+    #[test]
+    fn test_infinity() {
+        assert_relative_eq!(f32::INFINITY, f32::INFINITY);
+        assert_relative_eq!(f32::NEG_INFINITY, f32::NEG_INFINITY);
+        assert_relative_ne!(f32::NEG_INFINITY, f32::INFINITY);
+    }
+
+    #[test]
+    fn test_zero_infinity() {
+        assert_relative_ne!(0f32, f32::INFINITY);
+        assert_relative_ne!(0f32, f32::NEG_INFINITY);
+    }
+
+    #[test]
+    fn test_nan() {
+        assert_relative_ne!(f32::NAN, f32::NAN);
+
+        assert_relative_ne!(f32::NAN, 0.0);
+        assert_relative_ne!(-0.0, f32::NAN);
+        assert_relative_ne!(f32::NAN, -0.0);
+        assert_relative_ne!(0.0, f32::NAN);
+
+        assert_relative_ne!(f32::NAN, f32::INFINITY);
+        assert_relative_ne!(f32::INFINITY, f32::NAN);
+        assert_relative_ne!(f32::NAN, f32::NEG_INFINITY);
+        assert_relative_ne!(f32::NEG_INFINITY, f32::NAN);
+
+        assert_relative_ne!(f32::NAN, f32::MAX);
+        assert_relative_ne!(f32::MAX, f32::NAN);
+        assert_relative_ne!(f32::NAN, -f32::MAX);
+        assert_relative_ne!(-f32::MAX, f32::NAN);
+
+        assert_relative_ne!(f32::NAN, f32::MIN_POSITIVE);
+        assert_relative_ne!(f32::MIN_POSITIVE, f32::NAN);
+        assert_relative_ne!(f32::NAN, -f32::MIN_POSITIVE);
+        assert_relative_ne!(-f32::MIN_POSITIVE, f32::NAN);
+    }
+
+    #[test]
+    fn test_opposite_signs() {
+        assert_relative_ne!(1.000000001f32, -1.0f32);
+        assert_relative_ne!(-1.0f32, 1.000000001f32);
+        assert_relative_ne!(-1.000000001f32, 1.0f32);
+        assert_relative_ne!(1.0f32, -1.000000001f32);
+
+        assert_relative_eq!(10.0 * f32::MIN_POSITIVE, 10.0 * -f32::MIN_POSITIVE);
+    }
+
+    #[test]
+    fn test_close_to_zero() {
+        assert_relative_eq!(f32::MIN_POSITIVE, f32::MIN_POSITIVE);
+        assert_relative_eq!(f32::MIN_POSITIVE, -f32::MIN_POSITIVE);
+        assert_relative_eq!(-f32::MIN_POSITIVE, f32::MIN_POSITIVE);
+
+        assert_relative_eq!(f32::MIN_POSITIVE, 0.0f32);
+        assert_relative_eq!(0.0f32, f32::MIN_POSITIVE);
+        assert_relative_eq!(-f32::MIN_POSITIVE, 0.0f32);
+        assert_relative_eq!(0.0f32, -f32::MIN_POSITIVE);
+
+        assert_relative_ne!(0.000001f32, -f32::MIN_POSITIVE);
+        assert_relative_ne!(0.000001f32, f32::MIN_POSITIVE);
+        assert_relative_ne!(f32::MIN_POSITIVE, 0.000001f32);
+        assert_relative_ne!(-f32::MIN_POSITIVE, 0.000001f32);
+    }
+}
+
+#[cfg(test)]
+mod test_f64 {
+    use std::f64;
+
+    #[test]
+    fn test_basic() {
+        assert_relative_eq!(1.0f64, 1.0f64);
+        assert_relative_ne!(1.0f64, 2.0f64);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_basic_panic_eq() {
+        assert_relative_eq!(1.0f64, 2.0f64);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_basic_panic_ne() {
+        assert_relative_ne!(1.0f64, 1.0f64);
+    }
+
+    #[test]
+    fn test_big() {
+        assert_relative_eq!(10000000000000000.0f64, 10000000000000001.0f64);
+        assert_relative_eq!(10000000000000001.0f64, 10000000000000000.0f64);
+        assert_relative_ne!(1000000000000000.0f64, 1000000000000001.0f64);
+        assert_relative_ne!(1000000000000001.0f64, 1000000000000000.0f64);
+    }
+
+    #[test]
+    fn test_big_neg() {
+        assert_relative_eq!(-10000000000000000.0f64, -10000000000000001.0f64);
+        assert_relative_eq!(-10000000000000001.0f64, -10000000000000000.0f64);
+        assert_relative_ne!(-1000000000000000.0f64, -1000000000000001.0f64);
+        assert_relative_ne!(-1000000000000001.0f64, -1000000000000000.0f64);
+    }
+
+    #[test]
+    fn test_mid() {
+        assert_relative_eq!(1.0000000000000001f64, 1.0000000000000002f64);
+        assert_relative_eq!(1.0000000000000002f64, 1.0000000000000001f64);
+        assert_relative_ne!(1.000000000000001f64, 1.000000000000002f64);
+        assert_relative_ne!(1.000000000000002f64, 1.000000000000001f64);
+    }
+
+    #[test]
+    fn test_mid_neg() {
+        assert_relative_eq!(-1.0000000000000001f64, -1.0000000000000002f64);
+        assert_relative_eq!(-1.0000000000000002f64, -1.0000000000000001f64);
+        assert_relative_ne!(-1.000000000000001f64, -1.000000000000002f64);
+        assert_relative_ne!(-1.000000000000002f64, -1.000000000000001f64);
+    }
+
+    #[test]
+    fn test_small() {
+        assert_relative_eq!(0.0000000100000001f64, 0.0000000100000002f64);
+        assert_relative_eq!(0.0000000100000002f64, 0.0000000100000001f64);
+        assert_relative_ne!(0.0000000100000001f64, 0.0000000010000002f64);
+        assert_relative_ne!(0.0000000100000002f64, 0.0000000010000001f64);
+    }
+
+    #[test]
+    fn test_small_neg() {
+        assert_relative_eq!(-0.0000000100000001f64, -0.0000000100000002f64);
+        assert_relative_eq!(-0.0000000100000002f64, -0.0000000100000001f64);
+        assert_relative_ne!(-0.0000000100000001f64, -0.0000000010000002f64);
+        assert_relative_ne!(-0.0000000100000002f64, -0.0000000010000001f64);
+    }
+
+    #[test]
+    fn test_zero() {
+        assert_relative_eq!(0.0f64, 0.0f64);
+        assert_relative_eq!(0.0f64, -0.0f64);
+        assert_relative_eq!(-0.0f64, -0.0f64);
+
+        assert_relative_ne!(0.000000000000001f64, 0.0f64);
+        assert_relative_ne!(0.0f64, 0.000000000000001f64);
+        assert_relative_ne!(-0.000000000000001f64, 0.0f64);
+        assert_relative_ne!(0.0f64, -0.000000000000001f64);
+    }
+
+    #[test]
+    fn test_epsilon() {
+        assert_relative_eq!(0.0f64, 1e-40f64, epsilon = 1e-40f64);
+        assert_relative_eq!(1e-40f64, 0.0f64, epsilon = 1e-40f64);
+        assert_relative_eq!(0.0f64, -1e-40f64, epsilon = 1e-40f64);
+        assert_relative_eq!(-1e-40f64, 0.0f64, epsilon = 1e-40f64);
+
+        assert_relative_ne!(1e-40f64, 0.0f64, epsilon = 1e-41f64);
+        assert_relative_ne!(0.0f64, 1e-40f64, epsilon = 1e-41f64);
+        assert_relative_ne!(-1e-40f64, 0.0f64, epsilon = 1e-41f64);
+        assert_relative_ne!(0.0f64, -1e-40f64, epsilon = 1e-41f64);
+    }
+
+    #[test]
+    fn test_max() {
+        assert_relative_eq!(f64::MAX, f64::MAX);
+        assert_relative_ne!(f64::MAX, -f64::MAX);
+        assert_relative_ne!(-f64::MAX, f64::MAX);
+        assert_relative_ne!(f64::MAX, f64::MAX / 2.0);
+        assert_relative_ne!(f64::MAX, -f64::MAX / 2.0);
+        assert_relative_ne!(-f64::MAX, f64::MAX / 2.0);
+    }
+
+    #[test]
+    fn test_infinity() {
+        assert_relative_eq!(f64::INFINITY, f64::INFINITY);
+        assert_relative_eq!(f64::NEG_INFINITY, f64::NEG_INFINITY);
+        assert_relative_ne!(f64::NEG_INFINITY, f64::INFINITY);
+    }
+
+    #[test]
+    fn test_nan() {
+        assert_relative_ne!(f64::NAN, f64::NAN);
+
+        assert_relative_ne!(f64::NAN, 0.0);
+        assert_relative_ne!(-0.0, f64::NAN);
+        assert_relative_ne!(f64::NAN, -0.0);
+        assert_relative_ne!(0.0, f64::NAN);
+
+        assert_relative_ne!(f64::NAN, f64::INFINITY);
+        assert_relative_ne!(f64::INFINITY, f64::NAN);
+        assert_relative_ne!(f64::NAN, f64::NEG_INFINITY);
+        assert_relative_ne!(f64::NEG_INFINITY, f64::NAN);
+
+        assert_relative_ne!(f64::NAN, f64::MAX);
+        assert_relative_ne!(f64::MAX, f64::NAN);
+        assert_relative_ne!(f64::NAN, -f64::MAX);
+        assert_relative_ne!(-f64::MAX, f64::NAN);
+
+        assert_relative_ne!(f64::NAN, f64::MIN_POSITIVE);
+        assert_relative_ne!(f64::MIN_POSITIVE, f64::NAN);
+        assert_relative_ne!(f64::NAN, -f64::MIN_POSITIVE);
+        assert_relative_ne!(-f64::MIN_POSITIVE, f64::NAN);
+    }
+
+    #[test]
+    fn test_opposite_signs() {
+        assert_relative_ne!(1.000000001f64, -1.0f64);
+        assert_relative_ne!(-1.0f64, 1.000000001f64);
+        assert_relative_ne!(-1.000000001f64, 1.0f64);
+        assert_relative_ne!(1.0f64, -1.000000001f64);
+
+        assert_relative_eq!(10.0 * f64::MIN_POSITIVE, 10.0 * -f64::MIN_POSITIVE);
+    }
+
+    #[test]
+    fn test_close_to_zero() {
+        assert_relative_eq!(f64::MIN_POSITIVE, f64::MIN_POSITIVE);
+        assert_relative_eq!(f64::MIN_POSITIVE, -f64::MIN_POSITIVE);
+        assert_relative_eq!(-f64::MIN_POSITIVE, f64::MIN_POSITIVE);
+
+        assert_relative_eq!(f64::MIN_POSITIVE, 0.0f64);
+        assert_relative_eq!(0.0f64, f64::MIN_POSITIVE);
+        assert_relative_eq!(-f64::MIN_POSITIVE, 0.0f64);
+        assert_relative_eq!(0.0f64, -f64::MIN_POSITIVE);
+
+        assert_relative_ne!(0.000000000000001f64, -f64::MIN_POSITIVE);
+        assert_relative_ne!(0.000000000000001f64, f64::MIN_POSITIVE);
+        assert_relative_ne!(f64::MIN_POSITIVE, 0.000000000000001f64);
+        assert_relative_ne!(-f64::MIN_POSITIVE, 0.000000000000001f64);
+    }
+}
+
+mod test_ref {
+    mod test_f32 {
+        #[test]
+        fn test_basic() {
+            assert_relative_eq!(&1.0f32, &1.0f32);
+            assert_relative_ne!(&1.0f32, &2.0f32);
+        }
+    }
+
+    mod test_f64 {
+        #[test]
+        fn test_basic() {
+            assert_relative_eq!(&1.0f64, &1.0f64);
+            assert_relative_ne!(&1.0f64, &2.0f64);
+        }
+    }
+}
+
+mod test_slice {
+    mod test_f32 {
+        #[test]
+        fn test_basic() {
+            assert_relative_eq!([1.0f32, 2.0f32][..], [1.0f32, 2.0f32][..]);
+            assert_relative_ne!([1.0f32, 2.0f32][..], [2.0f32, 1.0f32][..]);
+        }
+    }
+
+    mod test_f64 {
+        #[test]
+        fn test_basic() {
+            assert_relative_eq!([1.0f64, 2.0f64][..], [1.0f64, 2.0f64][..]);
+            assert_relative_ne!([1.0f64, 2.0f64][..], [2.0f64, 1.0f64][..]);
+        }
+    }
+}
+
+#[cfg(feature = "num-complex")]
+mod test_complex {
+    extern crate num_complex;
+    pub use self::num_complex::Complex;
+
+    mod test_f32 {
+        use super::Complex;
+
+        #[test]
+        fn test_basic() {
+            assert_relative_eq!(Complex::new(1.0f32, 2.0f32), Complex::new(1.0f32, 2.0f32));
+            assert_relative_ne!(Complex::new(1.0f32, 2.0f32), Complex::new(2.0f32, 1.0f32));
+        }
+
+        #[test]
+        #[should_panic]
+        fn test_basic_panic_eq() {
+            assert_relative_eq!(Complex::new(1.0f32, 2.0f32), Complex::new(2.0f32, 1.0f32));
+        }
+
+        #[test]
+        #[should_panic]
+        fn test_basic_panic_ne() {
+            assert_relative_ne!(Complex::new(1.0f32, 2.0f32), Complex::new(1.0f32, 2.0f32));
+        }
+    }
+
+    mod test_f64 {
+        use super::Complex;
+
+        #[test]
+        fn test_basic() {
+            assert_relative_eq!(Complex::new(1.0f64, 2.0f64), Complex::new(1.0f64, 2.0f64));
+            assert_relative_ne!(Complex::new(1.0f64, 2.0f64), Complex::new(2.0f64, 1.0f64));
+        }
+
+        #[test]
+        #[should_panic]
+        fn test_basic_panic_eq() {
+            assert_relative_eq!(Complex::new(1.0f64, 2.0f64), Complex::new(2.0f64, 1.0f64));
+        }
+
+        #[test]
+        #[should_panic]
+        fn test_basic_panic_ne() {
+            assert_relative_ne!(Complex::new(1.0f64, 2.0f64), Complex::new(1.0f64, 2.0f64));
+        }
+    }
+}
diff --git a/rustc_deps/vendor/approx/tests/ulps_eq.rs b/rustc_deps/vendor/approx/tests/ulps_eq.rs
new file mode 100644
index 0000000..31c92af
--- /dev/null
+++ b/rustc_deps/vendor/approx/tests/ulps_eq.rs
@@ -0,0 +1,438 @@
+// Copyright 2015 Brendan Zabarauskas
+//
+// 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.
+
+// Test cases derived from:
+// https://github.com/Pybonacci/puntoflotante.org/blob/master/content/errors/NearlyEqualsTest.java
+
+#[macro_use]
+extern crate approx;
+
+mod test_f32 {
+    use std::f32;
+
+    #[test]
+    fn test_basic() {
+        assert_ulps_eq!(1.0f32, 1.0f32);
+        assert_ulps_ne!(1.0f32, 2.0f32);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_basic_panic_eq() {
+        assert_ulps_eq!(1.0f32, 2.0f32);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_basic_panic_ne() {
+        assert_ulps_ne!(1.0f32, 1.0f32);
+    }
+
+    #[test]
+    fn test_big() {
+        assert_ulps_eq!(100000000.0f32, 100000001.0f32);
+        assert_ulps_eq!(100000001.0f32, 100000000.0f32);
+        assert_ulps_ne!(10000.0f32, 10001.0f32);
+        assert_ulps_ne!(10001.0f32, 10000.0f32);
+    }
+
+    #[test]
+    fn test_big_neg() {
+        assert_ulps_eq!(-100000000.0f32, -100000001.0f32);
+        assert_ulps_eq!(-100000001.0f32, -100000000.0f32);
+        assert_ulps_ne!(-10000.0f32, -10001.0f32);
+        assert_ulps_ne!(-10001.0f32, -10000.0f32);
+    }
+
+    #[test]
+    fn test_mid() {
+        assert_ulps_eq!(1.0000001f32, 1.0000002f32);
+        assert_ulps_eq!(1.0000002f32, 1.0000001f32);
+        assert_ulps_ne!(1.000001f32, 1.000002f32);
+        assert_ulps_ne!(1.000002f32, 1.000001f32);
+    }
+
+    #[test]
+    fn test_mid_neg() {
+        assert_ulps_eq!(-1.0000001f32, -1.0000002f32);
+        assert_ulps_eq!(-1.0000002f32, -1.0000001f32);
+        assert_ulps_ne!(-1.000001f32, -1.000002f32);
+        assert_ulps_ne!(-1.000002f32, -1.000001f32);
+    }
+
+    #[test]
+    fn test_small() {
+        assert_ulps_eq!(0.000010001f32, 0.000010002f32);
+        assert_ulps_eq!(0.000010002f32, 0.000010001f32);
+        assert_ulps_ne!(0.000001002f32, 0.0000001001f32);
+        assert_ulps_ne!(0.000001001f32, 0.0000001002f32);
+    }
+
+    #[test]
+    fn test_small_neg() {
+        assert_ulps_eq!(-0.000010001f32, -0.000010002f32);
+        assert_ulps_eq!(-0.000010002f32, -0.000010001f32);
+        assert_ulps_ne!(-0.000001002f32, -0.0000001001f32);
+        assert_ulps_ne!(-0.000001001f32, -0.0000001002f32);
+    }
+
+    #[test]
+    fn test_zero() {
+        assert_ulps_eq!(0.0f32, 0.0f32);
+        assert_ulps_eq!(0.0f32, -0.0f32);
+        assert_ulps_eq!(-0.0f32, -0.0f32);
+
+        assert_ulps_ne!(0.000001f32, 0.0f32);
+        assert_ulps_ne!(0.0f32, 0.000001f32);
+        assert_ulps_ne!(-0.000001f32, 0.0f32);
+        assert_ulps_ne!(0.0f32, -0.000001f32);
+    }
+
+    #[test]
+    fn test_epsilon() {
+        assert_ulps_eq!(0.0f32, 1e-40f32, epsilon = 1e-40f32);
+        assert_ulps_eq!(1e-40f32, 0.0f32, epsilon = 1e-40f32);
+        assert_ulps_eq!(0.0f32, -1e-40f32, epsilon = 1e-40f32);
+        assert_ulps_eq!(-1e-40f32, 0.0f32, epsilon = 1e-40f32);
+
+        assert_ulps_ne!(1e-40f32, 0.0f32, epsilon = 1e-41f32);
+        assert_ulps_ne!(0.0f32, 1e-40f32, epsilon = 1e-41f32);
+        assert_ulps_ne!(-1e-40f32, 0.0f32, epsilon = 1e-41f32);
+        assert_ulps_ne!(0.0f32, -1e-40f32, epsilon = 1e-41f32);
+    }
+
+    #[test]
+    fn test_max() {
+        assert_ulps_eq!(f32::MAX, f32::MAX);
+        assert_ulps_ne!(f32::MAX, -f32::MAX);
+        assert_ulps_ne!(-f32::MAX, f32::MAX);
+        assert_ulps_ne!(f32::MAX, f32::MAX / 2.0);
+        assert_ulps_ne!(f32::MAX, -f32::MAX / 2.0);
+        assert_ulps_ne!(-f32::MAX, f32::MAX / 2.0);
+    }
+
+    #[test]
+    fn test_infinity() {
+        assert_ulps_eq!(f32::INFINITY, f32::INFINITY);
+        assert_ulps_eq!(f32::NEG_INFINITY, f32::NEG_INFINITY);
+        assert_ulps_ne!(f32::NEG_INFINITY, f32::INFINITY);
+        assert_ulps_eq!(f32::INFINITY, f32::MAX);
+        assert_ulps_eq!(f32::NEG_INFINITY, -f32::MAX);
+    }
+
+    #[test]
+    fn test_nan() {
+        assert_ulps_ne!(f32::NAN, f32::NAN);
+
+        assert_ulps_ne!(f32::NAN, 0.0);
+        assert_ulps_ne!(-0.0, f32::NAN);
+        assert_ulps_ne!(f32::NAN, -0.0);
+        assert_ulps_ne!(0.0, f32::NAN);
+
+        assert_ulps_ne!(f32::NAN, f32::INFINITY);
+        assert_ulps_ne!(f32::INFINITY, f32::NAN);
+        assert_ulps_ne!(f32::NAN, f32::NEG_INFINITY);
+        assert_ulps_ne!(f32::NEG_INFINITY, f32::NAN);
+
+        assert_ulps_ne!(f32::NAN, f32::MAX);
+        assert_ulps_ne!(f32::MAX, f32::NAN);
+        assert_ulps_ne!(f32::NAN, -f32::MAX);
+        assert_ulps_ne!(-f32::MAX, f32::NAN);
+
+        assert_ulps_ne!(f32::NAN, f32::MIN_POSITIVE);
+        assert_ulps_ne!(f32::MIN_POSITIVE, f32::NAN);
+        assert_ulps_ne!(f32::NAN, -f32::MIN_POSITIVE);
+        assert_ulps_ne!(-f32::MIN_POSITIVE, f32::NAN);
+    }
+
+    #[test]
+    fn test_opposite_signs() {
+        assert_ulps_ne!(1.000000001f32, -1.0f32);
+        assert_ulps_ne!(-1.0f32, 1.000000001f32);
+        assert_ulps_ne!(-1.000000001f32, 1.0f32);
+        assert_ulps_ne!(1.0f32, -1.000000001f32);
+
+        assert_ulps_eq!(10.0 * f32::MIN_POSITIVE, 10.0 * -f32::MIN_POSITIVE);
+    }
+
+    #[test]
+    fn test_close_to_zero() {
+        assert_ulps_eq!(f32::MIN_POSITIVE, f32::MIN_POSITIVE);
+        assert_ulps_eq!(f32::MIN_POSITIVE, -f32::MIN_POSITIVE);
+        assert_ulps_eq!(-f32::MIN_POSITIVE, f32::MIN_POSITIVE);
+
+        assert_ulps_eq!(f32::MIN_POSITIVE, 0.0f32);
+        assert_ulps_eq!(0.0f32, f32::MIN_POSITIVE);
+        assert_ulps_eq!(-f32::MIN_POSITIVE, 0.0f32);
+        assert_ulps_eq!(0.0f32, -f32::MIN_POSITIVE);
+
+        assert_ulps_ne!(0.000001f32, -f32::MIN_POSITIVE);
+        assert_ulps_ne!(0.000001f32, f32::MIN_POSITIVE);
+        assert_ulps_ne!(f32::MIN_POSITIVE, 0.000001f32);
+        assert_ulps_ne!(-f32::MIN_POSITIVE, 0.000001f32);
+    }
+}
+
+#[cfg(test)]
+mod test_f64 {
+    use std::f64;
+
+    #[test]
+    fn test_basic() {
+        assert_ulps_eq!(1.0f64, 1.0f64);
+        assert_ulps_ne!(1.0f64, 2.0f64);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_basic_panic_eq() {
+        assert_ulps_eq!(1.0f64, 2.0f64);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_basic_panic_ne() {
+        assert_ulps_ne!(1.0f64, 1.0f64);
+    }
+
+    #[test]
+    fn test_big() {
+        assert_ulps_eq!(10000000000000000.0f64, 10000000000000001.0f64);
+        assert_ulps_eq!(10000000000000001.0f64, 10000000000000000.0f64);
+        assert_ulps_ne!(1000000000000000.0f64, 1000000000000001.0f64);
+        assert_ulps_ne!(1000000000000001.0f64, 1000000000000000.0f64);
+    }
+
+    #[test]
+    fn test_big_neg() {
+        assert_ulps_eq!(-10000000000000000.0f64, -10000000000000001.0f64);
+        assert_ulps_eq!(-10000000000000001.0f64, -10000000000000000.0f64);
+        assert_ulps_ne!(-1000000000000000.0f64, -1000000000000001.0f64);
+        assert_ulps_ne!(-1000000000000001.0f64, -1000000000000000.0f64);
+    }
+
+    #[test]
+    fn test_mid() {
+        assert_ulps_eq!(1.0000000000000001f64, 1.0000000000000002f64);
+        assert_ulps_eq!(1.0000000000000002f64, 1.0000000000000001f64);
+        assert_ulps_ne!(1.000000000000001f64, 1.0000000000000022f64);
+        assert_ulps_ne!(1.0000000000000022f64, 1.000000000000001f64);
+    }
+
+    #[test]
+    fn test_mid_neg() {
+        assert_ulps_eq!(-1.0000000000000001f64, -1.0000000000000002f64);
+        assert_ulps_eq!(-1.0000000000000002f64, -1.0000000000000001f64);
+        assert_ulps_ne!(-1.000000000000001f64, -1.0000000000000022f64);
+        assert_ulps_ne!(-1.0000000000000022f64, -1.000000000000001f64);
+    }
+
+    #[test]
+    fn test_small() {
+        assert_ulps_eq!(0.0000000100000001f64, 0.0000000100000002f64);
+        assert_ulps_eq!(0.0000000100000002f64, 0.0000000100000001f64);
+        assert_ulps_ne!(0.0000000100000001f64, 0.0000000010000002f64);
+        assert_ulps_ne!(0.0000000100000002f64, 0.0000000010000001f64);
+    }
+
+    #[test]
+    fn test_small_neg() {
+        assert_ulps_eq!(-0.0000000100000001f64, -0.0000000100000002f64);
+        assert_ulps_eq!(-0.0000000100000002f64, -0.0000000100000001f64);
+        assert_ulps_ne!(-0.0000000100000001f64, -0.0000000010000002f64);
+        assert_ulps_ne!(-0.0000000100000002f64, -0.0000000010000001f64);
+    }
+
+    #[test]
+    fn test_zero() {
+        assert_ulps_eq!(0.0f64, 0.0f64);
+        assert_ulps_eq!(0.0f64, -0.0f64);
+        assert_ulps_eq!(-0.0f64, -0.0f64);
+
+        assert_ulps_ne!(0.000000000000001f64, 0.0f64);
+        assert_ulps_ne!(0.0f64, 0.000000000000001f64);
+        assert_ulps_ne!(-0.000000000000001f64, 0.0f64);
+        assert_ulps_ne!(0.0f64, -0.000000000000001f64);
+    }
+
+    #[test]
+    fn test_epsilon() {
+        assert_ulps_eq!(0.0f64, 1e-40f64, epsilon = 1e-40f64);
+        assert_ulps_eq!(1e-40f64, 0.0f64, epsilon = 1e-40f64);
+        assert_ulps_eq!(0.0f64, -1e-40f64, epsilon = 1e-40f64);
+        assert_ulps_eq!(-1e-40f64, 0.0f64, epsilon = 1e-40f64);
+
+        assert_ulps_ne!(1e-40f64, 0.0f64, epsilon = 1e-41f64);
+        assert_ulps_ne!(0.0f64, 1e-40f64, epsilon = 1e-41f64);
+        assert_ulps_ne!(-1e-40f64, 0.0f64, epsilon = 1e-41f64);
+        assert_ulps_ne!(0.0f64, -1e-40f64, epsilon = 1e-41f64);
+    }
+
+    #[test]
+    fn test_max() {
+        assert_ulps_eq!(f64::MAX, f64::MAX);
+        assert_ulps_ne!(f64::MAX, -f64::MAX);
+        assert_ulps_ne!(-f64::MAX, f64::MAX);
+        assert_ulps_ne!(f64::MAX, f64::MAX / 2.0);
+        assert_ulps_ne!(f64::MAX, -f64::MAX / 2.0);
+        assert_ulps_ne!(-f64::MAX, f64::MAX / 2.0);
+    }
+
+    #[test]
+    fn test_infinity() {
+        assert_ulps_eq!(f64::INFINITY, f64::INFINITY);
+        assert_ulps_eq!(f64::NEG_INFINITY, f64::NEG_INFINITY);
+        assert_ulps_ne!(f64::NEG_INFINITY, f64::INFINITY);
+        assert_ulps_eq!(f64::INFINITY, f64::MAX);
+        assert_ulps_eq!(f64::NEG_INFINITY, -f64::MAX);
+    }
+
+    #[test]
+    fn test_nan() {
+        assert_ulps_ne!(f64::NAN, f64::NAN);
+
+        assert_ulps_ne!(f64::NAN, 0.0);
+        assert_ulps_ne!(-0.0, f64::NAN);
+        assert_ulps_ne!(f64::NAN, -0.0);
+        assert_ulps_ne!(0.0, f64::NAN);
+
+        assert_ulps_ne!(f64::NAN, f64::INFINITY);
+        assert_ulps_ne!(f64::INFINITY, f64::NAN);
+        assert_ulps_ne!(f64::NAN, f64::NEG_INFINITY);
+        assert_ulps_ne!(f64::NEG_INFINITY, f64::NAN);
+
+        assert_ulps_ne!(f64::NAN, f64::MAX);
+        assert_ulps_ne!(f64::MAX, f64::NAN);
+        assert_ulps_ne!(f64::NAN, -f64::MAX);
+        assert_ulps_ne!(-f64::MAX, f64::NAN);
+
+        assert_ulps_ne!(f64::NAN, f64::MIN_POSITIVE);
+        assert_ulps_ne!(f64::MIN_POSITIVE, f64::NAN);
+        assert_ulps_ne!(f64::NAN, -f64::MIN_POSITIVE);
+        assert_ulps_ne!(-f64::MIN_POSITIVE, f64::NAN);
+    }
+
+    #[test]
+    fn test_opposite_signs() {
+        assert_ulps_ne!(1.000000001f64, -1.0f64);
+        assert_ulps_ne!(-1.0f64, 1.000000001f64);
+        assert_ulps_ne!(-1.000000001f64, 1.0f64);
+        assert_ulps_ne!(1.0f64, -1.000000001f64);
+
+        assert_ulps_eq!(10.0 * f64::MIN_POSITIVE, 10.0 * -f64::MIN_POSITIVE);
+    }
+
+    #[test]
+    fn test_close_to_zero() {
+        assert_ulps_eq!(f64::MIN_POSITIVE, f64::MIN_POSITIVE);
+        assert_ulps_eq!(f64::MIN_POSITIVE, -f64::MIN_POSITIVE);
+        assert_ulps_eq!(-f64::MIN_POSITIVE, f64::MIN_POSITIVE);
+
+        assert_ulps_eq!(f64::MIN_POSITIVE, 0.0f64);
+        assert_ulps_eq!(0.0f64, f64::MIN_POSITIVE);
+        assert_ulps_eq!(-f64::MIN_POSITIVE, 0.0f64);
+        assert_ulps_eq!(0.0f64, -f64::MIN_POSITIVE);
+
+        assert_ulps_ne!(0.000000000000001f64, -f64::MIN_POSITIVE);
+        assert_ulps_ne!(0.000000000000001f64, f64::MIN_POSITIVE);
+        assert_ulps_ne!(f64::MIN_POSITIVE, 0.000000000000001f64);
+        assert_ulps_ne!(-f64::MIN_POSITIVE, 0.000000000000001f64);
+    }
+}
+
+mod test_ref {
+    mod test_f32 {
+        #[test]
+        fn test_basic() {
+            assert_ulps_eq!(&1.0f32, &1.0f32);
+            assert_ulps_ne!(&1.0f32, &2.0f32);
+        }
+    }
+
+    mod test_f64 {
+        #[test]
+        fn test_basic() {
+            assert_ulps_eq!(&1.0f64, &1.0f64);
+            assert_ulps_ne!(&1.0f64, &2.0f64);
+        }
+    }
+}
+
+mod test_slice {
+    mod test_f32 {
+        #[test]
+        fn test_basic() {
+            assert_ulps_eq!([1.0f32, 2.0f32][..], [1.0f32, 2.0f32][..]);
+            assert_ulps_ne!([1.0f32, 2.0f32][..], [2.0f32, 1.0f32][..]);
+        }
+    }
+
+    mod test_f64 {
+        #[test]
+        fn test_basic() {
+            assert_ulps_eq!([1.0f64, 2.0f64][..], [1.0f64, 2.0f64][..]);
+            assert_ulps_ne!([1.0f64, 2.0f64][..], [2.0f64, 1.0f64][..]);
+        }
+    }
+}
+
+#[cfg(feature = "num-complex")]
+mod test_complex {
+    extern crate num_complex;
+    pub use self::num_complex::Complex;
+
+    mod test_f32 {
+        use super::Complex;
+
+        #[test]
+        fn test_basic() {
+            assert_ulps_eq!(Complex::new(1.0f32, 2.0f32), Complex::new(1.0f32, 2.0f32));
+            assert_ulps_ne!(Complex::new(1.0f32, 2.0f32), Complex::new(2.0f32, 1.0f32));
+        }
+
+        #[test]
+        #[should_panic]
+        fn test_basic_panic_eq() {
+            assert_ulps_eq!(Complex::new(1.0f32, 2.0f32), Complex::new(2.0f32, 1.0f32));
+        }
+
+        #[test]
+        #[should_panic]
+        fn test_basic_panic_ne() {
+            assert_ulps_ne!(Complex::new(1.0f32, 2.0f32), Complex::new(1.0f32, 2.0f32));
+        }
+    }
+
+    mod test_f64 {
+        use super::Complex;
+
+        #[test]
+        fn test_basic() {
+            assert_ulps_eq!(Complex::new(1.0f64, 2.0f64), Complex::new(1.0f64, 2.0f64));
+            assert_ulps_ne!(Complex::new(1.0f64, 2.0f64), Complex::new(2.0f64, 1.0f64));
+        }
+
+        #[test]
+        #[should_panic]
+        fn test_basic_panic_eq() {
+            assert_ulps_eq!(Complex::new(1.0f64, 2.0f64), Complex::new(2.0f64, 1.0f64));
+        }
+
+        #[test]
+        #[should_panic]
+        fn test_basic_panic_ne() {
+            assert_ulps_ne!(Complex::new(1.0f64, 2.0f64), Complex::new(1.0f64, 2.0f64));
+        }
+    }
+}
diff --git a/rustc_deps/vendor/ordered-float/.cargo-checksum.json b/rustc_deps/vendor/ordered-float/.cargo-checksum.json
new file mode 100644
index 0000000..00b28dc
--- /dev/null
+++ b/rustc_deps/vendor/ordered-float/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"3c58ad023bf0f3648553123f643212ce8aaf812960649099f0839a44ab4cf332","LICENSE-MIT":"f7715d38a3fa1b4ac97c5729740752505a39cb92ee83ab5b102aeb5eaa7cdea4","README.md":"c4aee96bd98f215fe099f498385e4f31319bff37d2415998f8e6ac27bbea3cc5","src/lib.rs":"a0f3650fb55786bdde477a0120e0a5665cca109a8377edc0f0ada93199710dc8","tests/test.rs":"a9d946dc02c92826e4dc0ff31960a76ff9370fa45feae5a0de72c8d020b56c5b","tests/test_deprecated_names.rs":"6f661c27e8b4d625c02202895f220d573e3dccc8cf684c77e754c444403939f7"},"package":"2f0015e9e8e28ee20c581cfbfe47c650cedeb9ed0721090e0b7ebb10b9cdbcc2"}
\ No newline at end of file
diff --git a/rustc_deps/vendor/ordered-float/Cargo.toml b/rustc_deps/vendor/ordered-float/Cargo.toml
new file mode 100644
index 0000000..980a788
--- /dev/null
+++ b/rustc_deps/vendor/ordered-float/Cargo.toml
@@ -0,0 +1,35 @@
+# 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 = "ordered-float"
+version = "1.0.1"
+authors = ["Jonathan Reem <jonathan.reem@gmail.com>", "Matt Brubeck <mbrubeck@limpet.net>"]
+description = "Wrappers for total ordering on floats"
+readme = "README.md"
+keywords = ["no_std", "ord", "f64", "f32", "sort"]
+categories = ["science", "rust-patterns", "no-std"]
+license = "MIT"
+repository = "https://github.com/reem/rust-ordered-float"
+[dependencies.num-traits]
+version = "0.2"
+
+[dependencies.serde]
+version = "1.0"
+optional = true
+default-features = false
+[dev-dependencies.serde_test]
+version = "1.0"
+
+[features]
+default = ["std"]
+std = []
diff --git a/rustc_deps/vendor/ordered-float/LICENSE-MIT b/rustc_deps/vendor/ordered-float/LICENSE-MIT
new file mode 100644
index 0000000..c8e0f5e
--- /dev/null
+++ b/rustc_deps/vendor/ordered-float/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2015 Jonathan Reem
+
+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.
diff --git a/rustc_deps/vendor/ordered-float/README.md b/rustc_deps/vendor/ordered-float/README.md
new file mode 100644
index 0000000..b5e3302
--- /dev/null
+++ b/rustc_deps/vendor/ordered-float/README.md
@@ -0,0 +1,29 @@
+# Ordered Floats
+
+Provides several wrapper types for Ord and Eq implementations on f64.
+
+## Usage
+
+Use the crates.io repository; add this to your `Cargo.toml` along
+with the rest of your dependencies:
+
+```toml
+[dependencies]
+ordered-float = "1.0"
+```
+
+See the [API documentation](https://docs.rs/ordered-float) for further details.
+
+## no_std
+
+To use `ordered_float` without requiring the Rust standard library, disable
+the default `std` feature:
+
+```toml
+[dependencies]
+ordered-float = { version = "1.0", default-features = false }
+```
+
+## License
+
+MIT
diff --git a/rustc_deps/vendor/ordered-float/src/lib.rs b/rustc_deps/vendor/ordered-float/src/lib.rs
new file mode 100644
index 0000000..38a849f
--- /dev/null
+++ b/rustc_deps/vendor/ordered-float/src/lib.rs
@@ -0,0 +1,758 @@
+#![no_std]
+#![cfg_attr(test, deny(warnings))]
+#![deny(missing_docs)]
+
+//! Wrappers for total order on Floats.
+
+extern crate num_traits;
+#[cfg(feature = "std")] extern crate std;
+
+use core::cmp::Ordering;
+use core::ops::{Add, AddAssign, Deref, DerefMut, Div, DivAssign, Mul, MulAssign, Neg, Rem,
+               RemAssign, Sub, SubAssign};
+use core::hash::{Hash, Hasher};
+use core::fmt;
+use core::mem;
+use core::hint::unreachable_unchecked;
+use num_traits::{Bounded, Float, FromPrimitive, Num, NumCast, One, Signed, ToPrimitive,
+                 Zero};
+
+/// A wrapper around Floats providing an implementation of Ord and Hash.
+///
+/// A NaN value cannot be stored in this type.
+#[deprecated(since = "0.6.0", note = "renamed to `NotNan`")]
+pub type NotNaN<T> = NotNan<T>;
+
+/// An error indicating an attempt to construct NotNan from a NaN
+#[deprecated(since = "0.6.0", note = "renamed to `FloatIsNan`")]
+pub type FloatIsNaN = FloatIsNan;
+
+// masks for the parts of the IEEE 754 float
+const SIGN_MASK: u64 = 0x8000000000000000u64;
+const EXP_MASK: u64 = 0x7ff0000000000000u64;
+const MAN_MASK: u64 = 0x000fffffffffffffu64;
+
+// canonical raw bit patterns (for hashing)
+const CANONICAL_NAN_BITS: u64 = 0x7ff8000000000000u64;
+const CANONICAL_ZERO_BITS: u64 = 0x0u64;
+
+/// A wrapper around Floats providing an implementation of Ord and Hash.
+///
+/// NaN is sorted as *greater* than all other values and *equal*
+/// to itself, in contradiction with the IEEE standard.
+#[derive(Debug, Default, Clone, Copy)]
+#[repr(transparent)]
+pub struct OrderedFloat<T: Float>(pub T);
+
+impl<T: Float> OrderedFloat<T> {
+    /// Get the value out.
+    pub fn into_inner(self) -> T {
+        let OrderedFloat(val) = self;
+        val
+    }
+}
+
+impl<T: Float> AsRef<T> for OrderedFloat<T> {
+    fn as_ref(&self) -> &T {
+        let OrderedFloat(ref val) = *self;
+        val
+    }
+}
+
+impl<T: Float> AsMut<T> for OrderedFloat<T> {
+    fn as_mut(&mut self) -> &mut T {
+        let OrderedFloat(ref mut val) = *self;
+        val
+    }
+}
+
+impl<T: Float> PartialOrd for OrderedFloat<T> {
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl<T: Float> Ord for OrderedFloat<T> {
+    fn cmp(&self, other: &Self) -> Ordering {
+        let lhs = self.as_ref();
+        let rhs = other.as_ref();
+        match lhs.partial_cmp(&rhs) {
+            Some(ordering) => ordering,
+            None => {
+                if lhs.is_nan() {
+                    if rhs.is_nan() {
+                        Ordering::Equal
+                    } else {
+                        Ordering::Greater
+                    }
+                } else {
+                    Ordering::Less
+                }
+            }
+        }
+    }
+}
+
+impl<T: Float> PartialEq for OrderedFloat<T> {
+    fn eq(&self, other: &OrderedFloat<T>) -> bool {
+        if self.as_ref().is_nan() {
+            other.as_ref().is_nan()
+        } else if other.as_ref().is_nan() {
+            false
+        } else {
+            self.as_ref() == other.as_ref()
+        }
+    }
+}
+
+impl<T: Float> Hash for OrderedFloat<T> {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        if self.is_nan() {
+            // normalize to one representation of NaN
+            hash_float(&T::nan(), state)
+        } else {
+            hash_float(self.as_ref(), state)
+        }
+    }
+}
+
+impl<T: Float + fmt::Display> fmt::Display for OrderedFloat<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.as_ref().fmt(f)
+    }
+}
+
+impl Into<f32> for OrderedFloat<f32> {
+    fn into(self) -> f32 {
+        self.into_inner()
+    }
+}
+
+impl Into<f64> for OrderedFloat<f64> {
+    fn into(self) -> f64 {
+        self.into_inner()
+    }
+}
+
+impl<T: Float> From<T> for OrderedFloat<T> {
+    fn from(val: T) -> Self {
+        OrderedFloat(val)
+    }
+}
+
+impl<T: Float> Deref for OrderedFloat<T> {
+    type Target = T;
+
+    fn deref(&self) -> &Self::Target {
+        self.as_ref()
+    }
+}
+
+impl<T: Float> DerefMut for OrderedFloat<T> {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        self.as_mut()
+    }
+}
+
+impl<T: Float> Eq for OrderedFloat<T> {}
+
+impl<T: Float> Bounded for OrderedFloat<T> {
+    fn min_value() -> Self {
+        OrderedFloat(T::min_value())
+    }
+
+    fn max_value() -> Self {
+        OrderedFloat(T::max_value())
+    }
+}
+
+/// A wrapper around Floats providing an implementation of Ord and Hash.
+///
+/// A NaN value cannot be stored in this type.
+#[derive(PartialOrd, PartialEq, Debug, Default, Clone, Copy)]
+#[repr(transparent)]
+pub struct NotNan<T: Float>(T);
+
+impl<T: Float> NotNan<T> {
+    /// Create a NotNan value.
+    ///
+    /// Returns Err if val is NaN
+    pub fn new(val: T) -> Result<Self, FloatIsNan> {
+        match val {
+            ref val if val.is_nan() => Err(FloatIsNan),
+            val => Ok(NotNan(val)),
+        }
+    }
+
+    /// Create a NotNan value from a value that is guaranteed to not be NaN
+    ///
+    /// Behaviour is undefined if `val` is NaN
+    pub unsafe fn unchecked_new(val: T) -> Self {
+        debug_assert!(!val.is_nan());
+        NotNan(val)
+    }
+
+    /// Get the value out.
+    pub fn into_inner(self) -> T {
+        let NotNan(val) = self;
+        val
+    }
+}
+
+impl<T: Float> AsRef<T> for NotNan<T> {
+    fn as_ref(&self) -> &T {
+        let NotNan(ref val) = *self;
+        val
+    }
+}
+
+impl<T: Float> Ord for NotNan<T> {
+    fn cmp(&self, other: &NotNan<T>) -> Ordering {
+        match self.partial_cmp(&other) {
+            Some(ord) => ord,
+            None => unsafe { unreachable_unchecked() },
+        }
+    }
+}
+
+impl<T: Float> Hash for NotNan<T> {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        hash_float(self.as_ref(), state)
+    }
+}
+
+impl<T: Float + fmt::Display> fmt::Display for NotNan<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.as_ref().fmt(f)
+    }
+}
+
+impl Into<f32> for NotNan<f32> {
+    fn into(self) -> f32 {
+        self.into_inner()
+    }
+}
+
+impl Into<f64> for NotNan<f64> {
+    fn into(self) -> f64 {
+        self.into_inner()
+    }
+}
+
+/// Creates a NotNan value from a Float.
+///
+/// Panics if the provided value is NaN or the computation results in NaN
+impl<T: Float> From<T> for NotNan<T> {
+    fn from(v: T) -> Self {
+        assert!(!v.is_nan());
+        NotNan(v)
+    }
+}
+
+impl<T: Float> Deref for NotNan<T> {
+    type Target = T;
+
+    fn deref(&self) -> &Self::Target {
+        self.as_ref()
+    }
+}
+
+impl<T: Float + PartialEq> Eq for NotNan<T> {}
+
+/// Adds two NotNans.
+///
+/// Panics if the computation results in NaN
+impl<T: Float> Add for NotNan<T> {
+    type Output = Self;
+
+    fn add(self, other: Self) -> Self {
+        NotNan::new(self.0 + other.0).expect("Addition resulted in NaN")
+    }
+}
+
+/// Adds a float directly.
+///
+/// Panics if the provided value is NaN or the computation results in NaN
+impl<T: Float> Add<T> for NotNan<T> {
+    type Output = Self;
+
+    fn add(self, other: T) -> Self {
+        assert!(!other.is_nan());
+        NotNan::new(self.0 + other).expect("Addition resulted in NaN")
+    }
+}
+
+impl AddAssign for NotNan<f64> {
+    fn add_assign(&mut self, other: Self) {
+        self.0 += other.0;
+        assert!(!self.0.is_nan(), "Addition resulted in NaN")
+    }
+}
+
+impl AddAssign for NotNan<f32> {
+    fn add_assign(&mut self, other: Self) {
+        self.0 += other.0;
+        assert!(!self.0.is_nan(), "Addition resulted in NaN")
+    }
+}
+
+/// Adds a float directly.
+///
+/// Panics if the provided value is NaN or the computation results in NaN
+impl AddAssign<f64> for NotNan<f64> {
+    fn add_assign(&mut self, other: f64) {
+        assert!(!other.is_nan());
+        self.0 += other;
+        assert!(!self.0.is_nan(), "Addition resulted in NaN")
+    }
+}
+
+/// Adds a float directly.
+///
+/// Panics if the provided value is NaN.
+impl AddAssign<f32> for NotNan<f32> {
+    fn add_assign(&mut self, other: f32) {
+        assert!(!other.is_nan());
+        self.0 += other;
+        assert!(!self.0.is_nan(), "Addition resulted in NaN")
+    }
+}
+
+impl<T: Float> Sub for NotNan<T> {
+    type Output = Self;
+
+    fn sub(self, other: Self) -> Self {
+        NotNan::new(self.0 - other.0).expect("Subtraction resulted in NaN")
+    }
+}
+
+/// Subtracts a float directly.
+///
+/// Panics if the provided value is NaN or the computation results in NaN
+impl<T: Float> Sub<T> for NotNan<T> {
+    type Output = Self;
+
+    fn sub(self, other: T) -> Self {
+        assert!(!other.is_nan());
+        NotNan::new(self.0 - other).expect("Subtraction resulted in NaN")
+    }
+}
+
+impl SubAssign for NotNan<f64> {
+    fn sub_assign(&mut self, other: Self) {
+        self.0 -= other.0;
+        assert!(!self.0.is_nan(), "Subtraction resulted in NaN")
+    }
+}
+
+impl SubAssign for NotNan<f32> {
+    fn sub_assign(&mut self, other: Self) {
+        self.0 -= other.0;
+        assert!(!self.0.is_nan(), "Subtraction resulted in NaN")
+    }
+}
+
+/// Subtracts a float directly.
+///
+/// Panics if the provided value is NaN or the computation results in NaN
+impl SubAssign<f64> for NotNan<f64> {
+    fn sub_assign(&mut self, other: f64) {
+        assert!(!other.is_nan());
+        self.0 -= other;
+        assert!(!self.0.is_nan(), "Subtraction resulted in NaN")
+    }
+}
+
+/// Subtracts a float directly.
+///
+/// Panics if the provided value is NaN or the computation results in NaN
+impl SubAssign<f32> for NotNan<f32> {
+    fn sub_assign(&mut self, other: f32) {
+        assert!(!other.is_nan());
+        self.0 -= other;
+        assert!(!self.0.is_nan(), "Subtraction resulted in NaN")
+    }
+}
+
+impl<T: Float> Mul for NotNan<T> {
+    type Output = Self;
+
+    fn mul(self, other: Self) -> Self {
+        NotNan::new(self.0 * other.0).expect("Multiplication resulted in NaN")
+    }
+}
+
+/// Multiplies a float directly.
+///
+/// Panics if the provided value is NaN or the computation results in NaN
+impl<T: Float> Mul<T> for NotNan<T> {
+    type Output = Self;
+
+    fn mul(self, other: T) -> Self {
+        assert!(!other.is_nan());
+        NotNan::new(self.0 * other).expect("Multiplication resulted in NaN")
+    }
+}
+
+impl MulAssign for NotNan<f64> {
+    fn mul_assign(&mut self, other: Self) {
+        self.0 *= other.0;
+        assert!(!self.0.is_nan(), "Multiplication resulted in NaN")
+    }
+}
+
+impl MulAssign for NotNan<f32> {
+    fn mul_assign(&mut self, other: Self) {
+        self.0 *= other.0;
+        assert!(!self.0.is_nan(), "Multiplication resulted in NaN")
+    }
+}
+
+/// Multiplies a float directly.
+///
+/// Panics if the provided value is NaN.
+impl MulAssign<f64> for NotNan<f64> {
+    fn mul_assign(&mut self, other: f64) {
+        assert!(!other.is_nan());
+        self.0 *= other;
+    }
+}
+
+/// Multiplies a float directly.
+///
+/// Panics if the provided value is NaN or the computation results in NaN
+impl MulAssign<f32> for NotNan<f32> {
+    fn mul_assign(&mut self, other: f32) {
+        assert!(!other.is_nan());
+        self.0 *= other;
+        assert!(!self.0.is_nan(), "Multiplication resulted in NaN")
+    }
+}
+
+impl<T: Float> Div for NotNan<T> {
+    type Output = Self;
+
+    fn div(self, other: Self) -> Self {
+        NotNan::new(self.0 / other.0).expect("Division resulted in NaN")
+    }
+}
+
+/// Divides a float directly.
+///
+/// Panics if the provided value is NaN or the computation results in NaN
+impl<T: Float> Div<T> for NotNan<T> {
+    type Output = Self;
+
+    fn div(self, other: T) -> Self {
+        assert!(!other.is_nan());
+        NotNan::new(self.0 / other).expect("Division resulted in NaN")
+    }
+}
+
+impl DivAssign for NotNan<f64> {
+    fn div_assign(&mut self, other: Self) {
+        self.0 /= other.0;
+        assert!(!self.0.is_nan(), "Division resulted in NaN")
+    }
+}
+
+impl DivAssign for NotNan<f32> {
+    fn div_assign(&mut self, other: Self) {
+        self.0 /= other.0;
+        assert!(!self.0.is_nan(), "Division resulted in NaN")
+    }
+}
+
+/// Divides a float directly.
+///
+/// Panics if the provided value is NaN or the computation results in NaN
+impl DivAssign<f64> for NotNan<f64> {
+    fn div_assign(&mut self, other: f64) {
+        assert!(!other.is_nan());
+        self.0 /= other;
+        assert!(!self.0.is_nan(), "Division resulted in NaN")
+    }
+}
+
+/// Divides a float directly.
+///
+/// Panics if the provided value is NaN or the computation results in NaN
+impl DivAssign<f32> for NotNan<f32> {
+    fn div_assign(&mut self, other: f32) {
+        assert!(!other.is_nan());
+        self.0 /= other;
+        assert!(!self.0.is_nan(), "Division resulted in NaN")
+    }
+}
+
+impl<T: Float> Rem for NotNan<T> {
+    type Output = Self;
+
+    fn rem(self, other: Self) -> Self {
+        NotNan::new(self.0 % other.0).expect("Rem resulted in NaN")
+    }
+}
+
+/// Calculates `%` with a float directly.
+///
+/// Panics if the provided value is NaN or the computation results in NaN
+impl<T: Float> Rem<T> for NotNan<T> {
+    type Output = Self;
+
+    fn rem(self, other: T) -> Self {
+        assert!(!other.is_nan());
+        NotNan::new(self.0 % other).expect("Rem resulted in NaN")
+    }
+}
+
+impl RemAssign for NotNan<f64> {
+    fn rem_assign(&mut self, other: Self) {
+        self.0 %= other.0;
+        assert!(!self.0.is_nan(), "Rem resulted in NaN")
+    }
+}
+
+impl RemAssign for NotNan<f32> {
+    fn rem_assign(&mut self, other: Self) {
+        self.0 %= other.0;
+        assert!(!self.0.is_nan(), "Rem resulted in NaN")
+    }
+}
+
+/// Calculates `%=` with a float directly.
+///
+/// Panics if the provided value is NaN or the computation results in NaN
+impl RemAssign<f64> for NotNan<f64> {
+    fn rem_assign(&mut self, other: f64) {
+        assert!(!other.is_nan());
+        self.0 %= other;
+        assert!(!self.0.is_nan(), "Rem resulted in NaN")
+    }
+}
+
+/// Calculates `%=` with a float directly.
+///
+/// Panics if the provided value is NaN or the computation results in NaN
+impl RemAssign<f32> for NotNan<f32> {
+    fn rem_assign(&mut self, other: f32) {
+        assert!(!other.is_nan());
+        self.0 %= other;
+        assert!(!self.0.is_nan(), "Rem resulted in NaN")
+    }
+}
+
+impl<T: Float> Neg for NotNan<T> {
+    type Output = Self;
+
+    fn neg(self) -> Self {
+        NotNan::new(-self.0).expect("Negation resulted in NaN")
+    }
+}
+
+/// An error indicating an attempt to construct NotNan from a NaN
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+pub struct FloatIsNan;
+
+#[cfg(feature = "std")]
+impl std::error::Error for FloatIsNan {
+    fn description(&self) -> &str {
+        "NotNan constructed with NaN"
+    }
+}
+
+impl fmt::Display for FloatIsNan {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "NotNan constructed with NaN")
+    }
+}
+
+#[cfg(feature = "std")]
+impl Into<std::io::Error> for FloatIsNan {
+    fn into(self) -> std::io::Error {
+        std::io::Error::new(std::io::ErrorKind::InvalidInput, self)
+    }
+}
+
+#[inline]
+fn hash_float<F: Float, H: Hasher>(f: &F, state: &mut H) {
+    raw_double_bits(f).hash(state);
+}
+
+#[inline]
+fn raw_double_bits<F: Float>(f: &F) -> u64 {
+    if f.is_nan() {
+        return CANONICAL_NAN_BITS;
+    }
+
+    let (man, exp, sign) = f.integer_decode();
+    if man == 0 {
+        return CANONICAL_ZERO_BITS;
+    }
+
+    let exp_u64 = unsafe { mem::transmute::<i16, u16>(exp) } as u64;
+    let sign_u64 = if sign > 0 { 1u64 } else { 0u64 };
+    (man & MAN_MASK) | ((exp_u64 << 52) & EXP_MASK) | ((sign_u64 << 63) & SIGN_MASK)
+}
+
+impl<T: Float> Zero for NotNan<T> {
+    fn zero() -> Self { NotNan(T::zero()) }
+
+    fn is_zero(&self) -> bool { self.0.is_zero() }
+}
+
+impl<T: Float> One for NotNan<T> {
+    fn one() -> Self { NotNan(T::one()) }
+}
+
+impl<T: Float> Bounded for NotNan<T> {
+    fn min_value() -> Self {
+        NotNan(T::min_value())
+    }
+
+    fn max_value() -> Self {
+        NotNan(T::max_value())
+    }
+}
+
+impl<T: Float + FromPrimitive> FromPrimitive for NotNan<T> {
+    fn from_i64(n: i64) -> Option<Self> { T::from_i64(n).and_then(|n| NotNan::new(n).ok()) }
+    fn from_u64(n: u64) -> Option<Self> { T::from_u64(n).and_then(|n| NotNan::new(n).ok()) }
+
+    fn from_isize(n: isize) -> Option<Self> { T::from_isize(n).and_then(|n| NotNan::new(n).ok()) }
+    fn from_i8(n: i8) -> Option<Self> { T::from_i8(n).and_then(|n| NotNan::new(n).ok()) }
+    fn from_i16(n: i16) -> Option<Self> { T::from_i16(n).and_then(|n| NotNan::new(n).ok()) }
+    fn from_i32(n: i32) -> Option<Self> { T::from_i32(n).and_then(|n| NotNan::new(n).ok()) }
+    fn from_usize(n: usize) -> Option<Self> { T::from_usize(n).and_then(|n| NotNan::new(n).ok()) }
+    fn from_u8(n: u8) -> Option<Self> { T::from_u8(n).and_then(|n| NotNan::new(n).ok()) }
+    fn from_u16(n: u16) -> Option<Self> { T::from_u16(n).and_then(|n| NotNan::new(n).ok()) }
+    fn from_u32(n: u32) -> Option<Self> { T::from_u32(n).and_then(|n| NotNan::new(n).ok()) }
+    fn from_f32(n: f32) -> Option<Self> { T::from_f32(n).and_then(|n| NotNan::new(n).ok()) }
+    fn from_f64(n: f64) -> Option<Self> { T::from_f64(n).and_then(|n| NotNan::new(n).ok()) }
+}
+
+impl<T: Float> ToPrimitive for NotNan<T> {
+    fn to_i64(&self) -> Option<i64> { self.0.to_i64() }
+    fn to_u64(&self) -> Option<u64> { self.0.to_u64() }
+
+    fn to_isize(&self) -> Option<isize> { self.0.to_isize() }
+    fn to_i8(&self) -> Option<i8> { self.0.to_i8() }
+    fn to_i16(&self) -> Option<i16> { self.0.to_i16() }
+    fn to_i32(&self) -> Option<i32> { self.0.to_i32() }
+    fn to_usize(&self) -> Option<usize> { self.0.to_usize() }
+    fn to_u8(&self) -> Option<u8> { self.0.to_u8() }
+    fn to_u16(&self) -> Option<u16> { self.0.to_u16() }
+    fn to_u32(&self) -> Option<u32> { self.0.to_u32() }
+    fn to_f32(&self) -> Option<f32> { self.0.to_f32() }
+    fn to_f64(&self) -> Option<f64> { self.0.to_f64() }
+}
+
+/// An error indicating a parse error from a string for `NotNan`.
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+pub enum ParseNotNanError<E> {
+    /// A plain parse error from the underlying float type.
+    ParseFloatError(E),
+    /// The parsed float value resulted in a NaN.
+    IsNaN,
+}
+
+#[cfg(feature = "std")]
+impl<E: fmt::Debug> std::error::Error for ParseNotNanError<E> {
+    fn description(&self) -> &str {
+        return "Error parsing a not-NaN floating point value";
+    }
+}
+
+impl<E: fmt::Debug> fmt::Display for ParseNotNanError<E> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        <Self as fmt::Debug>::fmt(self, f)
+    }
+}
+
+impl<T: Float> Num for NotNan<T> {
+    type FromStrRadixErr = ParseNotNanError<T::FromStrRadixErr>;
+
+    fn from_str_radix(src: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
+        T::from_str_radix(src, radix)
+            .map_err(|err| ParseNotNanError::ParseFloatError(err))
+            .and_then(|n| NotNan::new(n).map_err(|_| ParseNotNanError::IsNaN))
+    }
+}
+
+impl<T: Float + Signed> Signed for NotNan<T> {
+    fn abs(&self) -> Self { NotNan(self.0.abs()) }
+
+    fn abs_sub(&self, other: &Self) -> Self {
+        NotNan::new(self.0.abs_sub(other.0)).expect("Subtraction resulted in NaN")
+    }
+
+    fn signum(&self) -> Self { NotNan(self.0.signum()) }
+    fn is_positive(&self) -> bool { self.0.is_positive() }
+    fn is_negative(&self) -> bool { self.0.is_negative() }
+}
+
+impl<T: Float> NumCast for NotNan<T> {
+    fn from<F: ToPrimitive>(n: F) -> Option<Self> {
+        T::from(n).and_then(|n| NotNan::new(n).ok())
+    }
+}
+
+#[cfg(feature = "serde")]
+mod impl_serde {
+    extern crate serde;
+    use self::serde::{Serialize, Serializer, Deserialize, Deserializer};
+    use self::serde::de::{Error, Unexpected};
+    use super::{OrderedFloat, NotNan};
+    use num_traits::Float;
+    use core::f64;
+
+    #[cfg(test)]
+    extern crate serde_test;
+    #[cfg(test)]
+    use self::serde_test::{Token, assert_tokens, assert_de_tokens_error};
+
+    impl<T: Float + Serialize> Serialize for OrderedFloat<T> {
+        fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
+            self.0.serialize(s)
+        }
+    }
+
+    impl<'de, T: Float + Deserialize<'de>> Deserialize<'de> for OrderedFloat<T> {
+        fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
+            T::deserialize(d).map(OrderedFloat)
+        }
+    }
+
+    impl<T: Float + Serialize> Serialize for NotNan<T> {
+        fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
+            self.0.serialize(s)
+        }
+    }
+
+    impl<'de, T: Float + Deserialize<'de>> Deserialize<'de> for NotNan<T> {
+        fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
+            let float = T::deserialize(d)?;
+            NotNan::new(float).map_err(|_| {
+                Error::invalid_value(Unexpected::Float(f64::NAN), &"float (but not NaN)")
+            })
+        }
+    }
+
+    #[test]
+    fn test_ordered_float() {
+        let float = OrderedFloat(1.0f64);
+        assert_tokens(&float, &[Token::F64(1.0)]);
+    }
+
+    #[test]
+    fn test_not_nan() {
+        let float = NotNan(1.0f64);
+        assert_tokens(&float, &[Token::F64(1.0)]);
+    }
+
+    #[test]
+    fn test_fail_on_nan() {
+        assert_de_tokens_error::<NotNan<f64>>(
+            &[Token::F64(f64::NAN)],
+            "invalid value: floating point `NaN`, expected float (but not NaN)");
+    }
+}
diff --git a/rustc_deps/vendor/ordered-float/tests/test.rs b/rustc_deps/vendor/ordered-float/tests/test.rs
new file mode 100644
index 0000000..195d76a
--- /dev/null
+++ b/rustc_deps/vendor/ordered-float/tests/test.rs
@@ -0,0 +1,532 @@
+extern crate num_traits;
+extern crate ordered_float;
+
+pub use ordered_float::*;
+pub use num_traits::{Bounded, Float, FromPrimitive, Num, One, Signed, ToPrimitive, Zero};
+pub use std::cmp::Ordering::*;
+pub use std::{f32, f64, panic};
+
+pub use std::collections::hash_map::RandomState;
+pub use std::collections::HashSet;
+pub use std::hash::*;
+
+#[test]
+fn ordered_f32_compare_regular_floats() {
+    assert_eq!(OrderedFloat(7.0f32).cmp(&OrderedFloat(7.0)), Equal);
+    assert_eq!(OrderedFloat(8.0f32).cmp(&OrderedFloat(7.0)), Greater);
+    assert_eq!(OrderedFloat(4.0f32).cmp(&OrderedFloat(7.0)), Less);
+}
+
+#[test]
+fn ordered_f32_compare_regular_floats_op() {
+    assert!(OrderedFloat(7.0f32) == OrderedFloat(7.0));
+    assert!(OrderedFloat(7.0f32) <= OrderedFloat(7.0));
+    assert!(OrderedFloat(7.0f32) >= OrderedFloat(7.0));
+    assert!(OrderedFloat(8.0f32) > OrderedFloat(7.0));
+    assert!(OrderedFloat(8.0f32) >= OrderedFloat(7.0));
+    assert!(OrderedFloat(4.0f32) < OrderedFloat(7.0));
+    assert!(OrderedFloat(4.0f32) <= OrderedFloat(7.0));
+}
+
+#[test]
+fn ordered_f32_compare_nan() {
+    let f32_nan: f32 = Float::nan();
+    assert_eq!(OrderedFloat(f32_nan).cmp(&OrderedFloat(Float::nan())), Equal);
+    assert_eq!(OrderedFloat(f32_nan).cmp(&OrderedFloat(-100000.0f32)), Greater);
+    assert_eq!(OrderedFloat(-100.0f32).cmp(&OrderedFloat(Float::nan())), Less);
+}
+
+#[test]
+fn ordered_f32_compare_nan_op() {
+    let f32_nan: OrderedFloat<f32> = OrderedFloat(Float::nan());
+    assert!(f32_nan == f32_nan);
+    assert!(f32_nan <= f32_nan);
+    assert!(f32_nan >= f32_nan);
+    assert!(f32_nan > OrderedFloat(-100000.0f32));
+    assert!(f32_nan >= OrderedFloat(-100000.0f32));
+    assert!(OrderedFloat(-100.0f32) < f32_nan);
+    assert!(OrderedFloat(-100.0f32) <= f32_nan);
+    assert!(f32_nan > OrderedFloat(Float::infinity()));
+    assert!(f32_nan >= OrderedFloat(Float::infinity()));
+    assert!(f32_nan > OrderedFloat(Float::neg_infinity()));
+    assert!(f32_nan >= OrderedFloat(Float::neg_infinity()));
+}
+
+#[test]
+fn ordered_f64_compare_regular_floats() {
+    assert_eq!(OrderedFloat(7.0f64).cmp(&OrderedFloat(7.0)), Equal);
+    assert_eq!(OrderedFloat(8.0f64).cmp(&OrderedFloat(7.0)), Greater);
+    assert_eq!(OrderedFloat(4.0f64).cmp(&OrderedFloat(7.0)), Less);
+}
+
+#[test]
+fn not_nan32_zero() {
+    assert_eq!(NotNan::<f32>::zero(), NotNan::from(0.0f32));
+    assert!(NotNan::<f32>::zero().is_zero());
+}
+
+#[test]
+fn not_nan32_one() {
+    assert_eq!(NotNan::<f32>::one(), NotNan::from(1.0f32))
+}
+
+#[test]
+fn not_nan32_bounded() {
+    assert_eq!(NotNan::<f32>::min_value(), NotNan::from(<f32 as Bounded>::min_value()));
+    assert_eq!(NotNan::<f32>::max_value(), NotNan::from(<f32 as Bounded>::max_value()));
+}
+
+#[test]
+fn not_nan32_from_primitive() {
+    assert_eq!(NotNan::<f32>::from_i8(42i8), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f32>::from_u8(42u8), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f32>::from_i16(42i16), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f32>::from_u16(42u16), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f32>::from_i32(42i32), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f32>::from_u32(42u32), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f32>::from_i64(42i64), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f32>::from_u64(42u64), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f32>::from_isize(42isize), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f32>::from_usize(42usize), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f32>::from_f32(42f32), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f32>::from_f32(42f32), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f32>::from_f64(42f64), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f32>::from_f64(42f64), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f32>::from_f32(Float::nan()), None);
+    assert_eq!(NotNan::<f32>::from_f64(Float::nan()), None);
+}
+
+#[test]
+fn not_nan32_to_primitive() {
+    let x = NotNan::from(42.0f32);
+    assert_eq!(x.to_u8(), Some(42u8));
+    assert_eq!(x.to_i8(), Some(42i8));
+    assert_eq!(x.to_u16(), Some(42u16));
+    assert_eq!(x.to_i16(), Some(42i16));
+    assert_eq!(x.to_u32(), Some(42u32));
+    assert_eq!(x.to_i32(), Some(42i32));
+    assert_eq!(x.to_u64(), Some(42u64));
+    assert_eq!(x.to_i64(), Some(42i64));
+    assert_eq!(x.to_usize(), Some(42usize));
+    assert_eq!(x.to_isize(), Some(42isize));
+    assert_eq!(x.to_f32(), Some(42f32));
+    assert_eq!(x.to_f32(), Some(42f32));
+    assert_eq!(x.to_f64(), Some(42f64));
+    assert_eq!(x.to_f64(), Some(42f64));
+}
+
+#[test]
+fn not_nan32_num() {
+    assert_eq!(NotNan::<f32>::from_str_radix("42.0", 10).unwrap(), NotNan::from(42.0f32));
+    assert!(NotNan::<f32>::from_str_radix("NaN", 10).is_err());
+}
+
+#[test]
+fn not_nan32_signed() {
+    assert_eq!(NotNan::from(42f32).abs(), NotNan::from(42f32));
+    assert_eq!(NotNan::from(-42f32).abs(), NotNan::from(42f32));
+
+    assert_eq!(NotNan::from(50f32).abs_sub(&NotNan::from(8f32)), NotNan::from(42f32));
+    assert_eq!(NotNan::from(8f32).abs_sub(&NotNan::from(50f32)), NotNan::from(0f32));
+}
+
+#[test]
+fn not_nan32_num_cast() {
+    assert_eq!(<NotNan<f32> as num_traits::NumCast>::from(42), Some(NotNan::from(42f32)));
+    assert_eq!(<NotNan<f32> as num_traits::NumCast>::from(f32::nan()), None);
+}
+
+#[test]
+fn ordered_f64_compare_nan() {
+    let f64_nan: f64 = Float::nan();
+    assert_eq!(
+        OrderedFloat(f64_nan).cmp(&OrderedFloat(Float::nan())),
+        Equal
+    );
+    assert_eq!(
+        OrderedFloat(f64_nan).cmp(&OrderedFloat(-100000.0f64)),
+        Greater
+    );
+    assert_eq!(
+        OrderedFloat(-100.0f64).cmp(&OrderedFloat(Float::nan())),
+        Less
+    );
+}
+
+#[test]
+fn ordered_f64_compare_regular_floats_op() {
+    assert!(OrderedFloat(7.0) == OrderedFloat(7.0));
+    assert!(OrderedFloat(7.0) <= OrderedFloat(7.0));
+    assert!(OrderedFloat(7.0) >= OrderedFloat(7.0));
+    assert!(OrderedFloat(8.0) > OrderedFloat(7.0));
+    assert!(OrderedFloat(8.0) >= OrderedFloat(7.0));
+    assert!(OrderedFloat(4.0) < OrderedFloat(7.0));
+    assert!(OrderedFloat(4.0) <= OrderedFloat(7.0));
+}
+
+#[test]
+fn ordered_f64_compare_nan_op() {
+    let f64_nan: OrderedFloat<f64> = OrderedFloat(Float::nan());
+    assert!(f64_nan == f64_nan);
+    assert!(f64_nan <= f64_nan);
+    assert!(f64_nan >= f64_nan);
+    assert!(f64_nan > OrderedFloat(-100000.0));
+    assert!(f64_nan >= OrderedFloat(-100000.0));
+    assert!(OrderedFloat(-100.0) < f64_nan);
+    assert!(OrderedFloat(-100.0) <= f64_nan);
+    assert!(f64_nan > OrderedFloat(Float::infinity()));
+    assert!(f64_nan >= OrderedFloat(Float::infinity()));
+    assert!(f64_nan > OrderedFloat(Float::neg_infinity()));
+    assert!(f64_nan >= OrderedFloat(Float::neg_infinity()));
+}
+
+#[test]
+fn not_nan32_compare_regular_floats() {
+    assert_eq!(NotNan::from(7.0f32).cmp(&NotNan::from(7.0)), Equal);
+    assert_eq!(NotNan::from(8.0f32).cmp(&NotNan::from(7.0)), Greater);
+    assert_eq!(NotNan::from(4.0f32).cmp(&NotNan::from(7.0)), Less);
+}
+
+#[test]
+fn not_nan32_fail_when_constructing_with_nan() {
+    let f32_nan: f32 = Float::nan();
+    assert!(NotNan::new(f32_nan).is_err());
+}
+
+#[test]
+fn not_nan32_calculate_correctly() {
+    assert_eq!(
+        *(NotNan::from(5.0f32) + NotNan::from(4.0f32)),
+        5.0f32 + 4.0f32
+    );
+    assert_eq!(*(NotNan::from(5.0f32) + 4.0f32), 5.0f32 + 4.0f32);
+    assert_eq!(
+        *(NotNan::from(5.0f32) - NotNan::from(4.0f32)),
+        5.0f32 - 4.0f32
+    );
+    assert_eq!(*(NotNan::from(5.0f32) - 4.0f32), 5.0f32 - 4.0f32);
+    assert_eq!(
+        *(NotNan::from(5.0f32) * NotNan::from(4.0f32)),
+        5.0f32 * 4.0f32
+    );
+    assert_eq!(*(NotNan::from(5.0f32) * 4.0f32), 5.0f32 * 4.0f32);
+    assert_eq!(
+        *(NotNan::from(8.0f32) / NotNan::from(4.0f32)),
+        8.0f32 / 4.0f32
+    );
+    assert_eq!(*(NotNan::from(8.0f32) / 4.0f32), 8.0f32 / 4.0f32);
+    assert_eq!(
+        *(NotNan::from(8.0f32) % NotNan::from(4.0f32)),
+        8.0f32 % 4.0f32
+    );
+    assert_eq!(*(NotNan::from(8.0f32) % 4.0f32), 8.0f32 % 4.0f32);
+    assert_eq!(*(-NotNan::from(1.0f32)), -1.0f32);
+
+    assert!(panic::catch_unwind(|| NotNan::from(0.0f32) + f32::NAN).is_err());
+    assert!(panic::catch_unwind(|| NotNan::from(0.0f32) - f32::NAN).is_err());
+    assert!(panic::catch_unwind(|| NotNan::from(0.0f32) * f32::NAN).is_err());
+    assert!(panic::catch_unwind(|| NotNan::from(0.0f32) / f32::NAN).is_err());
+    assert!(panic::catch_unwind(|| NotNan::from(0.0f32) % f32::NAN).is_err());
+
+    let mut number = NotNan::from(5.0f32);
+    number += NotNan::from(4.0f32);
+    assert_eq!(*number, 9.0f32);
+    number -= NotNan::from(4.0f32);
+    assert_eq!(*number, 5.0f32);
+    number *= NotNan::from(4.0f32);
+    assert_eq!(*number, 20.0f32);
+    number /= NotNan::from(4.0f32);
+    assert_eq!(*number, 5.0f32);
+    number %= NotNan::from(4.0f32);
+    assert_eq!(*number, 1.0f32);
+
+    number = NotNan::from(5.0f32);
+    number += 4.0f32;
+    assert_eq!(*number, 9.0f32);
+    number -= 4.0f32;
+    assert_eq!(*number, 5.0f32);
+    number *= 4.0f32;
+    assert_eq!(*number, 20.0f32);
+    number /= 4.0f32;
+    assert_eq!(*number, 5.0f32);
+    number %= 4.0f32;
+    assert_eq!(*number, 1.0f32);
+
+    assert!(
+        panic::catch_unwind(|| {
+            let mut tmp = NotNan::from(0.0f32);
+            tmp += f32::NAN;
+        }).is_err()
+    );
+    assert!(
+        panic::catch_unwind(|| {
+            let mut tmp = NotNan::from(0.0f32);
+            tmp -= f32::NAN;
+        }).is_err()
+    );
+    assert!(
+        panic::catch_unwind(|| {
+            let mut tmp = NotNan::from(0.0f32);
+            tmp *= f32::NAN;
+        }).is_err()
+    );
+    assert!(
+        panic::catch_unwind(|| {
+            let mut tmp = NotNan::from(0.0f32);
+            tmp /= f32::NAN;
+        }).is_err()
+    );
+    assert!(
+        panic::catch_unwind(|| {
+            let mut tmp = NotNan::from(0.0f32);
+            tmp %= f32::NAN;
+        }).is_err()
+    );
+}
+
+#[test]
+fn not_nan64_compare_regular_floats() {
+    assert_eq!(NotNan::from(7.0f64).cmp(&NotNan::from(7.0)), Equal);
+    assert_eq!(NotNan::from(8.0f64).cmp(&NotNan::from(7.0)), Greater);
+    assert_eq!(NotNan::from(4.0f64).cmp(&NotNan::from(7.0)), Less);
+}
+
+#[test]
+fn not_nan64_fail_when_constructing_with_nan() {
+    let f64_nan: f64 = Float::nan();
+    assert!(NotNan::new(f64_nan).is_err());
+}
+
+#[test]
+fn not_nan64_calculate_correctly() {
+    assert_eq!(
+        *(NotNan::from(5.0f64) + NotNan::from(4.0f64)),
+        5.0f64 + 4.0f64
+    );
+    assert_eq!(*(NotNan::from(5.0f64) + 4.0f64), 5.0f64 + 4.0f64);
+    assert_eq!(
+        *(NotNan::from(5.0f64) - NotNan::from(4.0f64)),
+        5.0f64 - 4.0f64
+    );
+    assert_eq!(*(NotNan::from(5.0f64) - 4.0f64), 5.0f64 - 4.0f64);
+    assert_eq!(
+        *(NotNan::from(5.0f64) * NotNan::from(4.0f64)),
+        5.0f64 * 4.0f64
+    );
+    assert_eq!(*(NotNan::from(5.0f64) * 4.0f64), 5.0f64 * 4.0f64);
+    assert_eq!(
+        *(NotNan::from(8.0f64) / NotNan::from(4.0f64)),
+        8.0f64 / 4.0f64
+    );
+    assert_eq!(*(NotNan::from(8.0f64) / 4.0f64), 8.0f64 / 4.0f64);
+    assert_eq!(
+        *(NotNan::from(8.0f64) % NotNan::from(4.0f64)),
+        8.0f64 % 4.0f64
+    );
+    assert_eq!(*(NotNan::from(8.0f64) % 4.0f64), 8.0f64 % 4.0f64);
+    assert_eq!(*(-NotNan::from(1.0f64)), -1.0f64);
+
+    assert!(panic::catch_unwind(|| NotNan::from(0.0f64) + f64::NAN).is_err());
+    assert!(panic::catch_unwind(|| NotNan::from(0.0f64) - f64::NAN).is_err());
+    assert!(panic::catch_unwind(|| NotNan::from(0.0f64) * f64::NAN).is_err());
+    assert!(panic::catch_unwind(|| NotNan::from(0.0f64) / f64::NAN).is_err());
+    assert!(panic::catch_unwind(|| NotNan::from(0.0f64) % f64::NAN).is_err());
+
+    let mut number = NotNan::from(5.0f64);
+    number += NotNan::from(4.0f64);
+    assert_eq!(*number, 9.0f64);
+    number -= NotNan::from(4.0f64);
+    assert_eq!(*number, 5.0f64);
+    number *= NotNan::from(4.0f64);
+    assert_eq!(*number, 20.0f64);
+    number /= NotNan::from(4.0f64);
+    assert_eq!(*number, 5.0f64);
+    number %= NotNan::from(4.0f64);
+    assert_eq!(*number, 1.0f64);
+
+    number = NotNan::from(5.0f64);
+    number += 4.0f64;
+    assert_eq!(*number, 9.0f64);
+    number -= 4.0f64;
+    assert_eq!(*number, 5.0f64);
+    number *= 4.0f64;
+    assert_eq!(*number, 20.0f64);
+    number /= 4.0f64;
+    assert_eq!(*number, 5.0f64);
+    number %= 4.0f64;
+    assert_eq!(*number, 1.0f64);
+
+    assert!(
+        panic::catch_unwind(|| {
+            let mut tmp = NotNan::from(0.0f64);
+            tmp += f64::NAN;
+        }).is_err()
+    );
+    assert!(
+        panic::catch_unwind(|| {
+            let mut tmp = NotNan::from(0.0f64);
+            tmp -= f64::NAN;
+        }).is_err()
+    );
+    assert!(
+        panic::catch_unwind(|| {
+            let mut tmp = NotNan::from(0.0f64);
+            tmp *= f64::NAN;
+        }).is_err()
+    );
+    assert!(
+        panic::catch_unwind(|| {
+            let mut tmp = NotNan::from(0.0f64);
+            tmp /= f64::NAN;
+        }).is_err()
+    );
+    assert!(
+        panic::catch_unwind(|| {
+            let mut tmp = NotNan::from(0.0f64);
+            tmp %= f64::NAN;
+        }).is_err()
+    );
+}
+
+#[test]
+fn not_nan64_zero() {
+    assert_eq!(NotNan::<f64>::zero(), NotNan::from(0.0f64));
+    assert!(NotNan::<f64>::zero().is_zero());
+}
+
+#[test]
+fn not_nan64_one() {
+    assert_eq!(NotNan::<f64>::one(), NotNan::from(1.0f64))
+}
+
+#[test]
+fn not_nan64_bounded() {
+    assert_eq!(NotNan::<f64>::min_value(), NotNan::from(<f64 as Bounded>::min_value()));
+    assert_eq!(NotNan::<f64>::max_value(), NotNan::from(<f64 as Bounded>::max_value()));
+}
+
+#[test]
+fn not_nan64_from_primitive() {
+    assert_eq!(NotNan::<f64>::from_i8(42i8), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f64>::from_u8(42u8), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f64>::from_i16(42i16), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f64>::from_u16(42u16), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f64>::from_i32(42i32), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f64>::from_u32(42u32), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f64>::from_i64(42i64), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f64>::from_u64(42u64), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f64>::from_isize(42isize), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f64>::from_usize(42usize), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f64>::from_f64(42f64), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f64>::from_f64(42f64), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f64>::from_f64(42f64), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f64>::from_f64(42f64), Some(NotNan::from(42.0)));
+    assert_eq!(NotNan::<f64>::from_f64(Float::nan()), None);
+    assert_eq!(NotNan::<f64>::from_f64(Float::nan()), None);
+}
+
+#[test]
+fn not_nan64_to_primitive() {
+    let x = NotNan::from(42.0f64);
+    assert_eq!(x.to_u8(), Some(42u8));
+    assert_eq!(x.to_i8(), Some(42i8));
+    assert_eq!(x.to_u16(), Some(42u16));
+    assert_eq!(x.to_i16(), Some(42i16));
+    assert_eq!(x.to_u32(), Some(42u32));
+    assert_eq!(x.to_i32(), Some(42i32));
+    assert_eq!(x.to_u64(), Some(42u64));
+    assert_eq!(x.to_i64(), Some(42i64));
+    assert_eq!(x.to_usize(), Some(42usize));
+    assert_eq!(x.to_isize(), Some(42isize));
+    assert_eq!(x.to_f64(), Some(42f64));
+    assert_eq!(x.to_f64(), Some(42f64));
+    assert_eq!(x.to_f64(), Some(42f64));
+    assert_eq!(x.to_f64(), Some(42f64));
+}
+
+#[test]
+fn not_nan64_num() {
+    assert_eq!(NotNan::<f64>::from_str_radix("42.0", 10).unwrap(), NotNan::from(42.0f64));
+    assert!(NotNan::<f64>::from_str_radix("NaN", 10).is_err());
+}
+
+#[test]
+fn not_nan64_signed() {
+    assert_eq!(NotNan::from(42f64).abs(), NotNan::from(42f64));
+    assert_eq!(NotNan::from(-42f64).abs(), NotNan::from(42f64));
+
+    assert_eq!(NotNan::from(50f64).abs_sub(&NotNan::from(8f64)), NotNan::from(42f64));
+    assert_eq!(NotNan::from(8f64).abs_sub(&NotNan::from(50f64)), NotNan::from(0f64));
+}
+
+#[test]
+fn not_nan64_num_cast() {
+    assert_eq!(<NotNan<f64> as num_traits::NumCast>::from(42), Some(NotNan::from(42f64)));
+    assert_eq!(<NotNan<f64> as num_traits::NumCast>::from(f64::nan()), None);
+}
+
+#[test]
+fn hash_zero_and_neg_zero_to_the_same_hc() {
+    let state = RandomState::new();
+    let mut h1 = state.build_hasher();
+    let mut h2 = state.build_hasher();
+    OrderedFloat::from(0f64).hash(&mut h1);
+    OrderedFloat::from(-0f64).hash(&mut h2);
+    assert_eq!(h1.finish(), h2.finish());
+}
+
+#[test]
+fn hash_inf_and_neg_inf_to_different_hcs() {
+    let state = RandomState::new();
+    let mut h1 = state.build_hasher();
+    let mut h2 = state.build_hasher();
+    OrderedFloat::from(f64::INFINITY).hash(&mut h1);
+    OrderedFloat::from(f64::NEG_INFINITY).hash(&mut h2);
+    assert!(h1.finish() != h2.finish());
+}
+
+#[test]
+fn hash_is_good_for_whole_numbers() {
+    let state = RandomState::new();
+    let limit = 10000;
+
+    let mut set = ::std::collections::HashSet::with_capacity(limit);
+    for i in 0..limit {
+        let mut h = state.build_hasher();
+        OrderedFloat::from(i as f64).hash(&mut h);
+        set.insert(h.finish());
+    }
+
+    // This allows 100 collisions, which is far too
+    // many, but should guard against transient issues
+    // that will result from using RandomState
+    let pct_unique = set.len() as f64 / limit as f64;
+    assert!(0.99f64 < pct_unique, "percent-unique={}", pct_unique);
+}
+
+#[test]
+fn hash_is_good_for_fractional_numbers() {
+    let state = RandomState::new();
+    let limit = 10000;
+
+    let mut set = ::std::collections::HashSet::with_capacity(limit);
+    for i in 0..limit {
+        let mut h = state.build_hasher();
+        OrderedFloat::from(i as f64 * (1f64 / limit as f64)).hash(&mut h);
+        set.insert(h.finish());
+    }
+
+    // This allows 100 collisions, which is far too
+    // many, but should guard against transient issues
+    // that will result from using RandomState
+    let pct_unique = set.len() as f64 / limit as f64;
+    assert!(0.99f64 < pct_unique, "percent-unique={}", pct_unique);
+}
+
+#[test]
+#[should_panic]
+fn test_add_fails_on_nan() {
+    let a = NotNan::new(std::f32::INFINITY).unwrap();
+    let b = NotNan::new(std::f32::NEG_INFINITY).unwrap();
+    let _c = a + b;
+}
diff --git a/rustc_deps/vendor/ordered-float/tests/test_deprecated_names.rs b/rustc_deps/vendor/ordered-float/tests/test_deprecated_names.rs
new file mode 100644
index 0000000..78f8e06
--- /dev/null
+++ b/rustc_deps/vendor/ordered-float/tests/test_deprecated_names.rs
@@ -0,0 +1,526 @@
+#![allow(deprecated)]
+
+extern crate num_traits;
+extern crate ordered_float;
+
+pub use ordered_float::*;
+pub use num_traits::{Bounded, Float, FromPrimitive, Num, One, Signed, ToPrimitive, Zero};
+pub use std::cmp::Ordering::*;
+pub use std::{f32, f64, panic};
+
+pub use std::collections::hash_map::RandomState;
+pub use std::collections::HashSet;
+pub use std::hash::*;
+
+#[test]
+fn ordered_f32_compare_regular_floats() {
+    assert_eq!(OrderedFloat(7.0f32).cmp(&OrderedFloat(7.0)), Equal);
+    assert_eq!(OrderedFloat(8.0f32).cmp(&OrderedFloat(7.0)), Greater);
+    assert_eq!(OrderedFloat(4.0f32).cmp(&OrderedFloat(7.0)), Less);
+}
+
+#[test]
+fn ordered_f32_compare_regular_floats_op() {
+    assert!(OrderedFloat(7.0f32) == OrderedFloat(7.0));
+    assert!(OrderedFloat(7.0f32) <= OrderedFloat(7.0));
+    assert!(OrderedFloat(7.0f32) >= OrderedFloat(7.0));
+    assert!(OrderedFloat(8.0f32) > OrderedFloat(7.0));
+    assert!(OrderedFloat(8.0f32) >= OrderedFloat(7.0));
+    assert!(OrderedFloat(4.0f32) < OrderedFloat(7.0));
+    assert!(OrderedFloat(4.0f32) <= OrderedFloat(7.0));
+}
+
+#[test]
+fn ordered_f32_compare_nan() {
+    let f32_nan: f32 = Float::nan();
+    assert_eq!(OrderedFloat(f32_nan).cmp(&OrderedFloat(Float::nan())), Equal);
+    assert_eq!(OrderedFloat(f32_nan).cmp(&OrderedFloat(-100000.0f32)), Greater);
+    assert_eq!(OrderedFloat(-100.0f32).cmp(&OrderedFloat(Float::nan())), Less);
+}
+
+#[test]
+fn ordered_f32_compare_nan_op() {
+    let f32_nan: OrderedFloat<f32> = OrderedFloat(Float::nan());
+    assert!(f32_nan == f32_nan);
+    assert!(f32_nan <= f32_nan);
+    assert!(f32_nan >= f32_nan);
+    assert!(f32_nan > OrderedFloat(-100000.0f32));
+    assert!(f32_nan >= OrderedFloat(-100000.0f32));
+    assert!(OrderedFloat(-100.0f32) < f32_nan);
+    assert!(OrderedFloat(-100.0f32) <= f32_nan);
+    assert!(f32_nan > OrderedFloat(Float::infinity()));
+    assert!(f32_nan >= OrderedFloat(Float::infinity()));
+    assert!(f32_nan > OrderedFloat(Float::neg_infinity()));
+    assert!(f32_nan >= OrderedFloat(Float::neg_infinity()));
+}
+
+#[test]
+fn ordered_f64_compare_regular_floats() {
+    assert_eq!(OrderedFloat(7.0f64).cmp(&OrderedFloat(7.0)), Equal);
+    assert_eq!(OrderedFloat(8.0f64).cmp(&OrderedFloat(7.0)), Greater);
+    assert_eq!(OrderedFloat(4.0f64).cmp(&OrderedFloat(7.0)), Less);
+}
+
+#[test]
+fn not_nan32_zero() {
+    assert_eq!(NotNaN::<f32>::zero(), NotNaN::from(0.0f32));
+    assert!(NotNaN::<f32>::zero().is_zero());
+}
+
+#[test]
+fn not_nan32_one() {
+    assert_eq!(NotNaN::<f32>::one(), NotNaN::from(1.0f32))
+}
+
+#[test]
+fn not_nan32_bounded() {
+    assert_eq!(NotNaN::<f32>::min_value(), NotNaN::from(<f32 as Bounded>::min_value()));
+    assert_eq!(NotNaN::<f32>::max_value(), NotNaN::from(<f32 as Bounded>::max_value()));
+}
+
+#[test]
+fn not_nan32_from_primitive() {
+    assert_eq!(NotNaN::<f32>::from_i8(42i8), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f32>::from_u8(42u8), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f32>::from_i16(42i16), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f32>::from_u16(42u16), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f32>::from_i32(42i32), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f32>::from_u32(42u32), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f32>::from_i64(42i64), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f32>::from_u64(42u64), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f32>::from_isize(42isize), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f32>::from_usize(42usize), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f32>::from_f32(42f32), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f32>::from_f32(42f32), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f32>::from_f64(42f64), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f32>::from_f64(42f64), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f32>::from_f32(Float::nan()), None);
+    assert_eq!(NotNaN::<f32>::from_f64(Float::nan()), None);
+}
+
+#[test]
+fn not_nan32_to_primitive() {
+    let x = NotNaN::from(42.0f32);
+    assert_eq!(x.to_u8(), Some(42u8));
+    assert_eq!(x.to_i8(), Some(42i8));
+    assert_eq!(x.to_u16(), Some(42u16));
+    assert_eq!(x.to_i16(), Some(42i16));
+    assert_eq!(x.to_u32(), Some(42u32));
+    assert_eq!(x.to_i32(), Some(42i32));
+    assert_eq!(x.to_u64(), Some(42u64));
+    assert_eq!(x.to_i64(), Some(42i64));
+    assert_eq!(x.to_usize(), Some(42usize));
+    assert_eq!(x.to_isize(), Some(42isize));
+    assert_eq!(x.to_f32(), Some(42f32));
+    assert_eq!(x.to_f32(), Some(42f32));
+    assert_eq!(x.to_f64(), Some(42f64));
+    assert_eq!(x.to_f64(), Some(42f64));
+}
+
+#[test]
+fn not_nan32_num() {
+    assert_eq!(NotNaN::<f32>::from_str_radix("42.0", 10).unwrap(), NotNaN::from(42.0f32));
+    assert!(NotNaN::<f32>::from_str_radix("NaN", 10).is_err());
+}
+
+#[test]
+fn not_nan32_signed() {
+    assert_eq!(NotNaN::from(42f32).abs(), NotNaN::from(42f32));
+    assert_eq!(NotNaN::from(-42f32).abs(), NotNaN::from(42f32));
+
+    assert_eq!(NotNaN::from(50f32).abs_sub(&NotNaN::from(8f32)), NotNaN::from(42f32));
+    assert_eq!(NotNaN::from(8f32).abs_sub(&NotNaN::from(50f32)), NotNaN::from(0f32));
+}
+
+#[test]
+fn not_nan32_num_cast() {
+    assert_eq!(<NotNaN<f32> as num_traits::NumCast>::from(42), Some(NotNaN::from(42f32)));
+    assert_eq!(<NotNaN<f32> as num_traits::NumCast>::from(f32::nan()), None);
+}
+
+#[test]
+fn ordered_f64_compare_nan() {
+    let f64_nan: f64 = Float::nan();
+    assert_eq!(
+        OrderedFloat(f64_nan).cmp(&OrderedFloat(Float::nan())),
+        Equal
+    );
+    assert_eq!(
+        OrderedFloat(f64_nan).cmp(&OrderedFloat(-100000.0f64)),
+        Greater
+    );
+    assert_eq!(
+        OrderedFloat(-100.0f64).cmp(&OrderedFloat(Float::nan())),
+        Less
+    );
+}
+
+#[test]
+fn ordered_f64_compare_regular_floats_op() {
+    assert!(OrderedFloat(7.0) == OrderedFloat(7.0));
+    assert!(OrderedFloat(7.0) <= OrderedFloat(7.0));
+    assert!(OrderedFloat(7.0) >= OrderedFloat(7.0));
+    assert!(OrderedFloat(8.0) > OrderedFloat(7.0));
+    assert!(OrderedFloat(8.0) >= OrderedFloat(7.0));
+    assert!(OrderedFloat(4.0) < OrderedFloat(7.0));
+    assert!(OrderedFloat(4.0) <= OrderedFloat(7.0));
+}
+
+#[test]
+fn ordered_f64_compare_nan_op() {
+    let f64_nan: OrderedFloat<f64> = OrderedFloat(Float::nan());
+    assert!(f64_nan == f64_nan);
+    assert!(f64_nan <= f64_nan);
+    assert!(f64_nan >= f64_nan);
+    assert!(f64_nan > OrderedFloat(-100000.0));
+    assert!(f64_nan >= OrderedFloat(-100000.0));
+    assert!(OrderedFloat(-100.0) < f64_nan);
+    assert!(OrderedFloat(-100.0) <= f64_nan);
+    assert!(f64_nan > OrderedFloat(Float::infinity()));
+    assert!(f64_nan >= OrderedFloat(Float::infinity()));
+    assert!(f64_nan > OrderedFloat(Float::neg_infinity()));
+    assert!(f64_nan >= OrderedFloat(Float::neg_infinity()));
+}
+
+#[test]
+fn not_nan32_compare_regular_floats() {
+    assert_eq!(NotNaN::from(7.0f32).cmp(&NotNaN::from(7.0)), Equal);
+    assert_eq!(NotNaN::from(8.0f32).cmp(&NotNaN::from(7.0)), Greater);
+    assert_eq!(NotNaN::from(4.0f32).cmp(&NotNaN::from(7.0)), Less);
+}
+
+#[test]
+fn not_nan32_fail_when_constructing_with_nan() {
+    let f32_nan: f32 = Float::nan();
+    assert!(NotNaN::new(f32_nan).is_err());
+}
+
+#[test]
+fn not_nan32_calculate_correctly() {
+    assert_eq!(
+        *(NotNaN::from(5.0f32) + NotNaN::from(4.0f32)),
+        5.0f32 + 4.0f32
+    );
+    assert_eq!(*(NotNaN::from(5.0f32) + 4.0f32), 5.0f32 + 4.0f32);
+    assert_eq!(
+        *(NotNaN::from(5.0f32) - NotNaN::from(4.0f32)),
+        5.0f32 - 4.0f32
+    );
+    assert_eq!(*(NotNaN::from(5.0f32) - 4.0f32), 5.0f32 - 4.0f32);
+    assert_eq!(
+        *(NotNaN::from(5.0f32) * NotNaN::from(4.0f32)),
+        5.0f32 * 4.0f32
+    );
+    assert_eq!(*(NotNaN::from(5.0f32) * 4.0f32), 5.0f32 * 4.0f32);
+    assert_eq!(
+        *(NotNaN::from(8.0f32) / NotNaN::from(4.0f32)),
+        8.0f32 / 4.0f32
+    );
+    assert_eq!(*(NotNaN::from(8.0f32) / 4.0f32), 8.0f32 / 4.0f32);
+    assert_eq!(
+        *(NotNaN::from(8.0f32) % NotNaN::from(4.0f32)),
+        8.0f32 % 4.0f32
+    );
+    assert_eq!(*(NotNaN::from(8.0f32) % 4.0f32), 8.0f32 % 4.0f32);
+    assert_eq!(*(-NotNaN::from(1.0f32)), -1.0f32);
+
+    assert!(panic::catch_unwind(|| NotNaN::from(0.0f32) + f32::NAN).is_err());
+    assert!(panic::catch_unwind(|| NotNaN::from(0.0f32) - f32::NAN).is_err());
+    assert!(panic::catch_unwind(|| NotNaN::from(0.0f32) * f32::NAN).is_err());
+    assert!(panic::catch_unwind(|| NotNaN::from(0.0f32) / f32::NAN).is_err());
+    assert!(panic::catch_unwind(|| NotNaN::from(0.0f32) % f32::NAN).is_err());
+
+    let mut number = NotNaN::from(5.0f32);
+    number += NotNaN::from(4.0f32);
+    assert_eq!(*number, 9.0f32);
+    number -= NotNaN::from(4.0f32);
+    assert_eq!(*number, 5.0f32);
+    number *= NotNaN::from(4.0f32);
+    assert_eq!(*number, 20.0f32);
+    number /= NotNaN::from(4.0f32);
+    assert_eq!(*number, 5.0f32);
+    number %= NotNaN::from(4.0f32);
+    assert_eq!(*number, 1.0f32);
+
+    number = NotNaN::from(5.0f32);
+    number += 4.0f32;
+    assert_eq!(*number, 9.0f32);
+    number -= 4.0f32;
+    assert_eq!(*number, 5.0f32);
+    number *= 4.0f32;
+    assert_eq!(*number, 20.0f32);
+    number /= 4.0f32;
+    assert_eq!(*number, 5.0f32);
+    number %= 4.0f32;
+    assert_eq!(*number, 1.0f32);
+
+    assert!(
+        panic::catch_unwind(|| {
+            let mut tmp = NotNaN::from(0.0f32);
+            tmp += f32::NAN;
+        }).is_err()
+    );
+    assert!(
+        panic::catch_unwind(|| {
+            let mut tmp = NotNaN::from(0.0f32);
+            tmp -= f32::NAN;
+        }).is_err()
+    );
+    assert!(
+        panic::catch_unwind(|| {
+            let mut tmp = NotNaN::from(0.0f32);
+            tmp *= f32::NAN;
+        }).is_err()
+    );
+    assert!(
+        panic::catch_unwind(|| {
+            let mut tmp = NotNaN::from(0.0f32);
+            tmp /= f32::NAN;
+        }).is_err()
+    );
+    assert!(
+        panic::catch_unwind(|| {
+            let mut tmp = NotNaN::from(0.0f32);
+            tmp %= f32::NAN;
+        }).is_err()
+    );
+}
+
+#[test]
+fn not_nan64_compare_regular_floats() {
+    assert_eq!(NotNaN::from(7.0f64).cmp(&NotNaN::from(7.0)), Equal);
+    assert_eq!(NotNaN::from(8.0f64).cmp(&NotNaN::from(7.0)), Greater);
+    assert_eq!(NotNaN::from(4.0f64).cmp(&NotNaN::from(7.0)), Less);
+}
+
+#[test]
+fn not_nan64_fail_when_constructing_with_nan() {
+    let f64_nan: f64 = Float::nan();
+    assert!(NotNaN::new(f64_nan).is_err());
+}
+
+#[test]
+fn not_nan64_calculate_correctly() {
+    assert_eq!(
+        *(NotNaN::from(5.0f64) + NotNaN::from(4.0f64)),
+        5.0f64 + 4.0f64
+    );
+    assert_eq!(*(NotNaN::from(5.0f64) + 4.0f64), 5.0f64 + 4.0f64);
+    assert_eq!(
+        *(NotNaN::from(5.0f64) - NotNaN::from(4.0f64)),
+        5.0f64 - 4.0f64
+    );
+    assert_eq!(*(NotNaN::from(5.0f64) - 4.0f64), 5.0f64 - 4.0f64);
+    assert_eq!(
+        *(NotNaN::from(5.0f64) * NotNaN::from(4.0f64)),
+        5.0f64 * 4.0f64
+    );
+    assert_eq!(*(NotNaN::from(5.0f64) * 4.0f64), 5.0f64 * 4.0f64);
+    assert_eq!(
+        *(NotNaN::from(8.0f64) / NotNaN::from(4.0f64)),
+        8.0f64 / 4.0f64
+    );
+    assert_eq!(*(NotNaN::from(8.0f64) / 4.0f64), 8.0f64 / 4.0f64);
+    assert_eq!(
+        *(NotNaN::from(8.0f64) % NotNaN::from(4.0f64)),
+        8.0f64 % 4.0f64
+    );
+    assert_eq!(*(NotNaN::from(8.0f64) % 4.0f64), 8.0f64 % 4.0f64);
+    assert_eq!(*(-NotNaN::from(1.0f64)), -1.0f64);
+
+    assert!(panic::catch_unwind(|| NotNaN::from(0.0f64) + f64::NAN).is_err());
+    assert!(panic::catch_unwind(|| NotNaN::from(0.0f64) - f64::NAN).is_err());
+    assert!(panic::catch_unwind(|| NotNaN::from(0.0f64) * f64::NAN).is_err());
+    assert!(panic::catch_unwind(|| NotNaN::from(0.0f64) / f64::NAN).is_err());
+    assert!(panic::catch_unwind(|| NotNaN::from(0.0f64) % f64::NAN).is_err());
+
+    let mut number = NotNaN::from(5.0f64);
+    number += NotNaN::from(4.0f64);
+    assert_eq!(*number, 9.0f64);
+    number -= NotNaN::from(4.0f64);
+    assert_eq!(*number, 5.0f64);
+    number *= NotNaN::from(4.0f64);
+    assert_eq!(*number, 20.0f64);
+    number /= NotNaN::from(4.0f64);
+    assert_eq!(*number, 5.0f64);
+    number %= NotNaN::from(4.0f64);
+    assert_eq!(*number, 1.0f64);
+
+    number = NotNaN::from(5.0f64);
+    number += 4.0f64;
+    assert_eq!(*number, 9.0f64);
+    number -= 4.0f64;
+    assert_eq!(*number, 5.0f64);
+    number *= 4.0f64;
+    assert_eq!(*number, 20.0f64);
+    number /= 4.0f64;
+    assert_eq!(*number, 5.0f64);
+    number %= 4.0f64;
+    assert_eq!(*number, 1.0f64);
+
+    assert!(
+        panic::catch_unwind(|| {
+            let mut tmp = NotNaN::from(0.0f64);
+            tmp += f64::NAN;
+        }).is_err()
+    );
+    assert!(
+        panic::catch_unwind(|| {
+            let mut tmp = NotNaN::from(0.0f64);
+            tmp -= f64::NAN;
+        }).is_err()
+    );
+    assert!(
+        panic::catch_unwind(|| {
+            let mut tmp = NotNaN::from(0.0f64);
+            tmp *= f64::NAN;
+        }).is_err()
+    );
+    assert!(
+        panic::catch_unwind(|| {
+            let mut tmp = NotNaN::from(0.0f64);
+            tmp /= f64::NAN;
+        }).is_err()
+    );
+    assert!(
+        panic::catch_unwind(|| {
+            let mut tmp = NotNaN::from(0.0f64);
+            tmp %= f64::NAN;
+        }).is_err()
+    );
+}
+
+#[test]
+fn not_nan64_zero() {
+    assert_eq!(NotNaN::<f64>::zero(), NotNaN::from(0.0f64));
+    assert!(NotNaN::<f64>::zero().is_zero());
+}
+
+#[test]
+fn not_nan64_one() {
+    assert_eq!(NotNaN::<f64>::one(), NotNaN::from(1.0f64))
+}
+
+#[test]
+fn not_nan64_bounded() {
+    assert_eq!(NotNaN::<f64>::min_value(), NotNaN::from(<f64 as Bounded>::min_value()));
+    assert_eq!(NotNaN::<f64>::max_value(), NotNaN::from(<f64 as Bounded>::max_value()));
+}
+
+#[test]
+fn not_nan64_from_primitive() {
+    assert_eq!(NotNaN::<f64>::from_i8(42i8), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f64>::from_u8(42u8), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f64>::from_i16(42i16), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f64>::from_u16(42u16), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f64>::from_i32(42i32), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f64>::from_u32(42u32), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f64>::from_i64(42i64), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f64>::from_u64(42u64), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f64>::from_isize(42isize), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f64>::from_usize(42usize), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f64>::from_f64(42f64), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f64>::from_f64(42f64), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f64>::from_f64(42f64), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f64>::from_f64(42f64), Some(NotNaN::from(42.0)));
+    assert_eq!(NotNaN::<f64>::from_f64(Float::nan()), None);
+    assert_eq!(NotNaN::<f64>::from_f64(Float::nan()), None);
+}
+
+#[test]
+fn not_nan64_to_primitive() {
+    let x = NotNaN::from(42.0f64);
+    assert_eq!(x.to_u8(), Some(42u8));
+    assert_eq!(x.to_i8(), Some(42i8));
+    assert_eq!(x.to_u16(), Some(42u16));
+    assert_eq!(x.to_i16(), Some(42i16));
+    assert_eq!(x.to_u32(), Some(42u32));
+    assert_eq!(x.to_i32(), Some(42i32));
+    assert_eq!(x.to_u64(), Some(42u64));
+    assert_eq!(x.to_i64(), Some(42i64));
+    assert_eq!(x.to_usize(), Some(42usize));
+    assert_eq!(x.to_isize(), Some(42isize));
+    assert_eq!(x.to_f64(), Some(42f64));
+    assert_eq!(x.to_f64(), Some(42f64));
+    assert_eq!(x.to_f64(), Some(42f64));
+    assert_eq!(x.to_f64(), Some(42f64));
+}
+
+#[test]
+fn not_nan64_num() {
+    assert_eq!(NotNaN::<f64>::from_str_radix("42.0", 10).unwrap(), NotNaN::from(42.0f64));
+    assert!(NotNaN::<f64>::from_str_radix("NaN", 10).is_err());
+}
+
+#[test]
+fn not_nan64_signed() {
+    assert_eq!(NotNaN::from(42f64).abs(), NotNaN::from(42f64));
+    assert_eq!(NotNaN::from(-42f64).abs(), NotNaN::from(42f64));
+
+    assert_eq!(NotNaN::from(50f64).abs_sub(&NotNaN::from(8f64)), NotNaN::from(42f64));
+    assert_eq!(NotNaN::from(8f64).abs_sub(&NotNaN::from(50f64)), NotNaN::from(0f64));
+}
+
+#[test]
+fn not_nan64_num_cast() {
+    assert_eq!(<NotNaN<f64> as num_traits::NumCast>::from(42), Some(NotNaN::from(42f64)));
+    assert_eq!(<NotNaN<f64> as num_traits::NumCast>::from(f64::nan()), None);
+}
+
+#[test]
+fn hash_zero_and_neg_zero_to_the_same_hc() {
+    let state = RandomState::new();
+    let mut h1 = state.build_hasher();
+    let mut h2 = state.build_hasher();
+    OrderedFloat::from(0f64).hash(&mut h1);
+    OrderedFloat::from(-0f64).hash(&mut h2);
+    assert_eq!(h1.finish(), h2.finish());
+}
+
+#[test]
+fn hash_inf_and_neg_inf_to_different_hcs() {
+    let state = RandomState::new();
+    let mut h1 = state.build_hasher();
+    let mut h2 = state.build_hasher();
+    OrderedFloat::from(f64::INFINITY).hash(&mut h1);
+    OrderedFloat::from(f64::NEG_INFINITY).hash(&mut h2);
+    assert!(h1.finish() != h2.finish());
+}
+
+#[test]
+fn hash_is_good_for_whole_numbers() {
+    let state = RandomState::new();
+    let limit = 10000;
+
+    let mut set = ::std::collections::HashSet::with_capacity(limit);
+    for i in 0..limit {
+        let mut h = state.build_hasher();
+        OrderedFloat::from(i as f64).hash(&mut h);
+        set.insert(h.finish());
+    }
+
+    // This allows 100 collisions, which is far too
+    // many, but should guard against transient issues
+    // that will result from using RandomState
+    let pct_unique = set.len() as f64 / limit as f64;
+    assert!(0.99f64 < pct_unique, "percent-unique={}", pct_unique);
+}
+
+#[test]
+fn hash_is_good_for_fractional_numbers() {
+    let state = RandomState::new();
+    let limit = 10000;
+
+    let mut set = ::std::collections::HashSet::with_capacity(limit);
+    for i in 0..limit {
+        let mut h = state.build_hasher();
+        OrderedFloat::from(i as f64 * (1f64 / limit as f64)).hash(&mut h);
+        set.insert(h.finish());
+    }
+
+    // This allows 100 collisions, which is far too
+    // many, but should guard against transient issues
+    // that will result from using RandomState
+    let pct_unique = set.len() as f64 / limit as f64;
+    assert!(0.99f64 < pct_unique, "percent-unique={}", pct_unique);
+}
diff --git a/rustc_deps/vendor/rusttype/.cargo-checksum.json b/rustc_deps/vendor/rusttype/.cargo-checksum.json
new file mode 100644
index 0000000..77fb73c
--- /dev/null
+++ b/rustc_deps/vendor/rusttype/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"b336a7a4159cafed0157d66ca570f070b153b8097b812858a35b67edbd419ca1","Cargo.toml":"130693b0fff87992f5b1b41952324a0a7310aa2438844f09e5be12ee1ff3b00b","LICENSE-APACHE":"000b4962e6b27176a0ff89cce4be555b16472cafb5671eb2804a8fdac6854793","LICENSE-MIT":"fd198949ebcc78b2d12fc57ebfb2da4ae8f781b7c3b7047aaccc2f804b6f12ef","README.md":"5c0750e04c8a26e1383827b6c10b47a39ea82f81023391c4edbff996368a0d21","benches/cache.rs":"0878489bb22497b2f69f6bfd4985a8da898cce3233d3cb21b954b4a5e0546284","benches/draw.rs":"c33a9b163bd2e3dc5afa3702ab01e7cb93be263c4f1d66347db444ece6a48cf0","examples/gpu_cache.rs":"fb998b128640905bb69e75cfc3be734da0c06e628e40417e280b5e6a566eb74b","examples/image.rs":"a952e20b217754ac24e3dd3ec726f46635fc534e20d79ac8dff3f7aa08bbc5bb","examples/simple.rs":"42b3981b4e5ba133cf9f9a0eb47f57424ad97e9e4721c2a385f9a1ea90564e7d","rustfmt.toml":"ed17bf27c3712b8f22ec7a2a9d8e5d9d2a5654299754fb93e9ac76ef6d153114","src/geometry.rs":"163f5dfd3c431c41374bcf4df44f807da8eb634ec90965f2c258b807dde209d9","src/gpu_cache.rs":"e58ca212ce3ddfb67a5083fc1a5f4d5f20fd028b3186496524624b7ebb723c95","src/lib.rs":"56265b7f97db3bb24aeacd7be2d1f7b4675a97bd4dd24f2129b7ebcca2e6a2b3","src/rasterizer.rs":"a1dcbfaffe3bea68e5adfac7c44e097dd7648b130a2c790b6ed0c9622f7c16e2","tests/issues.rs":"953eb96cf4242e0f739105083bc54598ffc7708b5a6bea2e72e58efd381210ba","tests/lipsum.txt":"0e26c67bc34ba4c083a384468c0c3698800147f05afd13007cd44c5e4d799477","tests/reference_big_biohazard.png":"1f9a4fc9c6357d5462157c49f023d7be3805332be8b8dc85752b0ac0fa485e6a","tests/reference_iota.png":"83824e69dd00c9547a64a2f86a200fe58610bf02c2191044fa22942c56837d57","tests/reference_w.png":"6938997b5d4e798d90ea9ab7dc352c3807a17f974f6cf577963c827a5fc59a28","tests/render_reference.rs":"d501a73513922ab97500af6e25c71c7e4b7623b8bfc703d435c61a8500d5fd15"},"package":"436c67ae0d0d24f14e1177c3ed96780ee16db82b405f0fba1bb80b46c9a30625"}
\ No newline at end of file
diff --git a/rustc_deps/vendor/rusttype/CHANGELOG.md b/rustc_deps/vendor/rusttype/CHANGELOG.md
new file mode 100644
index 0000000..dce9d3c
--- /dev/null
+++ b/rustc_deps/vendor/rusttype/CHANGELOG.md
@@ -0,0 +1,136 @@
+## master
+
+## 0.7.3
+* gpu_cache: Update crossbeam-utils -> `0.6`
+
+## 0.7.2
+* Update ordered-float -> `1`
+
+## 0.7.1
+* Fix `PositionedGlyph::pixel_bounding_box()` size inconsistencies at different positions with identical sub-pixel positions.
+
+## 0.7
+
+* Rework `CacheBuilder` to use methods to allow non-breaking additions
+  in future. New style is `Cache::builder().dimensions(512, 512).build()`.
+* Support multithreaded rasterization in the gpu_cache. This yields
+  significant improvements in worst case performance when more than 1
+  CPU core is available. _Thrashing, resizing & population benchmarks
+  are ~3x faster on a 4-core Haswell._
+  Multithreading is enabled by default in environments with more than
+  a single core, but can be explicitly disabled using
+  `Cache::builder().multithread(false)`.
+* Remove all deprecated API.
+* Add `Debug` implementations for `Font`, `Glyph`, `ScaledGlyph` &
+  `PositionedGlyph`
+* Add and improve documentation + examples.
+
+## 0.6.5
+
+* Re-export rusttype `0.7` non-breaking main API, while keeping the current
+  version of the gpu_cache module.
+
+## 0.6.4
+
+* Add `CacheBuilder::rebuild` & `Cache::to_builder` methods.
+* gpu_cache: Only rasterize & upload after queue has successfully fit in cache
+  producing a 1.16-1.29x speedup in resizing & thrashing benchmarks.
+
+## 0.6.3
+
+* Documentation clarifications
+* Avoid depending on unused dependency default-features
+
+## 0.6.2
+
+* Add `From<&AsRef<[u8]>> for SharedBytes`.
+* Optimise `gpu_cache` hashing to improve benchmark performance by ~30%.
+
+## 0.6.1
+
+* Optimise rasterizer removing internal hashing. Improves draw benchmark
+  performance by 11-91%.
+
+## 0.6
+
+* Rework gpu_cache data structures allowing constant time hash lookup
+  of matching cached glyph textures. Improve performance by ~60-200%.
+* Deprecate `gpu_cache::Cache::new` in favour of `gpu_cache::CacheBuilder`.
+* Deprecate `gpu_cache::Cache::set_scale_tolerance` &
+  `gpu_cache::Cache::set_position_tolerance`. These are now equivalent to
+  recreating the cache as they invalidate the cache keys.
+* gpu_cache `scale_tolerance` & `position_tolerance` now have subtly different
+  meanings but guarantee their error in all cases, where previously the
+  worst case was double the set tolerance.
+
+## 0.5.2
+
+* Add gpu cache glyph padding option to fix texture bleeding from other
+  glyphs when using interpolated texture coordinates near edges. Use
+  `CacheBuilder` to construct a `Cache` that makes use of padding.
+* Inlining performance improvements.
+
+## 0.5.1
+
+* Fix tree removal on row clear (gpu_cache).
+
+## 0.5
+
+* Let functions like `Font::glyph` and `Font::pair_kerning` work with both
+  characters and glyph ids by having them accept any type that implements the
+  new `IntoGlyphId` trait. This replaces the `CodepointOrGlyph` enum, which
+  didn't seem widely used.
+* Make `Font::glyph` always return a `Glyph`, not `Option<Glyph>`. Passing a
+  `char` the font doesn't cover returns a `.notdef` glyph (id 0), as it did
+  before. Passing an invalid glyph id now panics, like a bad array index: glyph
+  ids should only be used to index the font they were looked up for.
+* Introduce `rusttype::Error`, which implements `std::error::Error`, `Debug` and
+  `Display`, and can be converted to `std::io::Error`.
+* Use `Result<_, rusttype::Error>` to report failures in FontCollection, Font
+  and associated iterators.
+* Add `Font::from_bytes` method similar to `FontCollection::from_bytes` for 1
+  font collections.
+* Improve gpu_cache performance ~2-6%
+
+## 0.4.3
+
+* Improve gpu_cache performance ~6-17%
+
+## 0.4.2
+
+* Allow users to get font names from `Font`. (#86)
+
+## 0.4
+
+* Add more debugging features
+* Add support for unscaled fonts
+* Improve performance
+* Make gpu_cache optional
+
+## 0.3
+
+* Transfer to redox-os organization, merge a number of pull requests
+
+## 0.2.1
+
+* Made the API more convenient (courtesy of @mitchmindtree, @I1048576).
+* Fixes for the examples (@I1048576)
+* Removed the dependency on ndarray (@I1048576)
+
+## 0.2
+
+* Initial GPU caching implementation.
+* Made font data management more flexible.
+* Made the interface for font scales simpler.
+
+## 0.1.2
+
+Fixed issue #8
+
+## 0.1.1
+
+Fixed issue #7
+
+## 0.1
+
+Initial release
diff --git a/rustc_deps/vendor/rusttype/Cargo.toml b/rustc_deps/vendor/rusttype/Cargo.toml
new file mode 100644
index 0000000..2624a5b
--- /dev/null
+++ b/rustc_deps/vendor/rusttype/Cargo.toml
@@ -0,0 +1,89 @@
+# 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 = "rusttype"
+version = "0.7.3"
+authors = ["Dylan Ede <dylanede@googlemail.com>", "Jeremy Soller <jackpot51@gmail.com>", "Alex Butler <alexheretic@gmail.com>"]
+exclude = ["/fonts/**"]
+description = "A pure Rust alternative to libraries like FreeType.\n\nRustType provides an API for loading, querying and rasterising TrueType fonts.\n\nIt also provides an implementation of a dynamic GPU glyph cache for hardware font rendering.\n"
+homepage = "https://gitlab.redox-os.org/redox-os/rusttype"
+documentation = "https://docs.rs/rusttype"
+readme = "README.md"
+keywords = ["font", "truetype", "opentype", "ttf", "otf"]
+license = "MIT / Apache-2.0"
+repository = "https://gitlab.redox-os.org/redox-os/rusttype"
+[package.metadata.docs.rs]
+features = ["gpu_cache"]
+
+[[example]]
+name = "gpu_cache"
+required-features = ["gpu_cache"]
+
+[[example]]
+name = "image"
+
+[[example]]
+name = "simple"
+[dependencies.approx]
+version = "0.3"
+default-features = false
+
+[dependencies.arrayvec]
+version = "0.4"
+default-features = false
+
+[dependencies.crossbeam-deque]
+version = "0.6"
+optional = true
+
+[dependencies.crossbeam-utils]
+version = "0.6"
+optional = true
+
+[dependencies.linked-hash-map]
+version = "0.5"
+optional = true
+
+[dependencies.num_cpus]
+version = "1.0"
+optional = true
+
+[dependencies.ordered-float]
+version = "1"
+
+[dependencies.rustc-hash]
+version = "1"
+optional = true
+
+[dependencies.stb_truetype]
+version = "0.2.2"
+[dev-dependencies.blake2]
+version = "0.8"
+
+[dev-dependencies.glium]
+version = "0.22"
+
+[dev-dependencies.image]
+version = "0.20"
+features = ["png_codec"]
+default-features = false
+
+[dev-dependencies.lazy_static]
+version = "1"
+
+[dev-dependencies.unicode-normalization]
+version = "0.1"
+
+[features]
+bench = ["gpu_cache"]
+gpu_cache = ["linked-hash-map", "rustc-hash", "crossbeam-deque", "crossbeam-utils", "num_cpus"]
diff --git a/rustc_deps/vendor/rusttype/LICENSE-APACHE b/rustc_deps/vendor/rusttype/LICENSE-APACHE
new file mode 100644
index 0000000..6f75635
--- /dev/null
+++ b/rustc_deps/vendor/rusttype/LICENSE-APACHE
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "{}"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/rustc_deps/vendor/rusttype/LICENSE-MIT b/rustc_deps/vendor/rusttype/LICENSE-MIT
new file mode 100644
index 0000000..93cbd53
--- /dev/null
+++ b/rustc_deps/vendor/rusttype/LICENSE-MIT
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Dylan Ede
+
+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.
diff --git a/rustc_deps/vendor/rusttype/README.md b/rustc_deps/vendor/rusttype/README.md
new file mode 100644
index 0000000..798833c
--- /dev/null
+++ b/rustc_deps/vendor/rusttype/README.md
@@ -0,0 +1,77 @@
+# RustType
+[![crates.io](https://img.shields.io/crates/v/rusttype.svg)](https://crates.io/crates/rusttype)
+[![docs.rs](https://docs.rs/rusttype/badge.svg)](https://docs.rs/rusttype)
+
+RustType is a pure Rust alternative to libraries like FreeType.
+
+The current capabilities of RustType:
+
+* Reading TrueType formatted fonts and font collections. This includes `*.ttf`
+  as well as a subset of `*.otf` font files.
+* Retrieving glyph shapes and commonly used properties for a font and its glyphs.
+* Laying out glyphs horizontally using horizontal and vertical metrics, and
+  glyph-pair-specific kerning.
+* Rasterising glyphs with sub-pixel positioning using an accurate analytical
+  algorithm (not based on sampling).
+* Managing a font cache on the GPU with the `gpu_cache` module. This keeps
+  recently used glyph renderings
+  in a dynamic cache in GPU memory to minimise texture uploads per-frame. It
+  also allows you keep the draw call count for text very low, as all glyphs are
+  kept in one GPU texture.
+
+Notable things that RustType does not support *yet*:
+
+* OpenType formatted fonts that are not just TrueType fonts (OpenType is a
+  superset of TrueType). Notably there is no support yet for cubic Bezier curves
+  used in glyphs.
+* Font hinting.
+* Ligatures of any kind
+* Some less common TrueType sub-formats.
+* Right-to-left and vertical text layout.
+
+## Getting Started
+
+To hit the ground running with RustType, look at the `simple.rs` example
+supplied with the crate. It demonstrates loading a font file, rasterising an
+arbitrary string, and displaying the result as ASCII art. If you prefer to just
+look at the documentation, the entry point for loading fonts is
+`FontCollection`, from which you can access individual fonts, then their glyphs.
+
+## Future Plans
+
+The initial motivation for the project was to provide easy-to-use font rendering for games.
+There are numerous avenues for improving RustType. Ideas:
+
+* Some form of hinting for improved legibility at small font sizes.
+* Replacing the dependency on
+  [stb_truetype-rs](https://gitlab.redox-os.org/redox-os/stb_truetype-rs)
+  (a translation of [stb_truetype.h](https://github.com/nothings/stb/blob/master/stb_truetype.h)),
+  with OpenType font loading written in idiomatic Rust.
+* Add support for cubic curves in OpenType fonts.
+* Extract the rasterisation code into a separate vector graphics rendering crate.
+* Support for some common forms of ligatures.
+* And, eventually, support for embedded right-to-left Unicode text.
+
+If you think you could help with achieving any of these goals, feel free to open
+a tracking issue for discussing them.
+
+## License
+
+Licensed under either of
+
+ * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
+   http://www.apache.org/licenses/LICENSE-2.0)
+ * MIT license ([LICENSE-MIT](LICENSE-MIT) or
+   http://opensource.org/licenses/MIT)
+
+at your option.
+
+### Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
+dual licensed as above, without any additional terms or conditions.
+
+### See Also
+
+- [glyph_brush](https://github.com/alexheretic/glyph-brush) - can cache vertex generation & provides more complex layouts.
diff --git a/rustc_deps/vendor/rusttype/benches/cache.rs b/rustc_deps/vendor/rusttype/benches/cache.rs
new file mode 100644
index 0000000..9a72055
--- /dev/null
+++ b/rustc_deps/vendor/rusttype/benches/cache.rs
@@ -0,0 +1,413 @@
+#![feature(test)]
+#![cfg(feature = "gpu_cache")]
+
+extern crate rusttype;
+extern crate test;
+#[macro_use]
+extern crate lazy_static;
+extern crate unicode_normalization;
+
+use rusttype::gpu_cache::*;
+use rusttype::*;
+
+/// Busy wait 2us
+fn mock_gpu_upload(_region: Rect<u32>, _bytes: &[u8]) {
+    use std::time::{Duration, Instant};
+
+    let now = Instant::now();
+    while now.elapsed() < Duration::from_micros(2) {}
+}
+
+fn test_glyphs<'a>(font: &Font<'a>, string: &str) -> Vec<PositionedGlyph<'a>> {
+    let mut glyphs = vec![];
+    // Set of scales, found through brute force, to reproduce GlyphNotCached issue
+    // Cache settings also affect this, it occurs when position_tolerance is < 1.0
+    for scale in &[25_f32, 24.5, 25.01, 24.7, 24.99] {
+        for glyph in layout_paragraph(font, Scale::uniform(*scale), 500, string) {
+            glyphs.push(glyph);
+        }
+    }
+    glyphs
+}
+
+fn layout_paragraph<'a>(
+    font: &Font<'a>,
+    scale: Scale,
+    width: u32,
+    text: &str,
+) -> Vec<PositionedGlyph<'a>> {
+    use unicode_normalization::UnicodeNormalization;
+    let mut result = Vec::new();
+    let v_metrics = font.v_metrics(scale);
+    let advance_height = v_metrics.ascent - v_metrics.descent + v_metrics.line_gap;
+    let mut caret = point(0.0, v_metrics.ascent);
+    let mut last_glyph_id = None;
+    for c in text.nfc() {
+        if c.is_control() {
+            if c == '\n' {
+                caret = point(0.0, caret.y + advance_height)
+            }
+            continue;
+        }
+        let base_glyph = font.glyph(c);
+        if let Some(id) = last_glyph_id.take() {
+            caret.x += font.pair_kerning(scale, id, base_glyph.id());
+        }
+        last_glyph_id = Some(base_glyph.id());
+        let mut glyph = base_glyph.scaled(scale).positioned(caret);
+        if let Some(bb) = glyph.pixel_bounding_box() {
+            if bb.max.x > width as i32 {
+                caret = point(0.0, caret.y + advance_height);
+                glyph = glyph.into_unpositioned().positioned(caret);
+                last_glyph_id = None;
+            }
+        }
+        caret.x += glyph.unpositioned().h_metrics().advance_width;
+        result.push(glyph);
+    }
+    result
+}
+
+lazy_static! {
+    static ref FONTS: Vec<Font<'static>> = vec![
+        include_bytes!("../fonts/wqy-microhei/WenQuanYiMicroHei.ttf") as &[u8],
+        include_bytes!("../fonts/dejavu/DejaVuSansMono.ttf") as &[u8],
+        include_bytes!("../fonts/opensans/OpenSans-Italic.ttf") as &[u8],
+    ].into_iter()
+    .map(|bytes| Font::from_bytes(bytes).unwrap())
+    .collect();
+}
+
+const TEST_STR: &str = include_str!("../tests/lipsum.txt");
+
+/// General use benchmarks.
+mod cache {
+    use super::*;
+
+    /// Benchmark using a single font at "don't care" position tolerance
+    #[bench]
+    fn high_position_tolerance(b: &mut ::test::Bencher) {
+        let font_id = 0;
+        let glyphs = test_glyphs(&FONTS[font_id], TEST_STR);
+        let mut cache = Cache::builder()
+            .dimensions(1024, 1024)
+            .scale_tolerance(0.1)
+            .position_tolerance(1.0)
+            .build();
+
+        b.iter(|| {
+            for glyph in &glyphs {
+                cache.queue_glyph(font_id, glyph.clone());
+            }
+
+            cache.cache_queued(|_, _| {}).expect("cache_queued");
+
+            for (index, glyph) in glyphs.iter().enumerate() {
+                let rect = cache.rect_for(font_id, glyph);
+                assert!(
+                    rect.is_ok(),
+                    "Gpu cache rect lookup failed ({:?}) for glyph index {}, id {}",
+                    rect,
+                    index,
+                    glyph.id().0
+                );
+            }
+        });
+    }
+
+    /// Benchmark using a single font with default tolerances
+    #[bench]
+    fn single_font(b: &mut ::test::Bencher) {
+        let font_id = 0;
+        let glyphs = test_glyphs(&FONTS[font_id], TEST_STR);
+        let mut cache = Cache::builder().dimensions(1024, 1024).build();
+
+        b.iter(|| {
+            for glyph in &glyphs {
+                cache.queue_glyph(font_id, glyph.clone());
+            }
+
+            cache.cache_queued(|_, _| {}).expect("cache_queued");
+
+            for (index, glyph) in glyphs.iter().enumerate() {
+                let rect = cache.rect_for(font_id, glyph);
+                assert!(
+                    rect.is_ok(),
+                    "Gpu cache rect lookup failed ({:?}) for glyph index {}, id {}",
+                    rect,
+                    index,
+                    glyph.id().0
+                );
+            }
+        });
+    }
+
+    /// Benchmark using multiple fonts with default tolerances
+    #[bench]
+    fn multi_font(b: &mut ::test::Bencher) {
+        // Use a smaller amount of the test string, to offset the extra font-glyph
+        // bench load
+        let up_to_index = TEST_STR
+            .char_indices()
+            .nth(TEST_STR.chars().count() / FONTS.len())
+            .unwrap()
+            .0;
+        let string = &TEST_STR[..up_to_index];
+
+        let font_glyphs: Vec<_> = FONTS
+            .iter()
+            .enumerate()
+            .map(|(id, font)| (id, test_glyphs(font, string)))
+            .collect();
+        let mut cache = Cache::builder().dimensions(1024, 1024).build();
+
+        b.iter(|| {
+            for &(font_id, ref glyphs) in &font_glyphs {
+                for glyph in glyphs {
+                    cache.queue_glyph(font_id, glyph.clone());
+                }
+            }
+
+            cache.cache_queued(|_, _| {}).expect("cache_queued");
+
+            for &(font_id, ref glyphs) in &font_glyphs {
+                for (index, glyph) in glyphs.iter().enumerate() {
+                    let rect = cache.rect_for(font_id, glyph);
+                    assert!(
+                        rect.is_ok(),
+                        "Gpu cache rect lookup failed ({:?}) for font {} glyph index {}, id {}",
+                        rect,
+                        font_id,
+                        index,
+                        glyph.id().0
+                    );
+                }
+            }
+        });
+    }
+
+    /// Benchmark using multiple fonts with default tolerances, clears the
+    /// cache each run to test the population "first run" performance
+    #[bench]
+    fn multi_font_population(b: &mut ::test::Bencher) {
+        // Use a much smaller amount of the test string, to offset the extra font-glyph
+        // bench load & much slower performance of fresh population each run
+        let up_to_index = TEST_STR.char_indices().nth(70).unwrap().0;
+        let string = &TEST_STR[..up_to_index];
+
+        let font_glyphs: Vec<_> = FONTS
+            .iter()
+            .enumerate()
+            .map(|(id, font)| (id, test_glyphs(font, string)))
+            .collect();
+
+        b.iter(|| {
+            let mut cache = Cache::builder().dimensions(1024, 1024).build();
+
+            for &(font_id, ref glyphs) in &font_glyphs {
+                for glyph in glyphs {
+                    cache.queue_glyph(font_id, glyph.clone());
+                }
+            }
+
+            cache.cache_queued(|_, _| {}).expect("cache_queued");
+
+            for &(font_id, ref glyphs) in &font_glyphs {
+                for (index, glyph) in glyphs.iter().enumerate() {
+                    let rect = cache.rect_for(font_id, glyph);
+                    assert!(
+                        rect.is_ok(),
+                        "Gpu cache rect lookup failed ({:?}) for font {} glyph index {}, id {}",
+                        rect,
+                        font_id,
+                        index,
+                        glyph.id().0
+                    );
+                }
+            }
+        });
+    }
+
+    /// Benchmark using multiple fonts and a different text group of glyphs
+    /// each run
+    #[bench]
+    fn moving_text(b: &mut ::test::Bencher) {
+        let chars: Vec<_> = TEST_STR.chars().collect();
+        let subsection_len = chars.len() / FONTS.len();
+        let distinct_subsection: Vec<_> = chars.windows(subsection_len).collect();
+
+        let mut first_glyphs = vec![];
+        let mut middle_glyphs = vec![];
+        let mut last_glyphs = vec![];
+
+        for (id, font) in FONTS.iter().enumerate() {
+            let first_str: String = distinct_subsection[0].iter().collect();
+            first_glyphs.push((id, test_glyphs(font, &first_str)));
+
+            let middle_str: String = distinct_subsection[distinct_subsection.len() / 2]
+                .iter()
+                .collect();
+            middle_glyphs.push((id, test_glyphs(font, &middle_str)));
+
+            let last_str: String = distinct_subsection[distinct_subsection.len() - 1]
+                .iter()
+                .collect();
+            last_glyphs.push((id, test_glyphs(font, &last_str)));
+        }
+
+        let test_variants = [first_glyphs, middle_glyphs, last_glyphs];
+        let mut test_variants = test_variants.iter().cycle();
+
+        let mut cache = Cache::builder()
+            .dimensions(1500, 1500)
+            .scale_tolerance(0.1)
+            .position_tolerance(0.1)
+            .build();
+
+        b.iter(|| {
+            // switch text variant each run to force cache to deal with moving text
+            // requirements
+            let glyphs = test_variants.next().unwrap();
+            for &(font_id, ref glyphs) in glyphs {
+                for glyph in glyphs {
+                    cache.queue_glyph(font_id, glyph.clone());
+                }
+            }
+
+            cache.cache_queued(|_, _| {}).expect("cache_queued");
+
+            for &(font_id, ref glyphs) in glyphs {
+                for (index, glyph) in glyphs.iter().enumerate() {
+                    let rect = cache.rect_for(font_id, glyph);
+                    assert!(
+                        rect.is_ok(),
+                        "Gpu cache rect lookup failed ({:?}) for font {} glyph index {}, id {}",
+                        rect,
+                        font_id,
+                        index,
+                        glyph.id().0
+                    );
+                }
+            }
+        });
+    }
+}
+
+/// Benchmarks for cases that should generally be avoided by the cache user if
+/// at all possible (ie by picking a better initial cache size).
+mod cache_bad_cases {
+    use super::*;
+
+    /// Cache isn't large enough for a queue so a new cache is created to hold
+    /// the queue.
+    #[bench]
+    fn resizing(b: &mut ::test::Bencher) {
+        let up_to_index = TEST_STR.char_indices().nth(120).unwrap().0;
+        let string = &TEST_STR[..up_to_index];
+
+        let font_glyphs: Vec<_> = FONTS
+            .iter()
+            .enumerate()
+            .map(|(id, font)| (id, test_glyphs(font, string)))
+            .collect();
+
+        b.iter(|| {
+            let mut cache = Cache::builder().dimensions(256, 256).build();
+
+            for &(font_id, ref glyphs) in &font_glyphs {
+                for glyph in glyphs {
+                    cache.queue_glyph(font_id, glyph.clone());
+                }
+            }
+
+            cache
+                .cache_queued(mock_gpu_upload)
+                .expect_err("shouldn't fit");
+
+            cache.to_builder().dimensions(512, 512).rebuild(&mut cache);
+
+            cache.cache_queued(mock_gpu_upload).expect("should fit now");
+
+            for &(font_id, ref glyphs) in &font_glyphs {
+                for (index, glyph) in glyphs.iter().enumerate() {
+                    let rect = cache.rect_for(font_id, glyph);
+                    assert!(
+                        rect.is_ok(),
+                        "Gpu cache rect lookup failed ({:?}) for font {} glyph index {}, id {}",
+                        rect,
+                        font_id,
+                        index,
+                        glyph.id().0
+                    );
+                }
+            }
+        });
+    }
+
+    /// Benchmark using multiple fonts and a different text group of glyphs
+    /// each run. The cache is only large enough to fit each run if it is
+    /// cleared and re-built.
+    #[bench]
+    fn moving_text_thrashing(b: &mut ::test::Bencher) {
+        let chars: Vec<_> = TEST_STR.chars().collect();
+        let subsection_len = 60;
+        let distinct_subsection: Vec<_> = chars.windows(subsection_len).collect();
+
+        let mut first_glyphs = vec![];
+        let mut middle_glyphs = vec![];
+        let mut last_glyphs = vec![];
+
+        for (id, font) in FONTS.iter().enumerate() {
+            let first_str: String = distinct_subsection[0].iter().collect();
+            first_glyphs.push((id, test_glyphs(font, &first_str)));
+
+            let middle_str: String = distinct_subsection[distinct_subsection.len() / 2]
+                .iter()
+                .collect();
+            middle_glyphs.push((id, test_glyphs(font, &middle_str)));
+
+            let last_str: String = distinct_subsection[distinct_subsection.len() - 1]
+                .iter()
+                .collect();
+            last_glyphs.push((id, test_glyphs(font, &last_str)));
+        }
+
+        let test_variants = [first_glyphs, middle_glyphs, last_glyphs];
+
+        // Cache is only a little larger than each variants size meaning a lot of
+        // re-ordering, re-rasterization & re-uploading has to occur.
+        let mut cache = Cache::builder()
+            .dimensions(450, 450)
+            .scale_tolerance(0.1)
+            .position_tolerance(0.1)
+            .build();
+
+        b.iter(|| {
+            // switch text variant each run to force cache to deal with moving text
+            // requirements
+            for glyphs in &test_variants {
+                for &(font_id, ref glyphs) in glyphs {
+                    for glyph in glyphs {
+                        cache.queue_glyph(font_id, glyph.clone());
+                    }
+                }
+
+                cache.cache_queued(mock_gpu_upload).expect("cache_queued");
+
+                for &(font_id, ref glyphs) in glyphs {
+                    for (index, glyph) in glyphs.iter().enumerate() {
+                        let rect = cache.rect_for(font_id, glyph);
+                        assert!(
+                            rect.is_ok(),
+                            "Gpu cache rect lookup failed ({:?}) for font {} glyph index {}, id {}",
+                            rect,
+                            font_id,
+                            index,
+                            glyph.id().0
+                        );
+                    }
+                }
+            }
+        });
+    }
+}
diff --git a/rustc_deps/vendor/rusttype/benches/draw.rs b/rustc_deps/vendor/rusttype/benches/draw.rs
new file mode 100644
index 0000000..720923b
--- /dev/null
+++ b/rustc_deps/vendor/rusttype/benches/draw.rs
@@ -0,0 +1,109 @@
+#![feature(test)]
+extern crate test;
+#[macro_use]
+extern crate lazy_static;
+extern crate blake2;
+extern crate rusttype;
+
+use blake2::{Blake2s, Digest};
+use rusttype::*;
+
+lazy_static! {
+    static ref DEJA_VU_MONO: Font<'static> =
+        Font::from_bytes(include_bytes!("../fonts/dejavu/DejaVuSansMono.ttf") as &[u8]).unwrap();
+    static ref OPEN_SANS_ITALIC: Font<'static> =
+        Font::from_bytes(include_bytes!("../fonts/opensans/OpenSans-Italic.ttf") as &[u8]).unwrap();
+}
+
+#[bench]
+fn draw_big_biohazard(b: &mut test::Bencher) {
+    let glyph = DEJA_VU_MONO
+        .glyph('☣')
+        .scaled(Scale::uniform(600.0))
+        .positioned(point(0.0, 0.0));
+
+    const WIDTH: usize = 294;
+    const HEIGHT: usize = 269;
+
+    let bounds = glyph.pixel_bounding_box().unwrap();
+    assert_eq!(
+        (bounds.width() as usize, bounds.height() as usize),
+        (WIDTH, HEIGHT)
+    );
+
+    let mut target = [0u8; WIDTH * HEIGHT];
+    b.iter(|| {
+        glyph.draw(|x, y, alpha| {
+            let (x, y) = (x as usize, y as usize);
+            target[WIDTH * y + x] = (alpha * 255.0) as u8;
+        })
+    });
+
+    // verify the draw result against static reference hash
+    assert_eq!(
+        format!("{:x}", Blake2s::digest(&target)),
+        "8e3927a33c6d563d45f82fb9620dea8036274b403523a2e98cd5f93eafdb2125"
+    );
+}
+
+#[bench]
+fn draw_w(b: &mut test::Bencher) {
+    let glyph = DEJA_VU_MONO
+        .glyph('w')
+        .scaled(Scale::uniform(16.0))
+        .positioned(point(0.0, 0.0));
+
+    const WIDTH: usize = 9;
+    const HEIGHT: usize = 8;
+
+    let bounds = glyph.pixel_bounding_box().unwrap();
+    assert_eq!(
+        (bounds.width() as usize, bounds.height() as usize),
+        (WIDTH, HEIGHT)
+    );
+
+    let mut target = [0u8; WIDTH * HEIGHT];
+    b.iter(|| {
+        glyph.draw(|x, y, alpha| {
+            let (x, y) = (x as usize, y as usize);
+            target[WIDTH * y + x] = (alpha * 255.0) as u8;
+        })
+    });
+
+    // verify the draw result against static reference hash
+    assert_eq!(
+        format!("{:x}", Blake2s::digest(&target)),
+        "c0e795601e3412144d1bfdc0cd94d9507aa9775a0f0f4f9862fe7ec7e83d7684"
+    );
+}
+
+#[bench]
+fn draw_iota(b: &mut test::Bencher) {
+    let glyph = OPEN_SANS_ITALIC
+        .glyph('ΐ')
+        .scaled(Scale::uniform(60.0))
+        .positioned(point(0.0, 0.0));
+
+    const WIDTH: usize = 14;
+    const HEIGHT: usize = 38;
+
+    let bounds = glyph.pixel_bounding_box().unwrap();
+    assert_eq!(
+        (bounds.width() as usize, bounds.height() as usize),
+        (WIDTH, HEIGHT)
+    );
+
+    let mut target = [0u8; WIDTH * HEIGHT];
+    b.iter(|| {
+        glyph.draw(|x, y, alpha| {
+            let (x, y) = (x as usize, y as usize);
+            target[WIDTH * y + x] = (alpha * 255.0) as u8;
+        })
+    });
+
+    // verify the draw result against static reference hash
+    assert_eq!(
+        format!("{:x}", Blake2s::digest(&target)),
+        "cdad348e38263a13f68ae41a95ce3b900d2881375a745232309ebd568a27cd4c"
+    );
+}
diff --git a/rustc_deps/vendor/rusttype/examples/gpu_cache.rs b/rustc_deps/vendor/rusttype/examples/gpu_cache.rs
new file mode 100644
index 0000000..7d4d5bf
--- /dev/null
+++ b/rustc_deps/vendor/rusttype/examples/gpu_cache.rs
@@ -0,0 +1,279 @@
+extern crate arrayvec;
+#[macro_use]
+extern crate glium;
+extern crate rusttype;
+extern crate unicode_normalization;
+
+use glium::{glutin, Surface};
+use rusttype::gpu_cache::Cache;
+use rusttype::{point, vector, Font, PositionedGlyph, Rect, Scale};
+use std::borrow::Cow;
+use std::error::Error;
+
+fn layout_paragraph<'a>(
+    font: &'a Font,
+    scale: Scale,
+    width: u32,
+    text: &str,
+) -> Vec<PositionedGlyph<'a>> {
+    use unicode_normalization::UnicodeNormalization;
+    let mut result = Vec::new();
+    let v_metrics = font.v_metrics(scale);
+    let advance_height = v_metrics.ascent - v_metrics.descent + v_metrics.line_gap;
+    let mut caret = point(0.0, v_metrics.ascent);
+    let mut last_glyph_id = None;
+    for c in text.nfc() {
+        if c.is_control() {
+            match c {
+                '\r' => {
+                    caret = point(0.0, caret.y + advance_height);
+                }
+                '\n' => {}
+                _ => {}
+            }
+            continue;
+        }
+        let base_glyph = font.glyph(c);
+        if let Some(id) = last_glyph_id.take() {
+            caret.x += font.pair_kerning(scale, id, base_glyph.id());
+        }
+        last_glyph_id = Some(base_glyph.id());
+        let mut glyph = base_glyph.scaled(scale).positioned(caret);
+        if let Some(bb) = glyph.pixel_bounding_box() {
+            if bb.max.x > width as i32 {
+                caret = point(0.0, caret.y + advance_height);
+                glyph = glyph.into_unpositioned().positioned(caret);
+                last_glyph_id = None;
+            }
+        }
+        caret.x += glyph.unpositioned().h_metrics().advance_width;
+        result.push(glyph);
+    }
+    result
+}
+
+fn main() -> Result<(), Box<Error>> {
+    let font_data = include_bytes!("../fonts/wqy-microhei/WenQuanYiMicroHei.ttf");
+    let font = Font::from_bytes(font_data as &[u8])?;
+
+    let window = glutin::WindowBuilder::new()
+        .with_dimensions((512, 512).into())
+        .with_title("RustType GPU cache example");
+    let context = glutin::ContextBuilder::new().with_vsync(true);
+    let mut events_loop = glutin::EventsLoop::new();
+    let display = glium::Display::new(window, context, &events_loop)?;
+
+    let dpi_factor = display.gl_window().get_hidpi_factor();
+
+    let (cache_width, cache_height) = ((512.0 * dpi_factor) as u32, (512.0 * dpi_factor) as u32);
+    let mut cache = Cache::builder()
+        .dimensions(cache_width, cache_height)
+        .build();
+
+    let program = program!(
+        &display,
+        140 => {
+            vertex: "
+                #version 140
+
+                in vec2 position;
+                in vec2 tex_coords;
+                in vec4 colour;
+
+                out vec2 v_tex_coords;
+                out vec4 v_colour;
+
+                void main() {
+                    gl_Position = vec4(position, 0.0, 1.0);
+                    v_tex_coords = tex_coords;
+                    v_colour = colour;
+                }
+            ",
+
+            fragment: "
+                #version 140
+                uniform sampler2D tex;
+                in vec2 v_tex_coords;
+                in vec4 v_colour;
+                out vec4 f_colour;
+
+                void main() {
+                    f_colour = v_colour * vec4(1.0, 1.0, 1.0, texture(tex, v_tex_coords).r);
+                }
+            "
+        })?;
+    let cache_tex = glium::texture::Texture2d::with_format(
+        &display,
+        glium::texture::RawImage2d {
+            data: Cow::Owned(vec![128u8; cache_width as usize * cache_height as usize]),
+            width: cache_width,
+            height: cache_height,
+            format: glium::texture::ClientFormat::U8,
+        },
+        glium::texture::UncompressedFloatFormat::U8,
+        glium::texture::MipmapsOption::NoMipmap,
+    )?;
+    let mut text: String = "A japanese poem:\r
+\r
+色は匂へど散りぬるを我が世誰ぞ常ならむ有為の奥山今日越えて浅き夢見じ酔ひもせず\r
+\r
+Feel free to type out some text, and delete it with Backspace. \
+You can also try resizing this window."
+        .into();
+    loop {
+        let dpi_factor = display.gl_window().get_hidpi_factor();
+        let (width, _): (u32, _) = display
+            .gl_window()
+            .get_inner_size()
+            .ok_or("get_inner_size")?
+            .to_physical(dpi_factor)
+            .into();
+        let dpi_factor = dpi_factor as f32;
+
+        let mut finished = false;
+        events_loop.poll_events(|event| {
+            use glutin::*;
+
+            if let Event::WindowEvent { event, .. } = event {
+                match event {
+                    WindowEvent::CloseRequested => finished = true,
+                    WindowEvent::KeyboardInput {
+                        input:
+                            KeyboardInput {
+                                state: ElementState::Pressed,
+                                virtual_keycode: Some(keypress),
+                                ..
+                            },
+                        ..
+                    } => match keypress {
+                        VirtualKeyCode::Escape => finished = true,
+                        VirtualKeyCode::Back => {
+                            text.pop();
+                        }
+                        _ => (),
+                    },
+                    WindowEvent::ReceivedCharacter(c) => if c != '\u{7f}' && c != '\u{8}' {
+                        text.push(c);
+                    },
+                    _ => {}
+                }
+            }
+        });
+        if finished {
+            break;
+        }
+
+        let glyphs = layout_paragraph(&font, Scale::uniform(24.0 * dpi_factor), width, &text);
+        for glyph in &glyphs {
+            cache.queue_glyph(0, glyph.clone());
+        }
+        cache.cache_queued(|rect, data| {
+            cache_tex.main_level().write(
+                glium::Rect {
+                    left: rect.min.x,
+                    bottom: rect.min.y,
+                    width: rect.width(),
+                    height: rect.height(),
+                },
+                glium::texture::RawImage2d {
+                    data: Cow::Borrowed(data),
+                    width: rect.width(),
+                    height: rect.height(),
+                    format: glium::texture::ClientFormat::U8,
+                },
+            );
+        })?;
+
+        let uniforms = uniform! {
+            tex: cache_tex.sampled().magnify_filter(glium::uniforms::MagnifySamplerFilter::Nearest)
+        };
+
+        let vertex_buffer = {
+            #[derive(Copy, Clone)]
+            struct Vertex {
+                position: [f32; 2],
+                tex_coords: [f32; 2],
+                colour: [f32; 4],
+            }
+
+            implement_vertex!(Vertex, position, tex_coords, colour);
+            let colour = [0.0, 0.0, 0.0, 1.0];
+            let (screen_width, screen_height) = {
+                let (w, h) = display.get_framebuffer_dimensions();
+                (w as f32, h as f32)
+            };
+            let origin = point(0.0, 0.0);
+            let vertices: Vec<Vertex> = glyphs
+                .iter()
+                .flat_map(|g| {
+                    if let Ok(Some((uv_rect, screen_rect))) = cache.rect_for(0, g) {
+                        let gl_rect = Rect {
+                            min: origin
+                                + (vector(
+                                    screen_rect.min.x as f32 / screen_width - 0.5,
+                                    1.0 - screen_rect.min.y as f32 / screen_height - 0.5,
+                                )) * 2.0,
+                            max: origin
+                                + (vector(
+                                    screen_rect.max.x as f32 / screen_width - 0.5,
+                                    1.0 - screen_rect.max.y as f32 / screen_height - 0.5,
+                                )) * 2.0,
+                        };
+                        arrayvec::ArrayVec::<[Vertex; 6]>::from([
+                            Vertex {
+                                position: [gl_rect.min.x, gl_rect.max.y],
+                                tex_coords: [uv_rect.min.x, uv_rect.max.y],
+                                colour,
+                            },
+                            Vertex {
+                                position: [gl_rect.min.x, gl_rect.min.y],
+                                tex_coords: [uv_rect.min.x, uv_rect.min.y],
+                                colour,
+                            },
+                            Vertex {
+                                position: [gl_rect.max.x, gl_rect.min.y],
+                                tex_coords: [uv_rect.max.x, uv_rect.min.y],
+                                colour,
+                            },
+                            Vertex {
+                                position: [gl_rect.max.x, gl_rect.min.y],
+                                tex_coords: [uv_rect.max.x, uv_rect.min.y],
+                                colour,
+                            },
+                            Vertex {
+                                position: [gl_rect.max.x, gl_rect.max.y],
+                                tex_coords: [uv_rect.max.x, uv_rect.max.y],
+                                colour,
+                            },
+                            Vertex {
+                                position: [gl_rect.min.x, gl_rect.max.y],
+                                tex_coords: [uv_rect.min.x, uv_rect.max.y],
+                                colour,
+                            },
+                        ])
+                    } else {
+                        arrayvec::ArrayVec::new()
+                    }
+                }).collect();
+
+            glium::VertexBuffer::new(&display, &vertices)?
+        };
+
+        let mut target = display.draw();
+        target.clear_color(1.0, 1.0, 1.0, 0.0);
+        target.draw(
+            &vertex_buffer,
+            glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList),
+            &program,
+            &uniforms,
+            &glium::DrawParameters {
+                blend: glium::Blend::alpha_blending(),
+                ..Default::default()
+            },
+        )?;
+
+        target.finish()?;
+    }
+
+    Ok(())
+}
diff --git a/rustc_deps/vendor/rusttype/examples/image.rs b/rustc_deps/vendor/rusttype/examples/image.rs
new file mode 100644
index 0000000..cec484f
--- /dev/null
+++ b/rustc_deps/vendor/rusttype/examples/image.rs
@@ -0,0 +1,67 @@
+extern crate image;
+extern crate rusttype;
+
+use image::{DynamicImage, Rgba};
+use rusttype::{point, Font, Scale};
+
+fn main() {
+    // Load the font
+    let font_data = include_bytes!("../fonts/wqy-microhei/WenQuanYiMicroHei.ttf");
+    // This only succeeds if collection consists of one font
+    let font = Font::from_bytes(font_data as &[u8]).expect("Error constructing Font");
+
+    // The font size to use
+    let scale = Scale::uniform(32.0);
+
+    // The text to render
+    let text = "This is RustType rendered into a png!";
+
+    // Use a dark red colour
+    let colour = (150, 0, 0);
+
+    let v_metrics = font.v_metrics(scale);
+
+    // layout the glyphs in a line with 20 pixels padding
+    let glyphs: Vec<_> = font
+        .layout(text, scale, point(20.0, 20.0 + v_metrics.ascent))
+        .collect();
+
+    // work out the layout size
+    let glyphs_height = (v_metrics.ascent - v_metrics.descent).ceil() as u32;
+    let glyphs_width = {
+        let min_x = glyphs
+            .first()
+            .map(|g| g.pixel_bounding_box().unwrap().min.x)
+            .unwrap();
+        let max_x = glyphs
+            .last()
+            .map(|g| g.pixel_bounding_box().unwrap().max.x)
+            .unwrap();
+        (max_x - min_x) as u32
+    };
+
+    // Create a new rgba image with some padding
+    let mut image = DynamicImage::new_rgba8(glyphs_width + 40, glyphs_height + 40).to_rgba();
+
+    // Loop through the glyphs in the text, positing each one on a line
+    for glyph in glyphs {
+        if let Some(bounding_box) = glyph.pixel_bounding_box() {
+            // Draw the glyph into the image per-pixel by using the draw closure
+            glyph.draw(|x, y, v| {
+                image.put_pixel(
+                    // Offset the position by the glyph bounding box
+                    x + bounding_box.min.x as u32,
+                    y + bounding_box.min.y as u32,
+                    // Turn the coverage into an alpha value
+                    Rgba {
+                        data: [colour.0, colour.1, colour.2, (v * 255.0) as u8],
+                    },
+                )
+            });
+        }
+    }
+
+    // Save the image to a png file
+    image.save("image_example.png").unwrap();
+    println!("Generated: image_example.png");
+}
diff --git a/rustc_deps/vendor/rusttype/examples/simple.rs b/rustc_deps/vendor/rusttype/examples/simple.rs
new file mode 100644
index 0000000..56b41da
--- /dev/null
+++ b/rustc_deps/vendor/rusttype/examples/simple.rs
@@ -0,0 +1,80 @@
+extern crate rusttype;
+
+use rusttype::{point, FontCollection, PositionedGlyph, Scale};
+use std::io::Write;
+
+fn main() {
+    let font_data = include_bytes!("../fonts/wqy-microhei/WenQuanYiMicroHei.ttf");
+    let collection = FontCollection::from_bytes(font_data as &[u8]).unwrap_or_else(|e| {
+        panic!("error constructing a FontCollection from bytes: {}", e);
+    });
+    let font = collection.into_font() // only succeeds if collection consists of one font
+        .unwrap_or_else(|e| {
+            panic!("error turning FontCollection into a Font: {}", e);
+        });
+
+    // Desired font pixel height
+    let height: f32 = 12.4; // to get 80 chars across (fits most terminals); adjust as desired
+    let pixel_height = height.ceil() as usize;
+
+    // 2x scale in x direction to counter the aspect ratio of monospace characters.
+    let scale = Scale {
+        x: height * 2.0,
+        y: height,
+    };
+
+    // The origin of a line of text is at the baseline (roughly where
+    // non-descending letters sit). We don't want to clip the text, so we shift
+    // it down with an offset when laying it out. v_metrics.ascent is the
+    // distance between the baseline and the highest edge of any glyph in
+    // the font. That's enough to guarantee that there's no clipping.
+    let v_metrics = font.v_metrics(scale);
+    let offset = point(0.0, v_metrics.ascent);
+
+    // Glyphs to draw for "RustType". Feel free to try other strings.
+    let glyphs: Vec<PositionedGlyph> = font.layout("RustType", scale, offset).collect();
+
+    // Find the most visually pleasing width to display
+    let width = glyphs
+        .iter()
+        .rev()
+        .map(|g| g.position().x as f32 + g.unpositioned().h_metrics().advance_width)
+        .next()
+        .unwrap_or(0.0)
+        .ceil() as usize;
+
+    println!("width: {}, height: {}", width, pixel_height);
+
+    // Rasterise directly into ASCII art.
+    let mut pixel_data = vec![b'@'; width * pixel_height];
+    let mapping = b"@%#x+=:-. "; // The approximation of greyscale
+    let mapping_scale = (mapping.len() - 1) as f32;
+    for g in glyphs {
+        if let Some(bb) = g.pixel_bounding_box() {
+            g.draw(|x, y, v| {
+                // v should be in the range 0.0 to 1.0
+                let i = (v * mapping_scale + 0.5) as usize;
+                // so something's wrong if you get $ in the output.
+                let c = mapping.get(i).cloned().unwrap_or(b'$');
+                let x = x as i32 + bb.min.x;
+                let y = y as i32 + bb.min.y;
+                // There's still a possibility that the glyph clips the boundaries of the bitmap
+                if x >= 0 && x < width as i32 && y >= 0 && y < pixel_height as i32 {
+                    let x = x as usize;
+                    let y = y as usize;
+                    pixel_data[(x + y * width)] = c;
+                }
+            })
+        }
+    }
+
+    // Print it out
+    let stdout = ::std::io::stdout();
+    let mut handle = stdout.lock();
+    for j in 0..pixel_height {
+        handle
+            .write_all(&pixel_data[j * width..(j + 1) * width])
+            .unwrap();
+        handle.write_all(b"\n").unwrap();
+    }
+}
diff --git a/rustc_deps/vendor/rusttype/rustfmt.toml b/rustc_deps/vendor/rusttype/rustfmt.toml
new file mode 100644
index 0000000..e2447e3
--- /dev/null
+++ b/rustc_deps/vendor/rusttype/rustfmt.toml
@@ -0,0 +1,5 @@
+# rustfmt 0.3.x-nightly
+wrap_comments = true
+error_on_line_overflow = false
+use_field_init_shorthand = true
+condense_wildcard_suffixes = true
diff --git a/rustc_deps/vendor/rusttype/src/geometry.rs b/rustc_deps/vendor/rusttype/src/geometry.rs
new file mode 100644
index 0000000..e730240
--- /dev/null
+++ b/rustc_deps/vendor/rusttype/src/geometry.rs
@@ -0,0 +1,350 @@
+use std::ops;
+
+/// A point in 2-dimensional space, with each dimension of type `N`.
+///
+/// Legal operations on points are addition and subtraction by vectors, and
+/// subtraction between points, to give a vector representing the offset between
+/// the two points. Combined with the legal operations on vectors, meaningful
+/// manipulations of vectors and points can be performed.
+///
+/// For example, to interpolate between two points by a factor `t`:
+///
+/// ```
+/// # use rusttype::*;
+/// # let t = 0.5; let p0 = point(0.0, 0.0); let p1 = point(0.0, 0.0);
+/// let interpolated_point = p0 + (p1 - p0) * t;
+/// ```
+#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq, Hash)]
+pub struct Point<N> {
+    pub x: N,
+    pub y: N,
+}
+
+/// A vector in 2-dimensional space, with each dimension of type `N`.
+///
+/// Legal operations on vectors are addition and subtraction by vectors,
+/// addition by points (to give points), and multiplication and division by
+/// scalars.
+#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq, Hash)]
+pub struct Vector<N> {
+    pub x: N,
+    pub y: N,
+}
+/// A convenience function for generating `Point`s.
+#[inline]
+pub fn point<N>(x: N, y: N) -> Point<N> {
+    Point { x, y }
+}
+/// A convenience function for generating `Vector`s.
+#[inline]
+pub fn vector<N>(x: N, y: N) -> Vector<N> {
+    Vector { x, y }
+}
+
+impl<N: ops::Sub<Output = N>> ops::Sub for Point<N> {
+    type Output = Vector<N>;
+    fn sub(self, rhs: Point<N>) -> Vector<N> {
+        vector(self.x - rhs.x, self.y - rhs.y)
+    }
+}
+
+impl<N: ops::Add<Output = N>> ops::Add for Vector<N> {
+    type Output = Vector<N>;
+    fn add(self, rhs: Vector<N>) -> Vector<N> {
+        vector(self.x + rhs.x, self.y + rhs.y)
+    }
+}
+
+impl<N: ops::Sub<Output = N>> ops::Sub for Vector<N> {
+    type Output = Vector<N>;
+    fn sub(self, rhs: Vector<N>) -> Vector<N> {
+        vector(self.x - rhs.x, self.y - rhs.y)
+    }
+}
+
+impl ops::Mul<f32> for Vector<f32> {
+    type Output = Vector<f32>;
+    fn mul(self, rhs: f32) -> Vector<f32> {
+        vector(self.x * rhs, self.y * rhs)
+    }
+}
+
+impl ops::Mul<Vector<f32>> for f32 {
+    type Output = Vector<f32>;
+    fn mul(self, rhs: Vector<f32>) -> Vector<f32> {
+        vector(self * rhs.x, self * rhs.y)
+    }
+}
+
+impl ops::Mul<f64> for Vector<f64> {
+    type Output = Vector<f64>;
+    fn mul(self, rhs: f64) -> Vector<f64> {
+        vector(self.x * rhs, self.y * rhs)
+    }
+}
+
+impl ops::Mul<Vector<f64>> for f64 {
+    type Output = Vector<f64>;
+    fn mul(self, rhs: Vector<f64>) -> Vector<f64> {
+        vector(self * rhs.x, self * rhs.y)
+    }
+}
+
+impl ops::Div<f32> for Vector<f32> {
+    type Output = Vector<f32>;
+    fn div(self, rhs: f32) -> Vector<f32> {
+        vector(self.x / rhs, self.y / rhs)
+    }
+}
+
+impl ops::Div<Vector<f32>> for f32 {
+    type Output = Vector<f32>;
+    fn div(self, rhs: Vector<f32>) -> Vector<f32> {
+        vector(self / rhs.x, self / rhs.y)
+    }
+}
+
+impl ops::Div<f64> for Vector<f64> {
+    type Output = Vector<f64>;
+    fn div(self, rhs: f64) -> Vector<f64> {
+        vector(self.x / rhs, self.y / rhs)
+    }
+}
+
+impl ops::Div<Vector<f64>> for f64 {
+    type Output = Vector<f64>;
+    fn div(self, rhs: Vector<f64>) -> Vector<f64> {
+        vector(self / rhs.x, self / rhs.y)
+    }
+}
+
+impl<N: ops::Add<Output = N>> ops::Add<Vector<N>> for Point<N> {
+    type Output = Point<N>;
+    fn add(self, rhs: Vector<N>) -> Point<N> {
+        point(self.x + rhs.x, self.y + rhs.y)
+    }
+}
+
+impl<N: ops::Sub<Output = N>> ops::Sub<Vector<N>> for Point<N> {
+    type Output = Point<N>;
+    fn sub(self, rhs: Vector<N>) -> Point<N> {
+        point(self.x - rhs.x, self.y - rhs.y)
+    }
+}
+
+impl<N: ops::Add<Output = N>> ops::Add<Point<N>> for Vector<N> {
+    type Output = Point<N>;
+    fn add(self, rhs: Point<N>) -> Point<N> {
+        point(self.x + rhs.x, self.y + rhs.y)
+    }
+}
+
+/// A straight line between two points, `p[0]` and `p[1]`
+#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
+pub struct Line {
+    pub p: [Point<f32>; 2],
+}
+/// A quadratic Bezier curve, starting at `p[0]`, ending at `p[2]`, with control
+/// point `p[1]`.
+#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
+pub struct Curve {
+    pub p: [Point<f32>; 3],
+}
+/// A rectangle, with top-left corner at `min`, and bottom-right corner at
+/// `max`.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
+pub struct Rect<N> {
+    pub min: Point<N>,
+    pub max: Point<N>,
+}
+impl<N: ops::Sub<Output = N> + Copy> Rect<N> {
+    pub fn width(&self) -> N {
+        self.max.x - self.min.x
+    }
+    pub fn height(&self) -> N {
+        self.max.y - self.min.y
+    }
+}
+
+pub trait BoundingBox<N> {
+    fn bounding_box(&self) -> Rect<N> {
+        let (min_x, max_x) = self.x_bounds();
+        let (min_y, max_y) = self.y_bounds();
+        Rect {
+            min: point(min_x, min_y),
+            max: point(max_x, max_y),
+        }
+    }
+    fn x_bounds(&self) -> (N, N);
+    fn y_bounds(&self) -> (N, N);
+}
+
+impl BoundingBox<f32> for Line {
+    fn x_bounds(&self) -> (f32, f32) {
+        let p = &self.p;
+        if p[0].x < p[1].x {
+            (p[0].x, p[1].x)
+        } else {
+            (p[1].x, p[0].x)
+        }
+    }
+    fn y_bounds(&self) -> (f32, f32) {
+        let p = &self.p;
+        if p[0].y < p[1].y {
+            (p[0].y, p[1].y)
+        } else {
+            (p[1].y, p[0].y)
+        }
+    }
+}
+
+impl BoundingBox<f32> for Curve {
+    fn x_bounds(&self) -> (f32, f32) {
+        let p = &self.p;
+        if p[0].x <= p[1].x && p[1].x <= p[2].x {
+            (p[0].x, p[2].x)
+        } else if p[0].x >= p[1].x && p[1].x >= p[2].x {
+            (p[2].x, p[0].x)
+        } else {
+            let t = (p[0].x - p[1].x) / (p[0].x - 2.0 * p[1].x + p[2].x);
+            let _1mt = 1.0 - t;
+            let inflection = _1mt * _1mt * p[0].x + 2.0 * _1mt * t * p[1].x + t * t * p[2].x;
+            if p[1].x < p[0].x {
+                (inflection, p[0].x.max(p[2].x))
+            } else {
+                (p[0].x.min(p[2].x), inflection)
+            }
+        }
+    }
+
+    fn y_bounds(&self) -> (f32, f32) {
+        let p = &self.p;
+        if p[0].y <= p[1].y && p[1].y <= p[2].y {
+            (p[0].y, p[2].y)
+        } else if p[0].y >= p[1].y && p[1].y >= p[2].y {
+            (p[2].y, p[0].y)
+        } else {
+            let t = (p[0].y - p[1].y) / (p[0].y - 2.0 * p[1].y + p[2].y);
+            let _1mt = 1.0 - t;
+            let inflection = _1mt * _1mt * p[0].y + 2.0 * _1mt * t * p[1].y + t * t * p[2].y;
+            if p[1].y < p[0].y {
+                (inflection, p[0].y.max(p[2].y))
+            } else {
+                (p[0].y.min(p[2].y), inflection)
+            }
+        }
+    }
+}
+
+pub trait Cut: Sized {
+    fn cut_to(self, t: f32) -> Self;
+    fn cut_from(self, t: f32) -> Self;
+    fn cut_from_to(self, t0: f32, t1: f32) -> Self {
+        self.cut_from(t0).cut_to((t1 - t0) / (1.0 - t0))
+    }
+}
+
+impl Cut for Curve {
+    fn cut_to(self, t: f32) -> Curve {
+        let p = self.p;
+        let a = p[0] + t * (p[1] - p[0]);
+        let b = p[1] + t * (p[2] - p[1]);
+        let c = a + t * (b - a);
+        Curve { p: [p[0], a, c] }
+    }
+    fn cut_from(self, t: f32) -> Curve {
+        let p = self.p;
+        let a = p[0] + t * (p[1] - p[0]);
+        let b = p[1] + t * (p[2] - p[1]);
+        let c = a + t * (b - a);
+        Curve { p: [c, b, p[2]] }
+    }
+}
+
+impl Cut for Line {
+    fn cut_to(self, t: f32) -> Line {
+        let p = self.p;
+        Line {
+            p: [p[0], p[0] + t * (p[1] - p[0])],
+        }
+    }
+    fn cut_from(self, t: f32) -> Line {
+        let p = self.p;
+        Line {
+            p: [p[0] + t * (p[1] - p[0]), p[1]],
+        }
+    }
+    fn cut_from_to(self, t0: f32, t1: f32) -> Line {
+        let p = self.p;
+        let v = p[1] - p[0];
+        Line {
+            p: [p[0] + t0 * v, p[0] + t1 * v],
+        }
+    }
+}
+
+/// The real valued solutions to a real quadratic equation.
+#[derive(Copy, Clone, Debug)]
+pub enum RealQuadraticSolution {
+    /// Two zero-crossing solutions
+    Two(f32, f32),
+    /// One zero-crossing solution (equation is a straight line)
+    One(f32),
+    /// One zero-touching solution
+    Touch(f32),
+    /// No solutions
+    None,
+    /// All real numbers are solutions since a == b == c == 0.0
+    All,
+}
+
+impl RealQuadraticSolution {
+    /// If there are two solutions, this function ensures that they are in order
+    /// (first < second)
+    pub fn in_order(self) -> RealQuadraticSolution {
+        use self::RealQuadraticSolution::*;
+        match self {
+            Two(x, y) => if x < y {
+                Two(x, y)
+            } else {
+                Two(y, x)
+            },
+            other => other,
+        }
+    }
+}
+
+/// Solve a real quadratic equation, giving all real solutions, if any.
+pub fn solve_quadratic_real(a: f32, b: f32, c: f32) -> RealQuadraticSolution {
+    let discriminant = b * b - 4.0 * a * c;
+    if discriminant > 0.0 {
+        let sqrt_d = discriminant.sqrt();
+        let common = -b + if b >= 0.0 { -sqrt_d } else { sqrt_d };
+        let x1 = 2.0 * c / common;
+        if a == 0.0 {
+            RealQuadraticSolution::One(x1)
+        } else {
+            let x2 = common / (2.0 * a);
+            RealQuadraticSolution::Two(x1, x2)
+        }
+    } else if discriminant < 0.0 {
+        RealQuadraticSolution::None
+    } else if b == 0.0 {
+        if a == 0.0 {
+            if c == 0.0 {
+                RealQuadraticSolution::All
+            } else {
+                RealQuadraticSolution::None
+            }
+        } else {
+            RealQuadraticSolution::Touch(0.0)
+        }
+    } else {
+        RealQuadraticSolution::Touch(2.0 * c / -b)
+    }
+}
+
+#[test]
+fn quadratic_test() {
+    solve_quadratic_real(-0.000_000_1, -2.0, 10.0);
+}
diff --git a/rustc_deps/vendor/rusttype/src/gpu_cache.rs b/rustc_deps/vendor/rusttype/src/gpu_cache.rs
new file mode 100644
index 0000000..ca37912
--- /dev/null
+++ b/rustc_deps/vendor/rusttype/src/gpu_cache.rs
@@ -0,0 +1,1112 @@
+//! This module provides capabilities for managing a cache of rendered glyphs in
+//! GPU memory, with the goal of minimisng the size and frequency of glyph
+//! uploads to GPU memory from the CPU.
+//!
+//! This module is optional, and not compiled by default. To use it enable the
+//! `gpu_cache` feature in your Cargo.toml.
+//!
+//! Typical applications that render directly with hardware graphics APIs (e.g.
+//! games) need text rendering. There is not yet a performant solution for high
+//! quality text rendering directly on the GPU that isn't experimental research
+//! work. Quality is often critical for legibility, so many applications use
+//! text or individual characters that have been rendered on the CPU. This is
+//! done either ahead-of-time, giving a fixed set of fonts, characters, and
+//! sizes that can be used at runtime, or dynamically as text is required. This
+//! latter scenario is more flexible and the focus of this module.
+//!
+//! To minimise the CPU load and texture upload bandwidth saturation, recently
+//! used glyphs should be cached on the GPU for use by future frames. This
+//! module provides a mechanism for maintaining such a cache in the form of a
+//! single packed 2D GPU texture. When a rendered glyph is requested, it is
+//! either retrieved from its location in the texture if it is present or room
+//! is made in the cache (if necessary), the CPU renders the glyph then it is
+//! uploaded into a gap in the texture to be available for GPU rendering. This
+//! cache uses a Least Recently Used (LRU) cache eviction scheme - glyphs in the
+//! cache that have not been used recently are as a rule of thumb not likely to
+//! be used again soon, so they are the best candidates for eviction to make
+//! room for required glyphs.
+//!
+//! The API for the cache does not assume a particular graphics API. The
+//! intended usage is to queue up glyphs that need to be present for the current
+//! frame using `Cache::queue_glyph`, update the cache to ensure that the queued
+//! glyphs are present using `Cache::cache_queued` (providing a function for
+//! uploading pixel data), then when it's time to render call `Cache::rect_for`
+//! to get the UV coordinates in the cache texture for each glyph. For a
+//! concrete use case see the `gpu_cache` example.
+//!
+//! Cache dimensions are immutable. If you need to change the dimensions of the
+//! cache texture (e.g. due to high cache pressure), rebuild a new `Cache`.
+//! Either from scratch or with `CacheBuilder::rebuild`.
+//!
+//! # Example
+//!
+//! ```
+//! # use rusttype::{Font, gpu_cache::Cache, point, Scale};
+//! # use std::error::Error;
+//! # fn example() -> Result<(), Box<Error>> {
+//! # let font_data: &[u8] = include_bytes!("../fonts/dejavu/DejaVuSansMono.ttf");
+//! # let font: Font<'static> = Font::from_bytes(font_data)?;
+//! # let glyph = font.glyph('a').scaled(Scale::uniform(25.0)).positioned(point(0.0, 0.0));
+//! # let glyph2 = glyph.clone();
+//! # let update_gpu_texture = |_, _| {};
+//! // Build a default Cache.
+//! let mut cache = Cache::builder().build();
+//!
+//! // Queue some positioned glyphs needed for the next frame.
+//! cache.queue_glyph(0, glyph);
+//!
+//! // Cache all queued glyphs somewhere in the cache texture.
+//! // If new glyph data has been drawn the closure is called to upload
+//! // the pixel data to GPU memory.
+//! cache.cache_queued(|region, data| update_gpu_texture(region, data))?;
+//!
+//! # let glyph = glyph2;
+//! // Lookup a positioned glyph's texture location
+//! if let Ok(Some((uv_rect, screen_rect))) = cache.rect_for(0, &glyph) {
+//!     // Generate vertex data, etc
+//! }
+//! # Ok(())
+//! # }
+//! ```
+
+extern crate crossbeam_deque;
+extern crate crossbeam_utils;
+extern crate linked_hash_map;
+extern crate num_cpus;
+extern crate rustc_hash;
+
+use self::linked_hash_map::LinkedHashMap;
+use self::rustc_hash::{FxHashMap, FxHasher};
+use std::collections::{HashMap, HashSet};
+use std::error;
+use std::fmt;
+use std::hash::BuildHasherDefault;
+use {point, vector, GlyphId, Point, PositionedGlyph, Rect, Vector};
+
+type FxBuildHasher = BuildHasherDefault<FxHasher>;
+
+/// Texture coordinates (floating point) of the quad for a glyph in the cache,
+/// as well as the pixel-space (integer) coordinates that this region should be
+/// drawn at.
+pub type TextureCoords = (Rect<f32>, Rect<i32>);
+type FontId = usize;
+
+/// Indicates where a glyph texture is stored in the cache
+/// (row position, glyph index in row)
+type TextureRowGlyphIndex = (u32, u32);
+
+/// Texture lookup key that uses scale & offset as integers attained
+/// by dividing by the relevant tolerance.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+struct LossyGlyphInfo {
+    font_id: FontId,
+    glyph_id: GlyphId,
+    /// x & y scales divided by `scale_tolerance` & rounded
+    scale_over_tolerance: (u32, u32),
+    /// Normalised subpixel positions divided by `position_tolerance` & rounded
+    ///
+    /// `u16` is enough as subpixel position `[-0.5, 0.5]` converted to `[0, 1]`
+    ///  divided by the min `position_tolerance` (`0.001`) is small.
+    offset_over_tolerance: (u16, u16),
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+struct ByteArray2d {
+    inner_array: Vec<u8>,
+    row: usize,
+    col: usize,
+}
+
+impl ByteArray2d {
+    #[inline]
+    pub fn zeros(row: usize, col: usize) -> Self {
+        ByteArray2d {
+            inner_array: vec![0; row * col],
+            row,
+            col,
+        }
+    }
+
+    #[inline]
+    fn as_slice(&self) -> &[u8] {
+        self.inner_array.as_slice()
+    }
+
+    #[inline]
+    fn get_vec_index(&self, row: usize, col: usize) -> usize {
+        debug_assert!(
+            row < self.row,
+            "row out of range: row={}, given={}",
+            self.row,
+            row
+        );
+        debug_assert!(
+            col < self.col,
+            "column out of range: col={}, given={}",
+            self.col,
+            col
+        );
+        row * self.col + col
+    }
+}
+
+impl ::std::ops::Index<(usize, usize)> for ByteArray2d {
+    type Output = u8;
+
+    #[inline]
+    fn index(&self, (row, col): (usize, usize)) -> &u8 {
+        &self.inner_array[self.get_vec_index(row, col)]
+    }
+}
+
+impl ::std::ops::IndexMut<(usize, usize)> for ByteArray2d {
+    #[inline]
+    fn index_mut(&mut self, (row, col): (usize, usize)) -> &mut u8 {
+        let vec_index = self.get_vec_index(row, col);
+        &mut self.inner_array[vec_index]
+    }
+}
+
+/// Row of pixel data
+struct Row {
+    /// Row pixel height
+    height: u32,
+    /// Pixel width current in use by glyphs
+    width: u32,
+    glyphs: Vec<GlyphTexInfo>,
+}
+
+struct GlyphTexInfo {
+    glyph_info: LossyGlyphInfo,
+    /// Actual (lossless) normalised subpixel offset of rasterized glyph
+    offset: Vector<f32>,
+    tex_coords: Rect<u32>,
+}
+
+trait PaddingAware {
+    fn unpadded(self) -> Self;
+}
+
+impl PaddingAware for Rect<u32> {
+    /// A padded texture has 1 extra pixel on all sides
+    fn unpadded(mut self) -> Self {
+        self.min.x += 1;
+        self.min.y += 1;
+        self.max.x -= 1;
+        self.max.y -= 1;
+        self
+    }
+}
+
+/// An implementation of a dynamic GPU glyph cache. See the module documentation
+/// for more information.
+pub struct Cache<'font> {
+    scale_tolerance: f32,
+    position_tolerance: f32,
+    width: u32,
+    height: u32,
+    rows: LinkedHashMap<u32, Row, FxBuildHasher>,
+    /// Mapping of row gaps bottom -> top
+    space_start_for_end: FxHashMap<u32, u32>,
+    /// Mapping of row gaps top -> bottom
+    space_end_for_start: FxHashMap<u32, u32>,
+    queue: Vec<(FontId, PositionedGlyph<'font>)>,
+    all_glyphs: FxHashMap<LossyGlyphInfo, TextureRowGlyphIndex>,
+    pad_glyphs: bool,
+    multithread: bool,
+}
+
+/// Builder & rebuilder for `Cache`.
+///
+/// # Example
+///
+/// ```
+/// use rusttype::gpu_cache::Cache;
+///
+/// // Create a cache with all default values set explicitly
+/// // equivalent to `Cache::builder().build()`
+/// let default_cache = Cache::builder()
+///     .dimensions(256, 256)
+///     .scale_tolerance(0.1)
+///     .position_tolerance(0.1)
+///     .pad_glyphs(true)
+///     .multithread(true)
+///     .build();
+///
+/// // Create a cache with all default values, except with a dimension of 1024x1024
+/// let bigger_cache = Cache::builder().dimensions(1024, 1024).build();
+/// ```
+#[derive(Debug, Clone)]
+pub struct CacheBuilder {
+    dimensions: (u32, u32),
+    scale_tolerance: f32,
+    position_tolerance: f32,
+    pad_glyphs: bool,
+    multithread: bool,
+}
+
+impl Default for CacheBuilder {
+    fn default() -> Self {
+        Self {
+            dimensions: (256, 256),
+            scale_tolerance: 0.1,
+            position_tolerance: 0.1,
+            pad_glyphs: true,
+            multithread: true,
+        }
+    }
+}
+
+impl CacheBuilder {
+    /// `width` & `height` dimensions of the 2D texture that will hold the
+    /// cache contents on the GPU.
+    ///
+    /// This must match the dimensions of the actual texture used, otherwise
+    /// `cache_queued` will try to cache into coordinates outside the bounds of
+    /// the texture.
+    ///
+    /// # Example (set to default value)
+    ///
+    /// ```
+    /// # use rusttype::gpu_cache::Cache;
+    /// let cache = Cache::builder().dimensions(256, 256).build();
+    /// ```
+    pub fn dimensions(mut self, width: u32, height: u32) -> Self {
+        self.dimensions = (width, height);
+        self
+    }
+
+    /// Specifies the tolerances (maximum allowed difference) for judging
+    /// whether an existing glyph in the cache is close enough to the
+    /// requested glyph in scale to be used in its place. Due to floating
+    /// point inaccuracies a min value of `0.001` is enforced.
+    ///
+    /// Both `scale_tolerance` and `position_tolerance` are measured in pixels.
+    ///
+    /// Tolerances produce even steps for scale and subpixel position. Only a
+    /// single glyph texture will be used within a single step. For example,
+    /// `scale_tolerance = 0.1` will have a step `9.95-10.05` so similar glyphs
+    /// with scale `9.98` & `10.04` will match.
+    ///
+    /// A typical application will produce results with no perceptible
+    /// inaccuracies with `scale_tolerance` and `position_tolerance` set to
+    /// 0.1. Depending on the target DPI higher tolerance may be acceptable.
+    ///
+    /// # Example (set to default value)
+    ///
+    /// ```
+    /// # use rusttype::gpu_cache::Cache;
+    /// let cache = Cache::builder().scale_tolerance(0.1).build();
+    /// ```
+    pub fn scale_tolerance<V: Into<f32>>(mut self, scale_tolerance: V) -> Self {
+        self.scale_tolerance = scale_tolerance.into();
+        self
+    }
+    /// Specifies the tolerances (maximum allowed difference) for judging
+    /// whether an existing glyph in the cache is close enough to the requested
+    /// glyph in subpixel offset to be used in its place. Due to floating
+    /// point inaccuracies a min value of `0.001` is enforced.
+    ///
+    /// Both `scale_tolerance` and `position_tolerance` are measured in pixels.
+    ///
+    /// Tolerances produce even steps for scale and subpixel position. Only a
+    /// single glyph texture will be used within a single step. For example,
+    /// `scale_tolerance = 0.1` will have a step `9.95-10.05` so similar glyphs
+    /// with scale `9.98` & `10.04` will match.
+    ///
+    /// Note that since `position_tolerance` is a tolerance of subpixel
+    /// offsets, setting it to 1.0 or higher is effectively a "don't care"
+    /// option.
+    ///
+    /// A typical application will produce results with no perceptible
+    /// inaccuracies with `scale_tolerance` and `position_tolerance` set to
+    /// 0.1. Depending on the target DPI higher tolerance may be acceptable.
+    ///
+    /// # Example (set to default value)
+    ///
+    /// ```
+    /// # use rusttype::gpu_cache::Cache;
+    /// let cache = Cache::builder().position_tolerance(0.1).build();
+    /// ```
+    pub fn position_tolerance<V: Into<f32>>(mut self, position_tolerance: V) -> Self {
+        self.position_tolerance = position_tolerance.into();
+        self
+    }
+    /// Pack glyphs in texture with a padding of a single zero alpha pixel to
+    /// avoid bleeding from interpolated shader texture lookups near edges.
+    ///
+    /// If glyphs are never transformed this may be set to `false` to slightly
+    /// improve the glyph packing.
+    ///
+    /// # Example (set to default value)
+    ///
+    /// ```
+    /// # use rusttype::gpu_cache::Cache;
+    /// let cache = Cache::builder().pad_glyphs(true).build();
+    /// ```
+    pub fn pad_glyphs(mut self, pad_glyphs: bool) -> Self {
+        self.pad_glyphs = pad_glyphs;
+        self
+    }
+    /// When multiple CPU cores are available spread rasterization work across
+    /// all cores.
+    ///
+    /// Significantly reduces worst case latency in multicore environments.
+    ///
+    /// # Example (set to default value)
+    ///
+    /// ```
+    /// # use rusttype::gpu_cache::Cache;
+    /// let cache = Cache::builder().multithread(true).build();
+    /// ```
+    pub fn multithread(mut self, multithread: bool) -> Self {
+        self.multithread = multithread;
+        self
+    }
+
+    fn validated(self) -> Self {
+        assert!(self.scale_tolerance >= 0.0);
+        assert!(self.position_tolerance >= 0.0);
+        let scale_tolerance = self.scale_tolerance.max(0.001);
+        let position_tolerance = self.position_tolerance.max(0.001);
+        let multithread = self.multithread && num_cpus::get() > 1;
+        Self {
+            scale_tolerance,
+            position_tolerance,
+            multithread,
+            ..self
+        }
+    }
+
+    /// Constructs a new cache. Note that this is just the CPU side of the
+    /// cache. The GPU texture is managed by the user.
+    ///
+    /// # Panics
+    ///
+    /// `scale_tolerance` or `position_tolerance` are less than or equal to
+    /// zero.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// # use rusttype::gpu_cache::Cache;
+    /// let cache = Cache::builder().build();
+    /// ```
+    pub fn build<'a>(self) -> Cache<'a> {
+        let CacheBuilder {
+            dimensions: (width, height),
+            scale_tolerance,
+            position_tolerance,
+            pad_glyphs,
+            multithread,
+        } = self.validated();
+
+        Cache {
+            scale_tolerance,
+            position_tolerance,
+            width,
+            height,
+            rows: LinkedHashMap::default(),
+            space_start_for_end: {
+                let mut m = HashMap::default();
+                m.insert(height, 0);
+                m
+            },
+            space_end_for_start: {
+                let mut m = HashMap::default();
+                m.insert(0, height);
+                m
+            },
+            queue: Vec::new(),
+            all_glyphs: HashMap::default(),
+            pad_glyphs,
+            multithread,
+        }
+    }
+
+    /// Rebuilds a cache with new attributes. Carries over the existing cache
+    /// queue unmodified.
+    ///
+    /// # Panics
+    ///
+    /// `scale_tolerance` or `position_tolerance` are less than or equal to
+    /// zero.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// # use rusttype::gpu_cache::Cache;
+    /// # let mut cache = Cache::builder().build();
+    /// // Rebuild the cache with different dimensions
+    /// cache.to_builder().dimensions(768, 768).rebuild(&mut cache);
+    /// ```
+    pub fn rebuild(self, cache: &mut Cache) {
+        let CacheBuilder {
+            dimensions: (width, height),
+            scale_tolerance,
+            position_tolerance,
+            pad_glyphs,
+            multithread,
+        } = self.validated();
+
+        cache.width = width;
+        cache.height = height;
+        cache.scale_tolerance = scale_tolerance;
+        cache.position_tolerance = position_tolerance;
+        cache.pad_glyphs = pad_glyphs;
+        cache.multithread = multithread;
+        cache.clear();
+    }
+}
+
+/// Returned from `Cache::rect_for`.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
+pub enum CacheReadErr {
+    /// Indicates that the requested glyph is not present in the cache
+    GlyphNotCached,
+}
+impl fmt::Display for CacheReadErr {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}", error::Error::description(self))
+    }
+}
+impl error::Error for CacheReadErr {
+    fn description(&self) -> &str {
+        match *self {
+            CacheReadErr::GlyphNotCached => "Glyph not cached",
+        }
+    }
+}
+
+/// Returned from `Cache::cache_queued`.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
+pub enum CacheWriteErr {
+    /// At least one of the queued glyphs is too big to fit into the cache, even
+    /// if all other glyphs are removed.
+    GlyphTooLarge,
+    /// Not all of the requested glyphs can fit into the cache, even if the
+    /// cache is completely cleared before the attempt.
+    NoRoomForWholeQueue,
+}
+impl fmt::Display for CacheWriteErr {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}", error::Error::description(self))
+    }
+}
+impl error::Error for CacheWriteErr {
+    fn description(&self) -> &str {
+        match *self {
+            CacheWriteErr::GlyphTooLarge => "Glyph too large",
+            CacheWriteErr::NoRoomForWholeQueue => "No room for whole queue",
+        }
+    }
+}
+
+fn normalised_offset_from_position(position: Point<f32>) -> Vector<f32> {
+    let mut offset = vector(position.x.fract(), position.y.fract());
+    if offset.x > 0.5 {
+        offset.x -= 1.0;
+    } else if offset.x < -0.5 {
+        offset.x += 1.0;
+    }
+    if offset.y > 0.5 {
+        offset.y -= 1.0;
+    } else if offset.y < -0.5 {
+        offset.y += 1.0;
+    }
+    offset
+}
+
+impl<'font> Cache<'font> {
+    /// Returns a default `CacheBuilder`.
+    #[inline]
+    pub fn builder() -> CacheBuilder {
+        CacheBuilder::default()
+    }
+
+    /// Returns the current scale tolerance for the cache.
+    pub fn scale_tolerance(&self) -> f32 {
+        self.scale_tolerance
+    }
+
+    /// Returns the current subpixel position tolerance for the cache.
+    pub fn position_tolerance(&self) -> f32 {
+        self.position_tolerance
+    }
+
+    /// Returns the cache texture dimensions assumed by the cache. For proper
+    /// operation this should match the dimensions of the used GPU texture.
+    pub fn dimensions(&self) -> (u32, u32) {
+        (self.width, self.height)
+    }
+
+    /// Queue a glyph for caching by the next call to `cache_queued`. `font_id`
+    /// is used to disambiguate glyphs from different fonts. The user should
+    /// ensure that `font_id` is unique to the font the glyph is from.
+    pub fn queue_glyph(&mut self, font_id: usize, glyph: PositionedGlyph<'font>) {
+        if glyph.pixel_bounding_box().is_some() {
+            self.queue.push((font_id, glyph));
+        }
+    }
+
+    /// Clears the cache. Does not affect the glyph queue.
+    pub fn clear(&mut self) {
+        self.rows.clear();
+        self.space_end_for_start.clear();
+        self.space_end_for_start.insert(0, self.height);
+        self.space_start_for_end.clear();
+        self.space_start_for_end.insert(self.height, 0);
+        self.all_glyphs.clear();
+    }
+
+    /// Clears the glyph queue.
+    pub fn clear_queue(&mut self) {
+        self.queue.clear();
+    }
+
+    /// Returns a `CacheBuilder` with this cache's attributes.
+    pub fn to_builder(&self) -> CacheBuilder {
+        CacheBuilder {
+            dimensions: (self.width, self.height),
+            position_tolerance: self.position_tolerance,
+            scale_tolerance: self.scale_tolerance,
+            pad_glyphs: self.pad_glyphs,
+            multithread: self.multithread,
+        }
+    }
+
+    /// Returns glyph info with accuracy according to the set tolerances.
+    fn lossy_info_for(&self, font_id: FontId, glyph: &PositionedGlyph<'font>) -> LossyGlyphInfo {
+        let scale = glyph.scale();
+        let offset = normalised_offset_from_position(glyph.position());
+
+        LossyGlyphInfo {
+            font_id,
+            glyph_id: glyph.id(),
+            scale_over_tolerance: (
+                (scale.x / self.scale_tolerance + 0.5) as u32,
+                (scale.y / self.scale_tolerance + 0.5) as u32,
+            ),
+            // convert [-0.5, 0.5] -> [0, 1] then divide
+            offset_over_tolerance: (
+                ((offset.x + 0.5) / self.position_tolerance + 0.5) as u16,
+                ((offset.y + 0.5) / self.position_tolerance + 0.5) as u16,
+            ),
+        }
+    }
+
+    /// Caches the queued glyphs. If this is unsuccessful, the queue is
+    /// untouched. Any glyphs cached by previous calls to this function may be
+    /// removed from the cache to make room for the newly queued glyphs. Thus if
+    /// you want to ensure that a glyph is in the cache, the most recently
+    /// cached queue must have contained that glyph.
+    ///
+    /// `uploader` is the user-provided function that should perform the texture
+    /// uploads to the GPU. The information provided is the rectangular region
+    /// to insert the pixel data into, and the pixel data itself. This data is
+    /// provided in horizontal scanline format (row major), with stride equal to
+    /// the rectangle width.
+    pub fn cache_queued<F: FnMut(Rect<u32>, &[u8])>(
+        &mut self,
+        mut uploader: F,
+    ) -> Result<(), CacheWriteErr> {
+        let mut queue_success = true;
+        let from_empty = self.all_glyphs.is_empty();
+
+        {
+            let (mut in_use_rows, mut uncached_glyphs) = {
+                let mut in_use_rows =
+                    HashSet::with_capacity_and_hasher(self.rows.len(), FxBuildHasher::default());
+                let mut uncached_glyphs = Vec::with_capacity(self.queue.len());
+
+                // divide glyphs into texture rows where a matching glyph texture
+                // already exists & glyphs where new textures must be cached
+                for (font_id, ref glyph) in &self.queue {
+                    let glyph_info = self.lossy_info_for(*font_id, glyph);
+                    if let Some((row, ..)) = self.all_glyphs.get(&glyph_info) {
+                        in_use_rows.insert(*row);
+                    } else {
+                        uncached_glyphs.push((glyph, glyph_info));
+                    }
+                }
+
+                (in_use_rows, uncached_glyphs)
+            };
+
+            for row in &in_use_rows {
+                self.rows.get_refresh(row);
+            }
+
+            // tallest first gives better packing
+            // can use 'sort_unstable' as order of equal elements is unimportant
+            uncached_glyphs
+                .sort_unstable_by_key(|(glyph, ..)| -glyph.pixel_bounding_box().unwrap().height());
+
+            self.all_glyphs.reserve(uncached_glyphs.len());
+            let mut draw_and_upload = Vec::with_capacity(uncached_glyphs.len());
+
+            'per_glyph: for (glyph, glyph_info) in uncached_glyphs {
+                // glyph may match a texture cached by a previous iteration
+                if self.all_glyphs.contains_key(&glyph_info) {
+                    continue;
+                }
+
+                // Not cached, so add it:
+                let (width, height) = {
+                    let bb = glyph.pixel_bounding_box().unwrap();
+                    if self.pad_glyphs {
+                        (bb.width() as u32 + 2, bb.height() as u32 + 2)
+                    } else {
+                        (bb.width() as u32, bb.height() as u32)
+                    }
+                };
+                if width >= self.width || height >= self.height {
+                    return Result::Err(CacheWriteErr::GlyphTooLarge);
+                }
+                // find row to put the glyph in, most used rows first
+                let mut row_top = None;
+                for (top, row) in self.rows.iter().rev() {
+                    if row.height >= height && self.width - row.width >= width {
+                        // found a spot on an existing row
+                        row_top = Some(*top);
+                        break;
+                    }
+                }
+
+                if row_top.is_none() {
+                    let mut gap = None;
+                    // See if there is space for a new row
+                    for (start, end) in &self.space_end_for_start {
+                        if end - start >= height {
+                            gap = Some((*start, *end));
+                            break;
+                        }
+                    }
+                    if gap.is_none() {
+                        // Remove old rows until room is available
+                        while !self.rows.is_empty() {
+                            // check that the oldest row isn't also in use
+                            if !in_use_rows.contains(self.rows.front().unwrap().0) {
+                                // Remove row
+                                let (top, row) = self.rows.pop_front().unwrap();
+
+                                for g in row.glyphs {
+                                    self.all_glyphs.remove(&g.glyph_info);
+                                }
+
+                                let (mut new_start, mut new_end) = (top, top + row.height);
+                                // Update the free space maps
+                                // Combine with neighbouring free space if possible
+                                if let Some(end) = self.space_end_for_start.remove(&new_end) {
+                                    new_end = end;
+                                }
+                                if let Some(start) = self.space_start_for_end.remove(&new_start) {
+                                    new_start = start;
+                                }
+                                self.space_start_for_end.insert(new_end, new_start);
+                                self.space_end_for_start.insert(new_start, new_end);
+                                if new_end - new_start >= height {
+                                    // The newly formed gap is big enough
+                                    gap = Some((new_start, new_end));
+                                    break;
+                                }
+                            }
+                            // all rows left are in use
+                            // try a clean insert of all needed glyphs
+                            // if that doesn't work, fail
+                            else if from_empty {
+                                // already trying a clean insert, don't do it again
+                                return Err(CacheWriteErr::NoRoomForWholeQueue);
+                            } else {
+                                // signal that a retry is needed
+                                queue_success = false;
+                                break 'per_glyph;
+                            }
+                        }
+                    }
+                    let (gap_start, gap_end) = gap.unwrap();
+                    // fill space for new row
+                    let new_space_start = gap_start + height;
+                    self.space_end_for_start.remove(&gap_start);
+                    if new_space_start == gap_end {
+                        self.space_start_for_end.remove(&gap_end);
+                    } else {
+                        self.space_end_for_start.insert(new_space_start, gap_end);
+                        self.space_start_for_end.insert(gap_end, new_space_start);
+                    }
+                    // add the row
+                    self.rows.insert(
+                        gap_start,
+                        Row {
+                            width: 0,
+                            height,
+                            glyphs: Vec::new(),
+                        },
+                    );
+                    row_top = Some(gap_start);
+                }
+                let row_top = row_top.unwrap();
+                // calculate the target rect
+                let row = self.rows.get_refresh(&row_top).unwrap();
+                let tex_coords = Rect {
+                    min: point(row.width, row_top),
+                    max: point(row.width + width, row_top + height),
+                };
+
+                draw_and_upload.push((tex_coords, glyph));
+
+                // add the glyph to the row
+                row.glyphs.push(GlyphTexInfo {
+                    glyph_info,
+                    offset: normalised_offset_from_position(glyph.position()),
+                    tex_coords,
+                });
+                row.width += width;
+                in_use_rows.insert(row_top);
+
+                self.all_glyphs
+                    .insert(glyph_info, (row_top, row.glyphs.len() as u32 - 1));
+            }
+
+            if queue_success {
+                let glyph_count = draw_and_upload.len();
+
+                if self.multithread && glyph_count > 1 {
+                    // multithread rasterization
+                    use self::crossbeam_deque::{Pop, Steal};
+                    use std::{
+                        mem,
+                        sync::mpsc::{self, TryRecvError},
+                    };
+
+                    let (main, stealer) = crossbeam_deque::fifo();
+                    let (to_main, from_stealers) = mpsc::channel();
+                    let pad_glyphs = self.pad_glyphs;
+
+                    for el in draw_and_upload {
+                        main.push(el);
+                    }
+                    crossbeam_utils::thread::scope(|scope| {
+                        for _ in 0..num_cpus::get().min(glyph_count).saturating_sub(1) {
+                            let stealer = stealer.clone();
+                            let to_main = to_main.clone();
+                            scope.spawn(move |_| loop {
+                                match stealer.steal() {
+                                    Steal::Data((tex_coords, glyph)) => {
+                                        let pixels = draw_glyph(tex_coords, glyph, pad_glyphs);
+                                        to_main.send((tex_coords, pixels)).unwrap();
+                                    }
+                                    Steal::Empty => break,
+                                    Steal::Retry => {}
+                                }
+                            });
+                        }
+                        mem::drop(to_main);
+
+                        let mut workers_finished = false;
+                        loop {
+                            match main.pop() {
+                                Pop::Data((tex_coords, glyph)) => {
+                                    let pixels = draw_glyph(tex_coords, glyph, pad_glyphs);
+                                    uploader(tex_coords, pixels.as_slice());
+                                }
+                                Pop::Empty if workers_finished => break,
+                                _ => {}
+                            }
+
+                            while !workers_finished {
+                                match from_stealers.try_recv() {
+                                    Ok((tex_coords, pixels)) => {
+                                        uploader(tex_coords, pixels.as_slice())
+                                    }
+                                    Err(TryRecvError::Disconnected) => workers_finished = true,
+                                    Err(TryRecvError::Empty) => break,
+                                }
+                            }
+                        }
+                    }).unwrap();
+                } else {
+                    // single thread rasterization
+                    for (tex_coords, glyph) in draw_and_upload {
+                        let pixels = draw_glyph(tex_coords, glyph, self.pad_glyphs);
+                        uploader(tex_coords, pixels.as_slice());
+                    }
+                }
+            }
+        }
+
+        if queue_success {
+            self.queue.clear();
+            Ok(())
+        } else {
+            // clear the cache then try again with optimal packing
+            self.clear();
+            self.cache_queued(uploader)
+        }
+    }
+
+    /// Retrieves the (floating point) texture coordinates of the quad for a
+    /// glyph in the cache, as well as the pixel-space (integer) coordinates
+    /// that this region should be drawn at. These pixel-space coordinates
+    /// assume an origin at the top left of the quad. In the majority of cases
+    /// these pixel-space coordinates should be identical to the bounding box of
+    /// the input glyph. They only differ if the cache has returned a substitute
+    /// glyph that is deemed close enough to the requested glyph as specified by
+    /// the cache tolerance parameters.
+    ///
+    /// A sucessful result is `Some` if the glyph is not an empty glyph (no
+    /// shape, and thus no rect to return).
+    ///
+    /// Ensure that `font_id` matches the `font_id` that was passed to
+    /// `queue_glyph` with this `glyph`.
+    pub fn rect_for(
+        &self,
+        font_id: usize,
+        glyph: &PositionedGlyph,
+    ) -> Result<Option<TextureCoords>, CacheReadErr> {
+        if glyph.pixel_bounding_box().is_none() {
+            return Ok(None);
+        }
+
+        let (row, index) = self
+            .all_glyphs
+            .get(&self.lossy_info_for(font_id, glyph))
+            .ok_or(CacheReadErr::GlyphNotCached)?;
+
+        let (tex_width, tex_height) = (self.width as f32, self.height as f32);
+
+        let GlyphTexInfo {
+            tex_coords: mut tex_rect,
+            offset: tex_offset,
+            ..
+        } = self.rows[&row].glyphs[*index as usize];
+        if self.pad_glyphs {
+            tex_rect = tex_rect.unpadded();
+        }
+        let uv_rect = Rect {
+            min: point(
+                tex_rect.min.x as f32 / tex_width,
+                tex_rect.min.y as f32 / tex_height,
+            ),
+            max: point(
+                tex_rect.max.x as f32 / tex_width,
+                tex_rect.max.y as f32 / tex_height,
+            ),
+        };
+
+        let local_bb = glyph
+            .unpositioned()
+            .clone()
+            .positioned(point(0.0, 0.0) + tex_offset)
+            .pixel_bounding_box()
+            .unwrap();
+        let min_from_origin =
+            point(local_bb.min.x as f32, local_bb.min.y as f32) - (point(0.0, 0.0) + tex_offset);
+        let ideal_min = min_from_origin + glyph.position();
+        let min = point(ideal_min.x.round() as i32, ideal_min.y.round() as i32);
+        let bb_offset = min - local_bb.min;
+        let bb = Rect {
+            min,
+            max: local_bb.max + bb_offset,
+        };
+        Ok(Some((uv_rect, bb)))
+    }
+}
+
+#[inline]
+fn draw_glyph<'font>(
+    tex_coords: Rect<u32>,
+    glyph: &PositionedGlyph<'font>,
+    pad_glyphs: bool,
+) -> ByteArray2d {
+    let mut pixels = ByteArray2d::zeros(tex_coords.height() as usize, tex_coords.width() as usize);
+    if pad_glyphs {
+        glyph.draw(|x, y, v| {
+            let v = (v * 255.0).round().max(0.0).min(255.0) as u8;
+            // `+ 1` accounts for top/left glyph padding
+            pixels[(y as usize + 1, x as usize + 1)] = v;
+        });
+    } else {
+        glyph.draw(|x, y, v| {
+            let v = (v * 255.0).round().max(0.0).min(255.0) as u8;
+            pixels[(y as usize, x as usize)] = v;
+        });
+    }
+    pixels
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+    use {Font, FontCollection, Scale};
+
+    #[test]
+    fn cache_test() {
+        let font_data = include_bytes!("../fonts/wqy-microhei/WenQuanYiMicroHei.ttf");
+        let font = FontCollection::from_bytes(font_data as &[u8])
+            .unwrap()
+            .into_font()
+            .unwrap();
+
+        let mut cache = Cache::builder()
+            .dimensions(32, 32)
+            .scale_tolerance(0.1)
+            .position_tolerance(0.1)
+            .pad_glyphs(false)
+            .build();
+        let strings = [
+            ("Hello World!", 15.0),
+            ("Hello World!", 14.0),
+            ("Hello World!", 10.0),
+            ("Hello World!", 15.0),
+            ("Hello World!", 14.0),
+            ("Hello World!", 10.0),
+        ];
+        for &(string, scale) in &strings {
+            println!("Caching {:?}", (string, scale));
+            for glyph in font.layout(string, Scale::uniform(scale), point(0.0, 0.0)) {
+                cache.queue_glyph(0, glyph);
+            }
+            cache.cache_queued(|_, _| {}).unwrap();
+        }
+    }
+
+    #[test]
+    fn need_to_check_whole_cache() {
+        let font_data = include_bytes!("../fonts/wqy-microhei/WenQuanYiMicroHei.ttf");
+        let font = Font::from_bytes(font_data as &[u8]).unwrap();
+
+        let glyph = font.glyph('l');
+
+        let small = glyph.clone().scaled(Scale::uniform(10.0));
+        let large = glyph.clone().scaled(Scale::uniform(10.05));
+
+        let small_left = small.clone().positioned(point(0.0, 0.0));
+        let large_left = large.clone().positioned(point(0.0, 0.0));
+        let large_right = large.clone().positioned(point(-0.2, 0.0));
+
+        let mut cache = Cache::builder()
+            .dimensions(32, 32)
+            .scale_tolerance(0.1)
+            .position_tolerance(0.1)
+            .pad_glyphs(false)
+            .build();
+
+        cache.queue_glyph(0, small_left.clone());
+        // Next line is noop since it's within the scale tolerance of small_left:
+        cache.queue_glyph(0, large_left.clone());
+        cache.queue_glyph(0, large_right.clone());
+
+        cache.cache_queued(|_, _| {}).unwrap();
+
+        cache.rect_for(0, &small_left).unwrap();
+        cache.rect_for(0, &large_left).unwrap();
+        cache.rect_for(0, &large_right).unwrap();
+    }
+
+    #[test]
+    fn lossy_info() {
+        let font_data = include_bytes!("../fonts/wqy-microhei/WenQuanYiMicroHei.ttf");
+        let font = Font::from_bytes(font_data as &[u8]).unwrap();
+        let glyph = font.glyph('l');
+
+        let small = glyph.clone().scaled(Scale::uniform(9.91));
+        let near = glyph.clone().scaled(Scale::uniform(10.09));
+        let far = glyph.clone().scaled(Scale::uniform(10.11));
+        let really_far = glyph.clone().scaled(Scale::uniform(12.0));
+
+        let small_pos = small.clone().positioned(point(0.0, 0.0));
+        let match_1 = near.clone().positioned(point(-10.0, -0.1));
+        let match_2 = near.clone().positioned(point(5.1, 0.24));
+        let match_3 = small.clone().positioned(point(-100.2, 50.1));
+
+        let miss_1 = far.clone().positioned(point(0.0, 0.0));
+        let miss_2 = really_far.clone().positioned(point(0.0, 0.0));
+        let miss_3 = small.clone().positioned(point(0.3, 0.0));
+
+        let cache = Cache::builder()
+            .scale_tolerance(0.2)
+            .position_tolerance(0.5)
+            .build();
+
+        let small_info = cache.lossy_info_for(0, &small_pos);
+
+        assert_eq!(small_info, cache.lossy_info_for(0, &match_1));
+        assert_eq!(small_info, cache.lossy_info_for(0, &match_2));
+        assert_eq!(small_info, cache.lossy_info_for(0, &match_3));
+
+        assert_ne!(small_info, cache.lossy_info_for(0, &miss_1));
+        assert_ne!(small_info, cache.lossy_info_for(0, &miss_2));
+        assert_ne!(small_info, cache.lossy_info_for(0, &miss_3));
+    }
+
+    #[test]
+    fn cache_to_builder() {
+        let cache = CacheBuilder {
+            dimensions: (32, 64),
+            scale_tolerance: 0.2,
+            position_tolerance: 0.3,
+            pad_glyphs: false,
+            multithread: false,
+        }.build();
+
+        let to_builder: CacheBuilder = cache.to_builder();
+
+        assert_eq!(to_builder.dimensions, (32, 64));
+        assert_relative_eq!(to_builder.scale_tolerance, 0.2);
+        assert_relative_eq!(to_builder.position_tolerance, 0.3);
+        assert_eq!(to_builder.pad_glyphs, false);
+        assert_eq!(to_builder.multithread, false);
+    }
+
+    #[test]
+    fn builder_rebuild() {
+        let mut cache = Cache::builder()
+            .dimensions(32, 64)
+            .scale_tolerance(0.2)
+            .position_tolerance(0.3)
+            .pad_glyphs(false)
+            .multithread(true)
+            .build();
+
+        let font = Font::from_bytes(
+            include_bytes!("../fonts/wqy-microhei/WenQuanYiMicroHei.ttf") as &[u8],
+        ).unwrap();
+        cache.queue_glyph(
+            0,
+            font.glyph('l')
+                .scaled(Scale::uniform(25.0))
+                .positioned(point(0.0, 0.0)),
+        );
+        cache.cache_queued(|_, _| {}).unwrap();
+
+        cache.queue_glyph(
+            0,
+            font.glyph('a')
+                .scaled(Scale::uniform(25.0))
+                .positioned(point(0.0, 0.0)),
+        );
+
+        Cache::builder()
+            .dimensions(64, 128)
+            .scale_tolerance(0.05)
+            .position_tolerance(0.15)
+            .pad_glyphs(true)
+            .multithread(false)
+            .rebuild(&mut cache);
+
+        assert_eq!(cache.width, 64);
+        assert_eq!(cache.height, 128);
+        assert_relative_eq!(cache.scale_tolerance, 0.05);
+        assert_relative_eq!(cache.position_tolerance, 0.15);
+        assert_eq!(cache.pad_glyphs, true);
+        assert_eq!(cache.multithread, false);
+
+        assert!(
+            cache.all_glyphs.is_empty(),
+            "cache should have been cleared"
+        );
+
+        assert_eq!(cache.queue.len(), 1, "cache should have an unchanged queue");
+    }
+}
diff --git a/rustc_deps/vendor/rusttype/src/lib.rs b/rustc_deps/vendor/rusttype/src/lib.rs
new file mode 100644
index 0000000..85fe6ad
--- /dev/null
+++ b/rustc_deps/vendor/rusttype/src/lib.rs
@@ -0,0 +1,1099 @@
+//! RustType is a pure Rust alternative to libraries like FreeType.
+//!
+//! The current capabilities of RustType:
+//!
+//! * Reading TrueType formatted fonts and font collections. This includes
+//!   `*.ttf` as well as a subset of `*.otf` font files.
+//! * Retrieving glyph shapes and commonly used properties for a font and its
+//!   glyphs.
+//! * Laying out glyphs horizontally using horizontal and vertical metrics, and
+//!   glyph-pair-specific kerning.
+//! * Rasterising glyphs with sub-pixel positioning using an accurate analytical
+//!   algorithm (not based on sampling).
+//! * Managing a font cache on the GPU with the `gpu_cache` module. This keeps
+//!   recently used glyph renderings in a dynamic cache in GPU memory to
+//!   minimise texture uploads per-frame. It also allows you keep the draw call
+//!   count for text very low, as all glyphs are kept in one GPU texture.
+//!
+//! Notable things that RustType does not support *yet*:
+//!
+//! * OpenType formatted fonts that are not just TrueType fonts (OpenType is a
+//!   superset of TrueType). Notably there is no support yet for cubic Bezier
+//!   curves used in glyphs.
+//! * Font hinting.
+//! * Ligatures of any kind.
+//! * Some less common TrueType sub-formats.
+//! * Right-to-left and vertical text layout.
+//!
+//! # Getting Started
+//!
+//! To hit the ground running with RustType, look at the `simple.rs` example
+//! supplied with the crate. It demonstrates loading a font file, rasterising an
+//! arbitrary string, and displaying the result as ASCII art. If you prefer to
+//! just look at the documentation, the entry point for loading fonts is
+//! `FontCollection`, from which you can access individual fonts, then their
+//! glyphs.
+//!
+//! # Glyphs
+//!
+//! The glyph API uses wrapper structs to augment a glyph with information such
+//! as scaling and positioning, making relevant methods that make use of this
+//! information available as appropriate. For example, given a `Glyph` `glyph`
+//! obtained directly from a `Font`:
+//!
+//! ```no_run
+//! # use rusttype::*;
+//! # let glyph: Glyph<'static> = unimplemented!();
+//! // One of the few things you can do with an unsized, positionless glyph is get its id.
+//! let id = glyph.id();
+//! let glyph = glyph.scaled(Scale::uniform(10.0));
+//! // Now glyph is a ScaledGlyph, you can do more with it, as well as what you can do with Glyph.
+//! // For example, you can access the correctly scaled horizontal metrics for the glyph.
+//! let h_metrics = glyph.h_metrics();
+//! let glyph = glyph.positioned(point(5.0, 3.0));
+//! // Now glyph is a PositionedGlyph, and you can do even more with it, e.g. drawing.
+//! glyph.draw(|x, y, v| {}); // In this case the pixel values are not used.
+//! ```
+//!
+//! # Unicode terminology
+//!
+//! This crate uses terminology for computerised typography as specified by the
+//! Unicode standard. If you are not sure of the differences between a code
+//! point, a character, and a glyph, you may want to check the [official Unicode
+//! glossary](http://unicode.org/glossary/), or alternatively, here's my take on
+//! it from a practical perspective:
+//!
+//! * A character is what you would conventionally call a single symbol,
+//!   independent of its appearance or representation in a particular font.
+//!   Examples include `a`, `A`, `ä`, `å`, `1`, `*`, `Ω`, etc.
+//! * A Unicode code point is the particular number that the Unicode standard
+//!   associates with a particular character. Note however that code points also
+//!   exist for things not conventionally thought of as characters by
+//!   themselves, but can be combined to form characters, such as diacritics
+//!   like accents. These "characters" are known in Unicode as "combining
+//!   characters". E.g., a diaeresis (`¨`) has the code point U+0308. If this
+//!   code point follows the code point U+0055 (the letter `u`), this sequence
+//!   represents the character `ü`. Note that there is also a single codepoint
+//!   for `ü`, U+00FC. This means that what visually looks like the same string
+//!   can have multiple different Unicode representations. Some fonts will have
+//!   glyphs (see below) for one sequence of codepoints, but not another that
+//!   has the same meaning. To deal with this problem it is recommended to use
+//!   Unicode normalisation, as provided by, for example, the
+//!   [unicode-normalization](http://crates.io/crates/unicode-normalization)
+//!   crate, to convert to code point sequences that work with the font in
+//!   question. Typically a font is more likely to support a single code point
+//!   vs. a sequence with the same meaning, so the best normalisation to use is
+//!   "canonical recomposition", known as NFC in the normalisation crate.
+//! * A glyph is a particular font's shape to draw the character for a
+//!   particular Unicode code point. This will have its own identifying number
+//!   unique to the font, its ID.
+
+#![allow(unknown_lints, renamed_and_removed_lints)]
+#![warn(clippy)]
+#![allow(
+    cyclomatic_complexity,
+    doc_markdown,
+    cast_lossless,
+    many_single_char_names
+)]
+#![cfg_attr(feature = "bench", feature(test))]
+#[cfg(feature = "bench")]
+extern crate test;
+#[cfg(test)]
+extern crate unicode_normalization;
+#[cfg(test)]
+#[macro_use]
+extern crate lazy_static;
+
+#[macro_use]
+extern crate approx;
+extern crate arrayvec;
+extern crate ordered_float;
+extern crate stb_truetype;
+
+mod geometry;
+mod rasterizer;
+
+#[cfg(feature = "gpu_cache")]
+pub mod gpu_cache;
+
+pub use geometry::{point, vector, Curve, Line, Point, Rect, Vector};
+use stb_truetype as tt;
+use std::fmt;
+use std::sync::Arc;
+
+/// A collection of fonts read straight from a font file's data. The data in the
+/// collection is not validated. This structure may or may not own the font
+/// data.
+///
+/// # Lifetime
+/// The lifetime reflects the font data lifetime. `FontCollection<'static>`
+/// covers most cases ie both dynamically loaded owned data and for referenced
+/// compile time font data.
+#[derive(Clone, Debug)]
+pub struct FontCollection<'a>(SharedBytes<'a>);
+/// A single font. This may or may not own the font data.
+///
+/// # Lifetime
+/// The lifetime reflects the font data lifetime. `Font<'static>` covers most
+/// cases ie both dynamically loaded owned data and for referenced compile time
+/// font data.
+///
+/// # Example
+///
+/// ```
+/// # use rusttype::{Font, Error};
+/// # fn example() -> Result<(), Error> {
+/// let font_data: &[u8] = include_bytes!("../fonts/dejavu/DejaVuSansMono.ttf");
+/// let font: Font<'static> = Font::from_bytes(font_data)?;
+///
+/// let owned_font_data: Vec<u8> = font_data.to_vec();
+/// let from_owned_font: Font<'static> = Font::from_bytes(owned_font_data)?;
+/// # Ok(())
+/// # }
+/// ```
+#[derive(Clone)]
+pub struct Font<'a> {
+    info: tt::FontInfo<SharedBytes<'a>>,
+}
+
+impl<'a> fmt::Debug for Font<'a> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "Font")
+    }
+}
+
+/// `SharedBytes` handles the lifetime of font data used in RustType. The data
+/// is either a shared reference to externally owned data, or managed by
+/// reference counting. `SharedBytes` can be conveniently used with `From` and
+/// `Into`, and dereferences to the contained bytes.
+///
+/// # Lifetime
+/// The lifetime reflects the font data lifetime. `SharedBytes<'static>` covers
+/// most cases ie both dynamically loaded owned data and for referenced compile
+/// time font data.
+#[derive(Clone, Debug)]
+pub enum SharedBytes<'a> {
+    ByRef(&'a [u8]),
+    ByArc(Arc<[u8]>),
+}
+
+impl<'a> ::std::ops::Deref for SharedBytes<'a> {
+    type Target = [u8];
+    fn deref(&self) -> &[u8] {
+        match *self {
+            SharedBytes::ByRef(bytes) => bytes,
+            SharedBytes::ByArc(ref bytes) => &**bytes,
+        }
+    }
+}
+/// ```
+/// # use rusttype::SharedBytes;
+/// let bytes: &[u8] = &[0u8, 1, 2, 3];
+/// let shared: SharedBytes = bytes.into();
+/// assert_eq!(&*shared, bytes);
+/// ```
+impl<'a> From<&'a [u8]> for SharedBytes<'a> {
+    fn from(bytes: &'a [u8]) -> SharedBytes<'a> {
+        SharedBytes::ByRef(bytes)
+    }
+}
+/// ```
+/// # use rusttype::SharedBytes;
+/// # use std::sync::Arc;
+/// let bytes: Arc<[u8]> = vec![0u8, 1, 2, 3].into();
+/// let shared: SharedBytes = Arc::clone(&bytes).into();
+/// assert_eq!(&*shared, &*bytes);
+/// ```
+impl From<Arc<[u8]>> for SharedBytes<'static> {
+    fn from(bytes: Arc<[u8]>) -> SharedBytes<'static> {
+        SharedBytes::ByArc(bytes)
+    }
+}
+/// ```
+/// # use rusttype::SharedBytes;
+/// let bytes: Box<[u8]> = vec![0u8, 1, 2, 3].into();
+/// let shared: SharedBytes = bytes.into();
+/// assert_eq!(&*shared, &[0u8, 1, 2, 3]);
+/// ```
+impl From<Box<[u8]>> for SharedBytes<'static> {
+    fn from(bytes: Box<[u8]>) -> SharedBytes<'static> {
+        SharedBytes::ByArc(bytes.into())
+    }
+}
+/// ```
+/// # use rusttype::SharedBytes;
+/// let bytes = vec![0u8, 1, 2, 3];
+/// let shared: SharedBytes = bytes.into();
+/// assert_eq!(&*shared, &[0u8, 1, 2, 3]);
+/// ```
+impl From<Vec<u8>> for SharedBytes<'static> {
+    fn from(bytes: Vec<u8>) -> SharedBytes<'static> {
+        SharedBytes::ByArc(bytes.into())
+    }
+}
+/// ```
+/// # use rusttype::SharedBytes;
+/// let bytes = vec![0u8, 1, 2, 3];
+/// let shared: SharedBytes = (&bytes).into();
+/// assert_eq!(&*shared, &bytes as &[u8]);
+/// ```
+impl<'a, T: AsRef<[u8]>> From<&'a T> for SharedBytes<'a> {
+    fn from(bytes: &'a T) -> SharedBytes<'a> {
+        SharedBytes::ByRef(bytes.as_ref())
+    }
+}
+
+#[test]
+fn lazy_static_shared_bytes() {
+    lazy_static! {
+        static ref BYTES: Vec<u8> = vec![0, 1, 2, 3];
+    }
+    let shared_bytes: SharedBytes<'static> = (&*BYTES).into();
+    assert_eq!(&*shared_bytes, &[0, 1, 2, 3]);
+}
+
+/// Represents a Unicode code point.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
+pub struct Codepoint(pub u32);
+/// Represents a glyph identifier for a particular font. This identifier will
+/// not necessarily correspond to the correct glyph in a font other than the
+/// one that it was obtained from.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
+pub struct GlyphId(pub u32);
+/// A single glyph of a font. this may either be a thin wrapper referring to the
+/// font and the glyph id, or it may be a standalone glyph that owns the data
+/// needed by it.
+///
+/// A `Glyph` does not have an inherent scale or position associated with it. To
+/// augment a glyph with a size, give it a scale using `scaled`. You can then
+/// position it using `positioned`.
+#[derive(Clone)]
+pub struct Glyph<'a> {
+    inner: GlyphInner<'a>,
+}
+
+impl<'a> fmt::Debug for Glyph<'a> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("Glyph").field("id", &self.id().0).finish()
+    }
+}
+
+#[derive(Clone)]
+enum GlyphInner<'a> {
+    Proxy(Font<'a>, u32),
+    Shared(Arc<SharedGlyphData>),
+}
+
+#[derive(Debug)]
+pub struct SharedGlyphData {
+    pub id: u32,
+    pub extents: Option<Rect<i32>>,
+    pub scale_for_1_pixel: f32,
+    pub unit_h_metrics: HMetrics,
+    pub shape: Option<Vec<tt::Vertex>>,
+}
+/// The "horizontal metrics" of a glyph. This is useful for calculating the
+/// horizontal offset of a glyph from the previous one in a string when laying a
+/// string out horizontally.
+#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
+pub struct HMetrics {
+    /// The horizontal offset that the origin of the next glyph should be from
+    /// the origin of this glyph.
+    pub advance_width: f32,
+    /// The horizontal offset between the origin of this glyph and the leftmost
+    /// edge/point of the glyph.
+    pub left_side_bearing: f32,
+}
+#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
+/// The "vertical metrics" of a font at a particular scale. This is useful for
+/// calculating the amount of vertical space to give a line of text, and for
+/// computing the vertical offset between successive lines.
+pub struct VMetrics {
+    /// The highest point that any glyph in the font extends to above the
+    /// baseline. Typically positive.
+    pub ascent: f32,
+    /// The lowest point that any glyph in the font extends to below the
+    /// baseline. Typically negative.
+    pub descent: f32,
+    /// The gap to leave between the descent of one line and the ascent of the
+    /// next. This is of course only a guideline given by the font's designers.
+    pub line_gap: f32,
+}
+
+impl From<tt::VMetrics> for VMetrics {
+    fn from(vm: tt::VMetrics) -> Self {
+        Self {
+            ascent: vm.ascent as f32,
+            descent: vm.descent as f32,
+            line_gap: vm.line_gap as f32,
+        }
+    }
+}
+
+impl ::std::ops::Mul<f32> for VMetrics {
+    type Output = VMetrics;
+
+    fn mul(self, rhs: f32) -> Self {
+        Self {
+            ascent: self.ascent * rhs,
+            descent: self.descent * rhs,
+            line_gap: self.line_gap * rhs,
+        }
+    }
+}
+
+/// A glyph augmented with scaling information. You can query such a glyph for
+/// information that depends on the scale of the glyph.
+#[derive(Clone)]
+pub struct ScaledGlyph<'a> {
+    g: Glyph<'a>,
+    api_scale: Scale,
+    scale: Vector<f32>,
+}
+
+impl<'a> fmt::Debug for ScaledGlyph<'a> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("ScaledGlyph")
+            .field("id", &self.id().0)
+            .field("scale", &self.api_scale)
+            .finish()
+    }
+}
+
+/// A glyph augmented with positioning and scaling information. You can query
+/// such a glyph for information that depends on the scale and position of the
+/// glyph.
+#[derive(Clone)]
+pub struct PositionedGlyph<'a> {
+    sg: ScaledGlyph<'a>,
+    position: Point<f32>,
+    bb: Option<Rect<i32>>,
+}
+
+impl<'a> fmt::Debug for PositionedGlyph<'a> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("PositionedGlyph")
+            .field("id", &self.id().0)
+            .field("scale", &self.scale())
+            .field("position", &self.position)
+            .finish()
+    }
+}
+
+/// Defines the size of a rendered face of a font, in pixels, horizontally and
+/// vertically. A vertical scale of `y` pixels means that the distance betwen
+/// the ascent and descent lines (see `VMetrics`) of the face will be `y`
+/// pixels. If `x` and `y` are equal the scaling is uniform. Non-uniform scaling
+/// by a factor *f* in the horizontal direction is achieved by setting `x` equal
+/// to *f* times `y`.
+#[derive(Copy, Clone, PartialEq, PartialOrd, Debug)]
+pub struct Scale {
+    /// Horizontal scale, in pixels.
+    pub x: f32,
+    /// Vertical scale, in pixels.
+    pub y: f32,
+}
+
+impl Scale {
+    /// Uniform scaling, equivalent to `Scale { x: s, y: s }`.
+    #[inline]
+    pub fn uniform(s: f32) -> Scale {
+        Scale { x: s, y: s }
+    }
+}
+/// A trait for types that can be converted into a `GlyphId`, in the context of
+/// a specific font.
+///
+/// Many `rusttype` functions that operate on characters accept values of any
+/// type that implements `IntoGlyphId`. Such types include `char`, `Codepoint`,
+/// and obviously `GlyphId` itself.
+pub trait IntoGlyphId {
+    /// Convert `self` into a `GlyphId`, consulting the index map of `font` if
+    /// necessary.
+    fn into_glyph_id(self, &Font) -> GlyphId;
+}
+impl IntoGlyphId for char {
+    fn into_glyph_id(self, font: &Font) -> GlyphId {
+        GlyphId(font.info.find_glyph_index(self as u32))
+    }
+}
+impl IntoGlyphId for Codepoint {
+    fn into_glyph_id(self, font: &Font) -> GlyphId {
+        GlyphId(font.info.find_glyph_index(self.0))
+    }
+}
+impl IntoGlyphId for GlyphId {
+    #[inline]
+    fn into_glyph_id(self, _font: &Font) -> GlyphId {
+        self
+    }
+}
+impl<'a> FontCollection<'a> {
+    /// Constructs a font collection from an array of bytes, typically loaded
+    /// from a font file, which may be a single font or a TrueType Collection
+    /// holding a number of fonts. This array may be owned (e.g. `Vec<u8>`), or
+    /// borrowed (`&[u8]`). As long as `From<T>` is implemented for `Bytes` for
+    /// some type `T`, `T` can be used as input.
+    ///
+    /// This returns an error if `bytes` does not seem to be font data in a
+    /// format we recognize.
+    pub fn from_bytes<B: Into<SharedBytes<'a>>>(bytes: B) -> Result<FontCollection<'a>, Error> {
+        let bytes = bytes.into();
+        // We should use tt::is_collection once it lands in stb_truetype-rs:
+        // https://github.com/redox-os/stb_truetype-rs/pull/15
+        if !tt::is_font(&bytes) && &bytes[0..4] != b"ttcf" {
+            return Err(Error::UnrecognizedFormat);
+        }
+
+        Ok(FontCollection(bytes))
+    }
+    /// If this `FontCollection` holds a single font, or a TrueType Collection
+    /// containing only one font, return that as a `Font`. The `FontCollection`
+    /// is consumed.
+    ///
+    /// If this `FontCollection` holds multiple fonts, return a
+    /// `CollectionContainsMultipleFonts` error.
+    ///
+    /// If an error occurs, the `FontCollection` is lost, since this function
+    /// takes ownership of it, and the error values don't give it back. If that
+    /// is a problem, use the `font_at` or `into_fonts` methods instead, which
+    /// borrow the `FontCollection` rather than taking ownership of it.
+    pub fn into_font(self) -> Result<Font<'a>, Error> {
+        let offset = if tt::is_font(&self.0) {
+            0
+        } else if tt::get_font_offset_for_index(&self.0, 1).is_some() {
+            return Err(Error::CollectionContainsMultipleFonts);
+        } else {
+            // We now know that either a) `self.0` is a collection with only one
+            // font, or b) `get_font_offset_for_index` found data it couldn't
+            // recognize. Request the first font's offset, distinguishing
+            // those two cases.
+            match tt::get_font_offset_for_index(&self.0, 0) {
+                None => return Err(Error::IllFormed),
+                Some(offset) => offset,
+            }
+        };
+        let info = tt::FontInfo::new(self.0, offset as usize).ok_or(Error::IllFormed)?;
+        Ok(Font { info })
+    }
+    /// Gets the font at index `i` in the font collection, if it exists and is
+    /// valid. The produced font borrows the font data that is either borrowed
+    /// or owned by this font collection.
+    pub fn font_at(&self, i: usize) -> Result<Font<'a>, Error> {
+        let offset = tt::get_font_offset_for_index(&self.0, i as i32)
+            .ok_or(Error::CollectionIndexOutOfBounds)?;
+        let info = tt::FontInfo::new(self.0.clone(), offset as usize).ok_or(Error::IllFormed)?;
+        Ok(Font { info })
+    }
+    /// Converts `self` into an `Iterator` yielding each `Font` that exists
+    /// within the collection.
+    pub fn into_fonts(self) -> IntoFontsIter<'a> {
+        IntoFontsIter {
+            collection: self,
+            next_index: 0,
+        }
+    }
+}
+pub struct IntoFontsIter<'a> {
+    next_index: usize,
+    collection: FontCollection<'a>,
+}
+impl<'a> Iterator for IntoFontsIter<'a> {
+    type Item = Result<Font<'a>, Error>;
+    fn next(&mut self) -> Option<Self::Item> {
+        let result = self.collection.font_at(self.next_index);
+        if let Err(Error::CollectionIndexOutOfBounds) = result {
+            return None;
+        }
+        self.next_index += 1;
+        Some(result)
+    }
+}
+impl<'a> Font<'a> {
+    /// Constructs a font from an array of bytes, this is a shortcut for
+    /// `FontCollection::from_bytes` for collections comprised of a single font.
+    pub fn from_bytes<B: Into<SharedBytes<'a>>>(bytes: B) -> Result<Font<'a>, Error> {
+        FontCollection::from_bytes(bytes).and_then(|c| c.into_font())
+    }
+
+    /// The "vertical metrics" for this font at a given scale. These metrics are
+    /// shared by all of the glyphs in the font. See `VMetrics` for more detail.
+    pub fn v_metrics(&self, scale: Scale) -> VMetrics {
+        let vm = self.info.get_v_metrics();
+        let scale = self.info.scale_for_pixel_height(scale.y);
+        VMetrics::from(vm) * scale
+    }
+
+    /// Get the unscaled VMetrics for this font, shared by all glyphs.
+    /// See `VMetrics` for more detail.
+    pub fn v_metrics_unscaled(&self) -> VMetrics {
+        VMetrics::from(self.info.get_v_metrics())
+    }
+
+    /// Returns the units per EM square of this font
+    pub fn units_per_em(&self) -> u16 {
+        self.info.units_per_em()
+    }
+
+    /// The number of glyphs present in this font. Glyph identifiers for this
+    /// font will always be in the range `0..self.glyph_count()`
+    pub fn glyph_count(&self) -> usize {
+        self.info.get_num_glyphs() as usize
+    }
+
+    /// Returns the corresponding glyph for a Unicode code point or a glyph id
+    /// for this font.
+    ///
+    /// If `id` is a `GlyphId`, it must be valid for this font; otherwise, this
+    /// function panics. `GlyphId`s should always be produced by looking up some
+    /// other sort of designator (like a Unicode code point) in a font, and
+    /// should only be used to index the font they were produced for.
+    ///
+    /// Note that code points without corresponding glyphs in this font map to
+    /// the ".notdef" glyph, glyph 0.
+    pub fn glyph<C: IntoGlyphId>(&self, id: C) -> Glyph<'a> {
+        let gid = id.into_glyph_id(self);
+        assert!((gid.0 as usize) < self.glyph_count());
+        // font clone either a reference clone, or arc clone
+        Glyph::new(GlyphInner::Proxy(self.clone(), gid.0))
+    }
+    /// A convenience function.
+    ///
+    /// Returns an iterator that produces the glyphs corresponding to the code
+    /// points or glyph ids produced by the given iterator `itr`.
+    ///
+    /// This is equivalent in behaviour to `itr.map(|c| font.glyph(c))`.
+    pub fn glyphs_for<I: Iterator>(&self, itr: I) -> GlyphIter<I>
+    where
+        I::Item: IntoGlyphId,
+    {
+        GlyphIter { font: self, itr }
+    }
+    /// Returns an iterator over the names for this font.
+    pub fn font_name_strings(&self) -> tt::FontNameIter<SharedBytes<'a>> {
+        self.info.get_font_name_strings()
+    }
+    /// A convenience function for laying out glyphs for a string horizontally.
+    /// It does not take control characters like line breaks into account, as
+    /// treatment of these is likely to depend on the application.
+    ///
+    /// Note that this function does not perform Unicode normalisation.
+    /// Composite characters (such as ö constructed from two code points, ¨ and
+    /// o), will not be normalised to single code points. So if a font does not
+    /// contain a glyph for each separate code point, but does contain one for
+    /// the normalised single code point (which is common), the desired glyph
+    /// will not be produced, despite being present in the font. Deal with this
+    /// by performing Unicode normalisation on the input string before passing
+    /// it to `layout`. The crate
+    /// [unicode-normalization](http://crates.io/crates/unicode-normalization)
+    /// is perfect for this purpose.
+    ///
+    /// Calling this function is equivalent to a longer sequence of operations
+    /// involving `glyphs_for`, e.g.
+    ///
+    /// ```no_run
+    /// # use rusttype::*;
+    /// # let (scale, start) = (Scale::uniform(0.0), point(0.0, 0.0));
+    /// # let font: Font = unimplemented!();
+    /// font.layout("Hello World!", scale, start)
+    /// # ;
+    /// ```
+    ///
+    /// produces an iterator with behaviour equivalent to the following:
+    ///
+    /// ```no_run
+    /// # use rusttype::*;
+    /// # let (scale, start) = (Scale::uniform(0.0), point(0.0, 0.0));
+    /// # let font: Font = unimplemented!();
+    /// font.glyphs_for("Hello World!".chars())
+    ///     .scan((None, 0.0), |&mut (mut last, mut x), g| {
+    ///         let g = g.scaled(scale);
+    ///         if let Some(last) = last {
+    ///             x += font.pair_kerning(scale, last, g.id());
+    ///         }
+    ///         let w = g.h_metrics().advance_width;
+    ///         let next = g.positioned(start + vector(x, 0.0));
+    ///         last = Some(next.id());
+    ///         x += w;
+    ///         Some(next)
+    ///     })
+    /// # ;
+    /// ```
+    pub fn layout<'b, 'c>(
+        &'b self,
+        s: &'c str,
+        scale: Scale,
+        start: Point<f32>,
+    ) -> LayoutIter<'b, 'c> {
+        LayoutIter {
+            font: self,
+            chars: s.chars(),
+            caret: 0.0,
+            scale,
+            start,
+            last_glyph: None,
+        }
+    }
+    /// Returns additional kerning to apply as well as that given by HMetrics
+    /// for a particular pair of glyphs.
+    pub fn pair_kerning<A, B>(&self, scale: Scale, first: A, second: B) -> f32
+    where
+        A: IntoGlyphId,
+        B: IntoGlyphId,
+    {
+        let first_id = first.into_glyph_id(self);
+        let second_id = second.into_glyph_id(self);
+        let factor = self.info.scale_for_pixel_height(scale.y) * (scale.x / scale.y);
+        let kern = self.info.get_glyph_kern_advance(first_id.0, second_id.0);
+        factor * kern as f32
+    }
+}
+#[derive(Clone)]
+pub struct GlyphIter<'a, I: Iterator>
+where
+    I::Item: IntoGlyphId,
+{
+    font: &'a Font<'a>,
+    itr: I,
+}
+impl<'a, I: Iterator> Iterator for GlyphIter<'a, I>
+where
+    I::Item: IntoGlyphId,
+{
+    type Item = Glyph<'a>;
+    fn next(&mut self) -> Option<Glyph<'a>> {
+        self.itr.next().map(|c| self.font.glyph(c))
+    }
+}
+#[derive(Clone)]
+pub struct LayoutIter<'a, 'b> {
+    font: &'a Font<'a>,
+    chars: ::std::str::Chars<'b>,
+    caret: f32,
+    scale: Scale,
+    start: Point<f32>,
+    last_glyph: Option<GlyphId>,
+}
+impl<'a, 'b> Iterator for LayoutIter<'a, 'b> {
+    type Item = PositionedGlyph<'a>;
+    fn next(&mut self) -> Option<PositionedGlyph<'a>> {
+        self.chars.next().map(|c| {
+            let g = self.font.glyph(c).scaled(self.scale);
+            if let Some(last) = self.last_glyph {
+                self.caret += self.font.pair_kerning(self.scale, last, g.id());
+            }
+            let g = g.positioned(point(self.start.x + self.caret, self.start.y));
+            self.caret += g.sg.h_metrics().advance_width;
+            self.last_glyph = Some(g.id());
+            g
+        })
+    }
+}
+impl<'a> Glyph<'a> {
+    fn new(inner: GlyphInner<'a>) -> Glyph<'a> {
+        Glyph { inner }
+    }
+    /// The font to which this glyph belongs. If the glyph is a standalone glyph
+    /// that owns its resources, it no longer has a reference to the font which
+    /// it was created from (using `standalone()`). In which case, `None` is
+    /// returned.
+    pub fn font(&self) -> Option<&Font<'a>> {
+        match self.inner {
+            GlyphInner::Proxy(ref f, _) => Some(f),
+            GlyphInner::Shared(_) => None,
+        }
+    }
+    /// The glyph identifier for this glyph.
+    pub fn id(&self) -> GlyphId {
+        match self.inner {
+            GlyphInner::Proxy(_, id) => GlyphId(id),
+            GlyphInner::Shared(ref data) => GlyphId(data.id),
+        }
+    }
+    /// Augments this glyph with scaling information, making methods that depend
+    /// on the scale of the glyph available.
+    pub fn scaled(self, scale: Scale) -> ScaledGlyph<'a> {
+        let (scale_x, scale_y) = match self.inner {
+            GlyphInner::Proxy(ref font, _) => {
+                let scale_y = font.info.scale_for_pixel_height(scale.y);
+                let scale_x = scale_y * scale.x / scale.y;
+                (scale_x, scale_y)
+            }
+            GlyphInner::Shared(ref data) => {
+                let scale_y = data.scale_for_1_pixel * scale.y;
+                let scale_x = scale_y * scale.x / scale.y;
+                (scale_x, scale_y)
+            }
+        };
+        ScaledGlyph {
+            g: self,
+            api_scale: scale,
+            scale: vector(scale_x, scale_y),
+        }
+    }
+    /// Turns a `Glyph<'a>` into a `Glyph<'static>`. This produces a glyph that
+    /// owns its resources, extracted from the font. This glyph can outlive the
+    /// font that it comes from.
+    ///
+    /// Calling `standalone()` on a standalone glyph shares the resources, and
+    /// is equivalent to `clone()`.
+    pub fn standalone(&self) -> Glyph<'static> {
+        match self.inner {
+            GlyphInner::Proxy(ref font, id) => {
+                Glyph::new(GlyphInner::Shared(Arc::new(SharedGlyphData {
+                    id,
+                    scale_for_1_pixel: font.info.scale_for_pixel_height(1.0),
+                    unit_h_metrics: {
+                        let hm = font.info.get_glyph_h_metrics(id);
+                        HMetrics {
+                            advance_width: hm.advance_width as f32,
+                            left_side_bearing: hm.left_side_bearing as f32,
+                        }
+                    },
+                    extents: font.info.get_glyph_box(id).map(|bb| Rect {
+                        min: point(bb.x0 as i32, -(bb.y1 as i32)),
+                        max: point(bb.x1 as i32, -(bb.y0 as i32)),
+                    }),
+                    shape: font.info.get_glyph_shape(id),
+                })))
+            }
+            GlyphInner::Shared(ref data) => Glyph::new(GlyphInner::Shared(data.clone())),
+        }
+    }
+    /// Get the data from this glyph (such as width, extents, vertices, etc.).
+    /// Only possible if the glyph is a shared glyph.
+    pub fn get_data(&self) -> Option<Arc<SharedGlyphData>> {
+        match self.inner {
+            GlyphInner::Proxy(..) => None,
+            GlyphInner::Shared(ref s) => Some(s.clone()),
+        }
+    }
+}
+/// Part of a `Contour`, either a `Line` or a `Curve`.
+#[derive(Copy, Clone, Debug)]
+pub enum Segment {
+    Line(Line),
+    Curve(Curve),
+}
+/// A closed loop consisting of a sequence of `Segment`s.
+#[derive(Clone, Debug)]
+pub struct Contour {
+    pub segments: Vec<Segment>,
+}
+impl<'a> ScaledGlyph<'a> {
+    /// The glyph identifier for this glyph.
+    pub fn id(&self) -> GlyphId {
+        self.g.id()
+    }
+    /// The font to which this glyph belongs. If the glyph is a standalone glyph
+    /// that owns its resources, it no longer has a reference to the font which
+    /// it was created from (using `standalone()`). In which case, `None` is
+    /// returned.
+    pub fn font(&self) -> Option<&Font<'a>> {
+        self.g.font()
+    }
+    /// A reference to this glyph without the scaling
+    pub fn into_unscaled(self) -> Glyph<'a> {
+        self.g
+    }
+    /// Removes the scaling from this glyph
+    pub fn unscaled(&self) -> &Glyph<'a> {
+        &self.g
+    }
+    /// Augments this glyph with positioning information, making methods that
+    /// depend on the position of the glyph available.
+    pub fn positioned(self, p: Point<f32>) -> PositionedGlyph<'a> {
+        // Use subpixel fraction in floor/ceil rounding to elimate rounding error
+        // from identical subpixel positions
+        let (x_trunc, x_fract) = (p.x.trunc() as i32, p.x.fract());
+        let (y_trunc, y_fract) = (p.y.trunc() as i32, p.y.fract());
+
+        let bb = match self.g.inner {
+            GlyphInner::Proxy(ref font, id) => font
+                .info
+                .get_glyph_bitmap_box_subpixel(id, self.scale.x, self.scale.y, x_fract, y_fract)
+                .map(|bb| Rect {
+                    min: point(x_trunc + bb.x0, y_trunc + bb.y0),
+                    max: point(x_trunc + bb.x1, y_trunc + bb.y1),
+                }),
+            GlyphInner::Shared(ref data) => data.extents.map(|bb| Rect {
+                min: point(
+                    (bb.min.x as f32 * self.scale.x + x_fract).floor() as i32 + x_trunc,
+                    (bb.min.y as f32 * self.scale.y + y_fract).floor() as i32 + y_trunc,
+                ),
+                max: point(
+                    (bb.max.x as f32 * self.scale.x + x_fract).ceil() as i32 + x_trunc,
+                    (bb.max.y as f32 * self.scale.y + y_fract).ceil() as i32 + y_trunc,
+                ),
+            }),
+        };
+        PositionedGlyph {
+            sg: self,
+            position: p,
+            bb,
+        }
+    }
+    pub fn scale(&self) -> Scale {
+        self.api_scale
+    }
+    /// Retrieves the "horizontal metrics" of this glyph. See `HMetrics` for
+    /// more detail.
+    pub fn h_metrics(&self) -> HMetrics {
+        match self.g.inner {
+            GlyphInner::Proxy(ref font, id) => {
+                let hm = font.info.get_glyph_h_metrics(id);
+                HMetrics {
+                    advance_width: hm.advance_width as f32 * self.scale.x,
+                    left_side_bearing: hm.left_side_bearing as f32 * self.scale.x,
+                }
+            }
+            GlyphInner::Shared(ref data) => HMetrics {
+                advance_width: data.unit_h_metrics.advance_width * self.scale.x,
+                left_side_bearing: data.unit_h_metrics.left_side_bearing * self.scale.y,
+            },
+        }
+    }
+    fn shape_with_offset(&self, offset: Point<f32>) -> Option<Vec<Contour>> {
+        use stb_truetype::VertexType;
+        use std::mem::replace;
+        match self.g.inner {
+            GlyphInner::Proxy(ref font, id) => font.info.get_glyph_shape(id),
+            GlyphInner::Shared(ref data) => data.shape.clone(),
+        }.map(|shape| {
+            let mut result = Vec::new();
+            let mut current = Vec::new();
+            let mut last = point(0.0, 0.0);
+            for v in shape {
+                let end = point(
+                    v.x as f32 * self.scale.x + offset.x,
+                    v.y as f32 * self.scale.y + offset.y,
+                );
+                match v.vertex_type() {
+                    VertexType::MoveTo if !current.is_empty() => result.push(Contour {
+                        segments: replace(&mut current, Vec::new()),
+                    }),
+                    VertexType::LineTo => current.push(Segment::Line(Line { p: [last, end] })),
+                    VertexType::CurveTo => {
+                        let control = point(
+                            v.cx as f32 * self.scale.x + offset.x,
+                            v.cy as f32 * self.scale.y + offset.y,
+                        );
+                        current.push(Segment::Curve(Curve {
+                            p: [last, control, end],
+                        }))
+                    }
+                    _ => (),
+                }
+                last = end;
+            }
+            if !current.is_empty() {
+                result.push(Contour {
+                    segments: replace(&mut current, Vec::new()),
+                });
+            }
+            result
+        })
+    }
+    /// Produces a list of the contours that make up the shape of this glyph.
+    /// Each contour consists of a sequence of segments. Each segment is either
+    /// a straight `Line` or a `Curve`.
+    ///
+    /// The winding of the produced contours is clockwise for closed shapes,
+    /// anticlockwise for holes.
+    pub fn shape(&self) -> Option<Vec<Contour>> {
+        self.shape_with_offset(point(0.0, 0.0))
+    }
+    /// The bounding box of the shape of this glyph, not to be confused with
+    /// `pixel_bounding_box`, the conservative pixel-boundary bounding box. The
+    /// coordinates are relative to the glyph's origin.
+    pub fn exact_bounding_box(&self) -> Option<Rect<f32>> {
+        match self.g.inner {
+            GlyphInner::Proxy(ref font, id) => font.info.get_glyph_box(id).map(|bb| Rect {
+                min: point(bb.x0 as f32 * self.scale.x, -bb.y1 as f32 * self.scale.y),
+                max: point(bb.x1 as f32 * self.scale.x, -bb.y0 as f32 * self.scale.y),
+            }),
+            GlyphInner::Shared(ref data) => data.extents.map(|bb| Rect {
+                min: point(
+                    bb.min.x as f32 * self.scale.x,
+                    bb.min.y as f32 * self.scale.y,
+                ),
+                max: point(
+                    bb.max.x as f32 * self.scale.x,
+                    bb.max.y as f32 * self.scale.y,
+                ),
+            }),
+        }
+    }
+    /// Constructs a glyph that owns its data from this glyph. This is similar
+    /// to `Glyph::standalone`. See that function for more details.
+    pub fn standalone(&self) -> ScaledGlyph<'static> {
+        ScaledGlyph {
+            g: self.g.standalone(),
+            api_scale: self.api_scale,
+            scale: self.scale,
+        }
+    }
+}
+
+impl<'a> PositionedGlyph<'a> {
+    /// The glyph identifier for this glyph.
+    pub fn id(&self) -> GlyphId {
+        self.sg.id()
+    }
+    /// The font to which this glyph belongs. If the glyph is a standalone glyph
+    /// that owns its resources, it no longer has a reference to the font which
+    /// it was created from (using `standalone()`). In which case, `None` is
+    /// returned.
+    pub fn font(&self) -> Option<&Font<'a>> {
+        self.sg.font()
+    }
+    /// A reference to this glyph without positioning
+    pub fn unpositioned(&self) -> &ScaledGlyph<'a> {
+        &self.sg
+    }
+    /// Removes the positioning from this glyph
+    pub fn into_unpositioned(self) -> ScaledGlyph<'a> {
+        self.sg
+    }
+    /// The conservative pixel-boundary bounding box for this glyph. This is the
+    /// smallest rectangle aligned to pixel boundaries that encloses the shape
+    /// of this glyph at this position. Note that the origin of the glyph, at
+    /// pixel-space coordinates (0, 0), is at the top left of the bounding box.
+    pub fn pixel_bounding_box(&self) -> Option<Rect<i32>> {
+        self.bb
+    }
+    /// Similar to `ScaledGlyph::shape()`, but with the position of the glyph
+    /// taken into account.
+    pub fn shape(&self) -> Option<Vec<Contour>> {
+        self.sg.shape_with_offset(self.position)
+    }
+    pub fn scale(&self) -> Scale {
+        self.sg.api_scale
+    }
+    pub fn position(&self) -> Point<f32> {
+        self.position
+    }
+    /// Rasterises this glyph. For each pixel in the rect given by
+    /// `pixel_bounding_box()`, `o` is called:
+    ///
+    /// ```ignore
+    /// o(x, y, v)
+    /// ```
+    ///
+    /// where `x` and `y` are the coordinates of the pixel relative to the `min`
+    /// coordinates of the bounding box, and `v` is the analytically calculated
+    /// coverage of the pixel by the shape of the glyph. Calls to `o` proceed in
+    /// horizontal scanline order, similar to this pseudo-code:
+    ///
+    /// ```ignore
+    /// let bb = glyph.pixel_bounding_box();
+    /// for y in 0..bb.height() {
+    ///     for x in 0..bb.width() {
+    ///         o(x, y, calc_coverage(&glyph, x, y));
+    ///     }
+    /// }
+    /// ```
+    pub fn draw<O: FnMut(u32, u32, f32)>(&self, o: O) {
+        use geometry::{Curve, Line};
+        use stb_truetype::VertexType;
+        let shape = match self.sg.g.inner {
+            GlyphInner::Proxy(ref font, id) => {
+                font.info.get_glyph_shape(id).unwrap_or_else(Vec::new)
+            }
+            GlyphInner::Shared(ref data) => data.shape.clone().unwrap_or_else(Vec::new),
+        };
+        let bb = if let Some(bb) = self.bb.as_ref() {
+            bb
+        } else {
+            return;
+        };
+        let offset = vector(bb.min.x as f32, bb.min.y as f32);
+        let mut lines = Vec::new();
+        let mut curves = Vec::new();
+        let mut last = point(0.0, 0.0);
+        for v in shape {
+            let end = point(
+                v.x as f32 * self.sg.scale.x + self.position.x,
+                -v.y as f32 * self.sg.scale.y + self.position.y,
+            ) - offset;
+            match v.vertex_type() {
+                VertexType::LineTo => lines.push(Line { p: [last, end] }),
+                VertexType::CurveTo => {
+                    let control = point(
+                        v.cx as f32 * self.sg.scale.x + self.position.x,
+                        -v.cy as f32 * self.sg.scale.y + self.position.y,
+                    ) - offset;
+                    curves.push(Curve {
+                        p: [last, control, end],
+                    })
+                }
+                VertexType::MoveTo => {}
+            }
+            last = end;
+        }
+        rasterizer::rasterize(
+            &lines,
+            &curves,
+            (bb.max.x - bb.min.x) as u32,
+            (bb.max.y - bb.min.y) as u32,
+            o,
+        );
+    }
+    /// Constructs a glyph that owns its data from this glyph. This is similar
+    /// to `Glyph::standalone`. See that function for more details.
+    pub fn standalone(&self) -> PositionedGlyph<'static> {
+        PositionedGlyph {
+            sg: self.sg.standalone(),
+            bb: self.bb,
+            position: self.position,
+        }
+    }
+}
+
+/// The type for errors returned by rusttype.
+#[derive(Debug)]
+pub enum Error {
+    /// Font data presented to rusttype is not in a format that the library
+    /// recognizes.
+    UnrecognizedFormat,
+
+    /// Font data presented to rusttype was ill-formed (lacking necessary
+    /// tables, for example).
+    IllFormed,
+
+    /// The caller tried to access the `i`'th font from a `FontCollection`, but
+    /// the collection doesn't contain that many fonts.
+    CollectionIndexOutOfBounds,
+
+    /// The caller tried to convert a `FontCollection` into a font via
+    /// `into_font`, but the `FontCollection` contains more than one font.
+    CollectionContainsMultipleFonts,
+}
+
+impl fmt::Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter) -> std::result::Result<(), fmt::Error> {
+        f.write_str(std::error::Error::description(self))
+    }
+}
+
+impl std::error::Error for Error {
+    fn description(&self) -> &str {
+        use self::Error::*;
+        match *self {
+            UnrecognizedFormat => "Font data in unrecognized format",
+            IllFormed => "Font data is ill-formed",
+            CollectionIndexOutOfBounds => "Font collection has no font at the given index",
+            CollectionContainsMultipleFonts => {
+                "Attempted to convert collection into a font, \
+                 but collection contais more than one font"
+            }
+        }
+    }
+}
+
+impl std::convert::From<Error> for std::io::Error {
+    fn from(error: Error) -> Self {
+        std::io::Error::new(std::io::ErrorKind::Other, error)
+    }
+}
diff --git a/rustc_deps/vendor/rusttype/src/rasterizer.rs b/rustc_deps/vendor/rusttype/src/rasterizer.rs
new file mode 100644
index 0000000..807e3d4
--- /dev/null
+++ b/rustc_deps/vendor/rusttype/src/rasterizer.rs
@@ -0,0 +1,390 @@
+use arrayvec;
+use geometry::*;
+use ordered_float::OrderedFloat;
+
+trait SliceUp: Sized {
+    type PerSlice: Iterator<Item = Self>;
+    type Out: Iterator<Item = Self::PerSlice>;
+    fn slice_up_x(&self, planes: PlaneSet) -> Self::Out;
+    fn slice_up_y(&self, planes: PlaneSet) -> Self::Out;
+}
+
+type LineIter = ::std::option::IntoIter<Line>;
+
+#[derive(Debug)]
+struct LineSliceIter {
+    l: Line,
+    m: f32,
+    c: f32,
+    planes: PlaneSet,
+    i: usize,
+}
+
+impl Iterator for LineSliceIter {
+    type Item = LineIter;
+    fn next(&mut self) -> Option<LineIter> {
+        if self.i >= self.planes.count {
+            return None;
+        }
+        if self.m == 0.0 {
+            self.i += 1;
+            return Some(Some(self.l).into_iter());
+        }
+        let lower = self.i as f32;
+        let upper = lower + 1.0;
+        let lower_d = self.planes.start + self.planes.step * lower;
+        let upper_d = self.planes.start + self.planes.step * upper;
+        let mut lower_t = (lower_d - self.c) / self.m;
+        let mut upper_t = (upper_d - self.c) / self.m;
+        lower_t = lower_t.max(0.0).min(1.0);
+        upper_t = upper_t.max(0.0).min(1.0);
+        if self.m < 0.0 {
+            ::std::mem::swap(&mut lower_t, &mut upper_t);
+        }
+        self.i += 1;
+        if !relative_eq!(lower_t, upper_t) {
+            let p = &self.l.p;
+            let v = p[1] - p[0];
+            Some(
+                Some(Line {
+                    p: [p[0] + v * lower_t, p[0] + v * upper_t],
+                }).into_iter(),
+            )
+        } else {
+            Some(None.into_iter())
+        }
+    }
+}
+
+impl SliceUp for Line {
+    type PerSlice = LineIter;
+    type Out = LineSliceIter;
+    fn slice_up_x(&self, planes: PlaneSet) -> LineSliceIter {
+        let p = &self.p;
+        LineSliceIter {
+            l: *self,
+            planes,
+            i: 0,
+            m: p[1].x - p[0].x,
+            c: p[0].x,
+        }
+    }
+    fn slice_up_y(&self, planes: PlaneSet) -> LineSliceIter {
+        let p = &self.p;
+        LineSliceIter {
+            l: *self,
+            planes,
+            i: 0,
+            m: p[1].y - p[0].y,
+            c: p[0].y,
+        }
+    }
+}
+
+type CurveIter = arrayvec::IntoIter<[Curve; 2]>;
+
+struct CurveSliceIter {
+    curve: Curve,
+    planes: PlaneSet,
+    i: usize,
+    a: f32,
+    b: f32,
+    c_shift: f32,
+}
+
+impl Iterator for CurveSliceIter {
+    type Item = CurveIter;
+    fn next(&mut self) -> Option<Self::Item> {
+        use arrayvec::ArrayVec;
+        use geometry::solve_quadratic_real as solve;
+        use geometry::Cut;
+        use geometry::RealQuadraticSolution as RQS;
+        if self.i >= self.planes.count {
+            return None;
+        }
+        let lower = self.i as f32;
+        self.i += 1;
+        let upper = lower + self.planes.step;
+        let lower_d = self.planes.start + self.planes.step * lower;
+        let upper_d = self.planes.start + self.planes.step * upper;
+        let l_sol = solve(self.a, self.b, self.c_shift - lower_d);
+        let u_sol = solve(self.a, self.b, self.c_shift - upper_d);
+        let mut result = ArrayVec::<[Curve; 2]>::new();
+        match (l_sol.in_order(), u_sol.in_order()) {
+            (RQS::Two(a, b), RQS::Two(c, d)) => {
+                // Two pieces
+                let (a, b, c, d) = if self.a > 0.0 {
+                    (c, a, b, d)
+                } else {
+                    (a, c, d, b)
+                };
+                let (a, b, c, d) = (
+                    a.min(1.0).max(0.0),
+                    b.min(1.0).max(0.0),
+                    c.min(1.0).max(0.0),
+                    d.min(1.0).max(0.0),
+                );
+                if !relative_eq!(a, b) {
+                    result.push(self.curve.cut_from_to(a, b));
+                }
+                if !relative_eq!(c, d) {
+                    result.push(self.curve.cut_from_to(c, d));
+                }
+            }
+            (RQS::Two(a, b), RQS::None)
+            | (RQS::Two(a, b), RQS::Touch(_))
+            | (RQS::None, RQS::Two(a, b))
+            | (RQS::Touch(_), RQS::Two(a, b))
+            | (RQS::One(a), RQS::One(b)) => {
+                // One piece
+                let (a, b) = if a > b { (b, a) } else { (a, b) };
+                let a = a.min(1.0).max(0.0);
+                let b = b.min(1.0).max(0.0);
+                if !relative_eq!(a, b) {
+                    result.push(self.curve.cut_from_to(a, b));
+                }
+            }
+            (RQS::All, RQS::None) | (RQS::None, RQS::All) => {
+                // coincident with one plane
+                result.push(self.curve);
+            }
+            (RQS::None, RQS::None) => if self.a == 0.0
+                && self.b == 0.0
+                && self.c_shift >= lower_d
+                && self.c_shift <= upper_d
+            {
+                // parallel to planes, inbetween
+                result.push(self.curve);
+            },
+            _ => unreachable!(), // impossible
+        }
+        Some(result.into_iter())
+    }
+}
+
+#[derive(Debug)]
+struct PlaneSet {
+    start: f32,
+    step: f32,
+    count: usize,
+}
+
+impl SliceUp for Curve {
+    type PerSlice = CurveIter;
+    type Out = CurveSliceIter;
+    fn slice_up_x(&self, planes: PlaneSet) -> CurveSliceIter {
+        let p = &self.p;
+        CurveSliceIter {
+            curve: *self,
+            planes,
+            i: 0,
+            a: p[0].x - 2.0 * p[1].x + p[2].x,
+            b: 2.0 * (p[1].x - p[0].x),
+            c_shift: p[0].x,
+        }
+    }
+    fn slice_up_y(&self, planes: PlaneSet) -> CurveSliceIter {
+        let p = &self.p;
+        CurveSliceIter {
+            curve: *self,
+            planes,
+            i: 0,
+            a: p[0].y - 2.0 * p[1].y + p[2].y,
+            b: 2.0 * (p[1].y - p[0].y),
+            c_shift: p[0].y,
+        }
+    }
+}
+
+pub fn rasterize<O: FnMut(u32, u32, f32)>(
+    lines: &[Line],
+    curves: &[Curve],
+    width: u32,
+    height: u32,
+    mut output: O,
+) {
+    let mut lines: Vec<_> = lines.iter().map(|&l| (l, l.bounding_box())).collect();
+    lines.sort_by_key(|&(_, ref a)| OrderedFloat(a.min.y));
+    let mut curves: Vec<_> = curves.iter().map(|&c| (c, c.bounding_box())).collect();
+    curves.sort_by_key(|&(_, ref a)| OrderedFloat(a.min.y));
+    let mut y = 0;
+    let mut next_line = 0;
+    let mut next_curve = 0;
+    let mut active_lines_y = Vec::new();
+    let mut active_curves_y = Vec::new();
+    let mut active_lines_x = Vec::new();
+    let mut active_curves_x = Vec::new();
+    let mut scanline_lines = Vec::new();
+    let mut lines_to_remove = Vec::new();
+    let mut scanline_curves = Vec::new();
+    let mut curves_to_remove = Vec::new();
+    while y < height
+        && (next_line != lines.len()
+            || next_curve != curves.len()
+            || !active_lines_y.is_empty()
+            || !active_curves_y.is_empty())
+    {
+        let lower = y as f32;
+        let upper = (y + 1) as f32;
+        // Add newly active segments
+        for &(ref line, ref bb) in lines[next_line..].iter().take_while(|p| p.1.min.y < upper) {
+            let planes = PlaneSet {
+                start: lower,
+                step: 1.0,
+                count: (bb.max.y.ceil() - lower).max(1.0) as usize,
+            };
+            active_lines_y.push(line.slice_up_y(planes));
+            next_line += 1;
+        }
+        for &(ref curve, ref bb) in curves[next_curve..]
+            .iter()
+            .take_while(|p| p.1.min.y < upper)
+        {
+            let planes = PlaneSet {
+                start: lower,
+                step: 1.0,
+                count: (bb.max.y.ceil() - lower).max(1.0) as usize,
+            };
+            active_curves_y.push(curve.slice_up_y(planes));
+            next_curve += 1;
+        }
+        // get y sliced segments for this scanline
+        scanline_lines.clear();
+        scanline_curves.clear();
+
+        for (k, itr) in active_lines_y.iter_mut().enumerate() {
+            if let Some(itr) = itr.next() {
+                for line in itr {
+                    scanline_lines.push((line, line.x_bounds()))
+                }
+            } else {
+                lines_to_remove.push(k);
+            }
+        }
+        for (k, itr) in active_curves_y.iter_mut().enumerate() {
+            if let Some(itr) = itr.next() {
+                for curve in itr {
+                    scanline_curves.push((curve, curve.x_bounds()))
+                }
+            } else {
+                curves_to_remove.push(k);
+            }
+        }
+        // remove deactivated segments
+        for k in lines_to_remove.drain(..).rev() {
+            active_lines_y.swap_remove(k);
+        }
+        for k in curves_to_remove.drain(..).rev() {
+            active_curves_y.swap_remove(k);
+        }
+        // sort scanline for traversal
+        scanline_lines.sort_by_key(|a| OrderedFloat((a.1).0));
+        scanline_curves.sort_by_key(|a| OrderedFloat((a.1).0));
+        // Iterate through x, slice scanline segments into each cell.
+        // Evaluate, accumulate and output.
+        {
+            let mut next_line = 0;
+            let mut next_curve = 0;
+            let mut x = 0;
+            let mut acc = 0.0;
+            active_lines_x.clear();
+            active_curves_x.clear();
+            while x < width
+                && (next_line != scanline_lines.len()
+                    || next_curve != scanline_curves.len()
+                    || !active_lines_x.is_empty()
+                    || !active_curves_x.is_empty())
+            {
+                let offset = vector(x as f32, y as f32);
+                let lower = x as f32;
+                let upper = (x + 1) as f32;
+                //add newly active segments
+                for &(ref line, (_, ref max)) in scanline_lines[next_line..]
+                    .iter()
+                    .take_while(|p| (p.1).0 < upper)
+                {
+                    let planes = PlaneSet {
+                        start: lower,
+                        step: 1.0,
+                        count: (max.ceil() - lower).max(1.0) as usize,
+                    };
+                    active_lines_x.push(line.slice_up_x(planes));
+                    next_line += 1;
+                }
+                for &(ref curve, (_, ref max)) in scanline_curves[next_curve..]
+                    .iter()
+                    .take_while(|p| (p.1).0 < upper)
+                {
+                    let planes = PlaneSet {
+                        start: lower,
+                        step: 1.0,
+                        count: (max.ceil() - lower).max(1.0) as usize,
+                    };
+                    active_curves_x.push(curve.slice_up_x(planes));
+                    next_curve += 1;
+                }
+                //process x sliced segments for this pixel
+                let mut pixel_value = acc;
+                let mut pixel_acc = 0.0;
+                for (k, itr) in active_lines_x.iter_mut().enumerate() {
+                    if let Some(itr) = itr.next() {
+                        for mut line in itr {
+                            let p = &mut line.p;
+                            p[0] = p[0] - offset;
+                            p[1] = p[1] - offset;
+
+                            let a = p[0].y - p[1].y;
+                            let v = (1.0 - (p[0].x + p[1].x) * 0.5) * a;
+                            pixel_value += v;
+                            pixel_acc += a;
+                        }
+                    } else {
+                        lines_to_remove.push(k);
+                    }
+                }
+                for (k, itr) in active_curves_x.iter_mut().enumerate() {
+                    if let Some(itr) = itr.next() {
+                        for mut curve in itr {
+                            let p = &mut curve.p;
+                            p[0] = p[0] - offset;
+                            p[1] = p[1] - offset;
+                            p[2] = p[2] - offset;
+                            let a = p[0].y - p[2].y;
+                            let b = p[0].y - p[1].y;
+                            let c = p[1].y - p[2].y;
+                            let v = (b * (6.0 - 3.0 * p[0].x - 2.0 * p[1].x - p[2].x)
+                                + c * (6.0 - p[0].x - 2.0 * p[1].x - 3.0 * p[2].x))
+                                / 6.0;
+                            pixel_value += v;
+                            pixel_acc += a;
+                        }
+                    } else {
+                        curves_to_remove.push(k);
+                    }
+                }
+                //output
+                output(x, y, pixel_value.abs());
+                acc += pixel_acc;
+                // remove deactivated segments
+                for k in lines_to_remove.drain(..).rev() {
+                    active_lines_x.swap_remove(k);
+                }
+                for k in curves_to_remove.drain(..).rev() {
+                    active_curves_x.swap_remove(k);
+                }
+                x += 1;
+            }
+            // fill remaining pixels
+            for x in x..width {
+                output(x, y, acc.abs());
+            }
+        }
+        y += 1;
+    }
+    // fill remaining scanlines with 0.0
+    for y in y..height {
+        for x in 0..width {
+            output(x, y, 0.0);
+        }
+    }
+}
diff --git a/rustc_deps/vendor/rusttype/tests/issues.rs b/rustc_deps/vendor/rusttype/tests/issues.rs
new file mode 100644
index 0000000..5adebfe
--- /dev/null
+++ b/rustc_deps/vendor/rusttype/tests/issues.rs
@@ -0,0 +1,34 @@
+extern crate rusttype;
+
+use rusttype::*;
+
+static ROBOTO_REGULAR: &[u8] = include_bytes!("../fonts/Roboto-Regular.ttf");
+
+#[test]
+fn consistent_bounding_box_subpixel_size_proxy() {
+    let font = Font::from_bytes(ROBOTO_REGULAR).unwrap();
+    let height_at_y = |y| {
+        font.glyph('s')
+            .scaled(rusttype::Scale::uniform(20.0))
+            .positioned(rusttype::Point { x: 0.0, y })
+            .pixel_bounding_box()
+            .unwrap()
+            .height()
+    };
+    assert_eq!(height_at_y(50.833_336), height_at_y(110.833_336));
+}
+
+#[test]
+fn consistent_bounding_box_subpixel_size_standalone() {
+    let font = Font::from_bytes(ROBOTO_REGULAR).unwrap();
+    let height_at_y = |y| {
+        font.glyph('s')
+            .standalone()
+            .scaled(rusttype::Scale::uniform(20.0))
+            .positioned(rusttype::Point { x: 0.0, y })
+            .pixel_bounding_box()
+            .unwrap()
+            .height()
+    };
+    assert_eq!(height_at_y(50.833_336), height_at_y(110.833_336));
+}
diff --git a/rustc_deps/vendor/rusttype/tests/lipsum.txt b/rustc_deps/vendor/rusttype/tests/lipsum.txt
new file mode 100644
index 0000000..1763c41
--- /dev/null
+++ b/rustc_deps/vendor/rusttype/tests/lipsum.txt
@@ -0,0 +1,9 @@
+Lorem ipsum dolor sit amet, ferri simul omittantur eam eu, no debet doming dolorem ius. Iriure vocibus est te, natum delicata dignissim pri ea. Purto docendi definitiones no qui. Vel ridens instructior ad, vidisse percipitur et eos. Alienum ocurreret laboramus mei cu, usu ne meliore nostrum, usu tritani luptatum electram ad.
+
+Vis oratio tantas prodesset et, id stet inermis mea, at his copiosae accusata. Mel diam accusata argumentum cu, ut agam consul invidunt est. Ocurreret appellantur deterruisset no vis, his alia postulant inciderint no. Has albucius offendit at. An has noluisse comprehensam, vel veri dicit blandit ea, per paulo noluisse reformidans no. Nec ad sale illum soleat, agam scriptorem ad per.
+
+An cum odio mucius apeirian, labores conceptam ex nec, eruditi habemus qualisque eam an. Eu facilisi maluisset eos, fabulas apeirian ut qui, no atqui blandit vix. Apeirian phaedrum pri ex, vel hinc omnes sapientem et, vim vocibus legendos disputando ne. Et vel semper nominati rationibus, eum lorem causae scripta no.
+
+Ut quo elitr viderer constituam, pro omnesque forensibus at. Timeam scaevola mediocrem ut pri, te pro congue delicatissimi. Mei wisi nostro imperdiet ea, ridens salutatus per no, ut viris partem disputationi sit. Exerci eripuit referrentur vix at, sale mediocrem repudiare per te, modus admodum an eam. No vocent indoctum vis, ne quodsi patrioque vix. Vocent labores omittam et usu.
+
+Democritum signiferumque id nam, enim idque facilis at his. Inermis percipitur scriptorem sea cu, est ne error ludus option. Graecis expetenda contentiones cum et, ius nullam impetus suscipit ex. Modus clita corrumpit mel te, qui at lorem harum, primis cetero habemus sea id. Ei mutat affert dolorum duo, eum dissentias voluptatibus te, libris theophrastus duo id.
diff --git a/rustc_deps/vendor/rusttype/tests/reference_big_biohazard.png b/rustc_deps/vendor/rusttype/tests/reference_big_biohazard.png
new file mode 100644
index 0000000..96ab2e8
--- /dev/null
+++ b/rustc_deps/vendor/rusttype/tests/reference_big_biohazard.png
Binary files differ
diff --git a/rustc_deps/vendor/rusttype/tests/reference_iota.png b/rustc_deps/vendor/rusttype/tests/reference_iota.png
new file mode 100644
index 0000000..4488c68
--- /dev/null
+++ b/rustc_deps/vendor/rusttype/tests/reference_iota.png
Binary files differ
diff --git a/rustc_deps/vendor/rusttype/tests/reference_w.png b/rustc_deps/vendor/rusttype/tests/reference_w.png
new file mode 100644
index 0000000..670740f
--- /dev/null
+++ b/rustc_deps/vendor/rusttype/tests/reference_w.png
Binary files differ
diff --git a/rustc_deps/vendor/rusttype/tests/render_reference.rs b/rustc_deps/vendor/rusttype/tests/render_reference.rs
new file mode 100644
index 0000000..f57ed57
--- /dev/null
+++ b/rustc_deps/vendor/rusttype/tests/render_reference.rs
@@ -0,0 +1,124 @@
+extern crate image;
+extern crate rusttype;
+#[macro_use]
+extern crate lazy_static;
+
+use image::{DynamicImage, LumaA};
+use rusttype::{point, Font, Scale, ScaledGlyph};
+use std::io::Cursor;
+
+lazy_static! {
+    static ref DEJA_VU_MONO: Font<'static> =
+        Font::from_bytes(include_bytes!("../fonts/dejavu/DejaVuSansMono.ttf") as &[u8]).unwrap();
+    static ref OPEN_SANS_ITALIC: Font<'static> =
+        Font::from_bytes(include_bytes!("../fonts/opensans/OpenSans-Italic.ttf") as &[u8]).unwrap();
+}
+
+fn draw_luma_alpha(glyph: ScaledGlyph) -> image::GrayAlphaImage {
+    let glyph = glyph.positioned(point(0.0, 0.0));
+    let bounds = glyph.pixel_bounding_box().unwrap();
+    let mut glyph_image =
+        DynamicImage::new_luma_a8(bounds.width() as _, bounds.height() as _).to_luma_alpha();
+
+    glyph.draw(|x, y, v| {
+        glyph_image.put_pixel(
+            x,
+            y,
+            LumaA {
+                data: [128, (v * 255.0) as u8],
+            },
+        )
+    });
+
+    glyph_image
+}
+
+/// Render a 600px U+2623 character require it to match the reference with
+/// 8-bit accuracy
+#[test]
+fn render_to_reference_big_biohazard() {
+    let new_image = draw_luma_alpha(DEJA_VU_MONO.glyph('☣').scaled(Scale::uniform(600.0)));
+
+    // save the new render for manual inspection
+    new_image.save("target/big_biohazard.png").unwrap();
+
+    let reference = image::load(
+        Cursor::new(include_bytes!("reference_big_biohazard.png") as &[u8]),
+        image::PNG,
+    ).expect("!image::load")
+    .to_luma_alpha();
+
+    assert_eq!(reference.dimensions(), new_image.dimensions());
+
+    for y in 0..reference.height() {
+        for x in 0..reference.width() {
+            assert_eq!(
+                reference.get_pixel(x, y),
+                new_image.get_pixel(x, y),
+                "unexpected alpha difference at ({}, {})",
+                x,
+                y
+            );
+        }
+    }
+}
+
+/// Render a 16px 'w' character require it to match the reference with 8-bit
+/// accuracy
+#[test]
+fn render_to_reference_w() {
+    let new_image = draw_luma_alpha(DEJA_VU_MONO.glyph('w').scaled(Scale::uniform(16.0)));
+
+    // save the new render for manual inspection
+    new_image.save("target/w.png").unwrap();
+
+    let reference = image::load(
+        Cursor::new(include_bytes!("reference_w.png") as &[u8]),
+        image::PNG,
+    ).expect("!image::load")
+    .to_luma_alpha();
+
+    assert_eq!(reference.dimensions(), new_image.dimensions());
+
+    for y in 0..reference.height() {
+        for x in 0..reference.width() {
+            assert_eq!(
+                reference.get_pixel(x, y),
+                new_image.get_pixel(x, y),
+                "unexpected alpha difference at ({}, {})",
+                x,
+                y
+            );
+        }
+    }
+}
+
+/// Render a 60px 'ΐ' character require it to match the reference with 8-bit
+/// accuracy
+#[test]
+fn render_to_reference_iota() {
+    let new_image = draw_luma_alpha(OPEN_SANS_ITALIC.glyph('ΐ').scaled(Scale::uniform(60.0)));
+
+    // save the new render for manual inspection
+    new_image.save("target/iota.png").unwrap();
+
+    let reference = image::load(
+        Cursor::new(include_bytes!("reference_iota.png") as &[u8]),
+        image::PNG,
+    ).expect("!image::load")
+    .to_luma_alpha();
+
+    assert_eq!(reference.dimensions(), new_image.dimensions());
+
+    for y in 0..reference.height() {
+        for x in 0..reference.width() {
+            assert_eq!(
+                reference.get_pixel(x, y),
+                new_image.get_pixel(x, y),
+                "unexpected alpha difference at ({}, {})",
+                x,
+                y
+            );
+        }
+    }
+}
diff --git a/rustc_deps/vendor/stb_truetype/.cargo-checksum.json b/rustc_deps/vendor/stb_truetype/.cargo-checksum.json
new file mode 100644
index 0000000..18f2631
--- /dev/null
+++ b/rustc_deps/vendor/stb_truetype/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"395d9fd7be9c554bf3b342d1ea964201c10b63404df47fe0d58e2b7cb8bc8e95","Cargo.toml":"6107e30495f14cfb09e89acf1f49804bf6863104b7b37d5563eefdbd744a4712","LICENSE-APACHE":"559a84a882160cd5ae5ad559efb15bc613adac9e5346fd047617f48e1bb9fcb4","LICENSE-MIT":"fd198949ebcc78b2d12fc57ebfb2da4ae8f781b7c3b7047aaccc2f804b6f12ef","README.md":"ece578bde0501ca01953e4021aef20870cd642b16967a4667b87d48715025092","benches/api.rs":"93736e6890564ca49358b96e61657b4782e88cae2819ddbc5107d4a1d919de9e","examples/fontnames.rs":"0d4f8e9a5ac17d6996152ccde807b988d924891a3bb93027d6b61fdb1b7927a9","examples/simple.rs":"4be429c753c88a6a83560ebeba2865cdf1c8e7b5cc2bdf57b3c816d4a3af3ee9","rustfmt.toml":"ed17bf27c3712b8f22ec7a2a9d8e5d9d2a5654299754fb93e9ac76ef6d153114","src/lib.rs":"5c7f1403d16ae38d6d80c6ef82218000f35cc4b567d2e69619535b3fb18d7f76","tests/mod.rs":"4f6a741cd2781af7004f7bba2c6a9a81b4fc91b7203ecfbba1a8c2bc8f5ba884"},"package":"48fa7d3136d8645909de1f7c7eb5416cc43057a75ace08fc39ae736bc9da8af1"}
\ No newline at end of file
diff --git a/rustc_deps/vendor/stb_truetype/CHANGELOG.md b/rustc_deps/vendor/stb_truetype/CHANGELOG.md
new file mode 100644
index 0000000..4d382e0
--- /dev/null
+++ b/rustc_deps/vendor/stb_truetype/CHANGELOG.md
@@ -0,0 +1,41 @@
+## master
+
+## 0.2.4
+* Remove all unsafe usage.
+* Fix glyph positioning bug for compound glyphs (#18).
+* Optimise compound glyph shape computation.
+
+## 0.2.3
+* Add `is_collection(&[u8]) -> bool`.
+* Remove most unsafe usages.
+* `VertexType` implements `Eq`.
+* Optimise API performance using new benchmark/regression suite
+
+```
+name                                        control ns/iter  change ns/iter  diff ns/iter   diff %  speedup
+find_glyph_index_deja_vu_mono               1,189            856                     -333  -28.01%   x 1.39
+get_glyph_bitmap_box_subpixel_deja_vu_mono  859              696                     -163  -18.98%   x 1.23
+get_glyph_box_deja_vu_mono                  617              276                     -341  -55.27%   x 2.24
+get_glyph_h_metrics_deja_vu_mono            204              184                      -20   -9.80%   x 1.11
+get_glyph_shape_deja_vu_mono                12,304           12,950                   646    5.25%   x 0.95
+get_v_metrics_deja_vu_mono                  360              100                     -260  -72.22%   x 3.60
+scale_for_pixel_height_deja_vu_mono         145              118                      -27  -18.62%   x 1.23
+```
+
+## 0.2.2
+* Merge a number of bugfixes, update documentation links, add new debugging features.
+
+## 0.2.1
+* Fix `attempt to subtract with overflow` error in get_glyph_kern_advance.
+
+## 0.2
+* `FontInfo` is now generic in the storage for the font data, allowing flexible management of font data lifetimes. This is a breaking change.
+
+## 0.1.2
+* Fix for edge case behaviour for `get_glyph_pair_kern_advance` by switching to `i32` instead of `u32` to match stb_truetype.h (see issue #3).
+
+## 0.1.1
+* Fix for glyf table format 12 and 13 handling to match implementation in stb_truetype.h (see issue #2).
+
+## 0.1
+* Initial release.
diff --git a/rustc_deps/vendor/stb_truetype/Cargo.toml b/rustc_deps/vendor/stb_truetype/Cargo.toml
new file mode 100644
index 0000000..f2b5e21
--- /dev/null
+++ b/rustc_deps/vendor/stb_truetype/Cargo.toml
@@ -0,0 +1,28 @@
+# 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 = "stb_truetype"
+version = "0.2.4"
+authors = ["Dylan Ede <dylanede@googlemail.com>"]
+exclude = ["/fonts/**"]
+description = "A straight translation of the font loading code in stb_truetype.h from C to Rust."
+documentation = "https://docs.rs/stb_truetype-rs"
+readme = "README.md"
+keywords = ["font", "truetype", "opentype", "ttf", "otf"]
+license = "MIT / Apache-2.0"
+repository = "https://gitlab.redox-os.org/redox-os/stb_truetype-rs"
+[dependencies.byteorder]
+version = "1.0"
+[dev-dependencies.approx]
+version = "0.3"
+default-features = false
diff --git a/rustc_deps/vendor/stb_truetype/LICENSE-APACHE b/rustc_deps/vendor/stb_truetype/LICENSE-APACHE
new file mode 100644
index 0000000..23394dd
--- /dev/null
+++ b/rustc_deps/vendor/stb_truetype/LICENSE-APACHE
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "{}"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright 2016 Dylan Ede
+
+   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.
diff --git a/rustc_deps/vendor/stb_truetype/LICENSE-MIT b/rustc_deps/vendor/stb_truetype/LICENSE-MIT
new file mode 100644
index 0000000..93cbd53
--- /dev/null
+++ b/rustc_deps/vendor/stb_truetype/LICENSE-MIT
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Dylan Ede
+
+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.
diff --git a/rustc_deps/vendor/stb_truetype/README.md b/rustc_deps/vendor/stb_truetype/README.md
new file mode 100644
index 0000000..2e2ae04
--- /dev/null
+++ b/rustc_deps/vendor/stb_truetype/README.md
@@ -0,0 +1,34 @@
+# stb_truetype-rs
+
+[![Crates.io](https://img.shields.io/crates/v/stb_truetype.svg)](https://crates.io/crates/stb_truetype)
+[![docs.rs](https://docs.rs/stb_truetype/badge.svg)](https://docs.rs/stb_truetype/)
+
+This is a translation of the font loading code in
+[stb_truetype.h](https://github.com/nothings/stb/blob/master/stb_truetype.h)
+from C to Rust. It is intended as a stopgap dependency for libraries that deal
+with fonts until something better, written in idiomatic Rust, is available. This
+library is not an example of good Rust code, but it works.
+
+Please note that the documentation provided is also a straight copy from the
+original code.
+
+Currently this port does not include the rasterisation or font querying API
+provided by stb_truetype.h. If you are looking for font rasterisation, that is
+provided by [RustType](https://gitlab.redox-os.org/redox-os/rusttype).
+
+## License
+
+Licensed under either of
+
+ * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
+   http://www.apache.org/licenses/LICENSE-2.0)
+ * MIT license ([LICENSE-MIT](LICENSE-MIT) or
+   http://opensource.org/licenses/MIT)
+
+at your option.
+
+### Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
+dual licensed as above, without any additional terms or conditions.
diff --git a/rustc_deps/vendor/stb_truetype/benches/api.rs b/rustc_deps/vendor/stb_truetype/benches/api.rs
new file mode 100644
index 0000000..3f9e176
--- /dev/null
+++ b/rustc_deps/vendor/stb_truetype/benches/api.rs
@@ -0,0 +1,507 @@
+#![feature(test)]
+extern crate stb_truetype;
+extern crate test;
+#[macro_use]
+extern crate approx;
+
+use stb_truetype::*;
+
+/// index map format 12
+static DEJA_VU_MONO: &[u8] = include_bytes!("../fonts/DejaVuSansMono.ttf");
+static ROBOTO: &[u8] = include_bytes!("../fonts/Roboto-Regular.ttf");
+/// index map format 4
+static GUDEA: &[u8] = include_bytes!("../fonts/Gudea-Regular.ttf");
+
+const ALPHABET_SIZE: usize = 62;
+const ALPHABET: &[char; ALPHABET_SIZE] = &[
+    'A', 'a', 'B', 'b', 'C', 'c', 'D', 'd', 'E', 'e', 'F', 'f', 'G', 'g', 'H', 'h', 'I', 'i', 'J',
+    'j', 'K', 'k', 'L', 'l', 'M', 'm', 'N', 'n', 'O', 'o', 'P', 'p', 'Q', 'q', 'R', 'r', 'S', 's',
+    'T', 't', 'U', 'u', 'V', 'v', 'W', 'w', 'X', 'x', 'W', 'w', 'Z', 'z', '0', '1', '2', '3', '4',
+    '5', '6', '7', '8', '9',
+];
+
+#[bench]
+fn find_glyph_index_deja_vu_mono(b: &mut test::Bencher) {
+    let font = FontInfo::new(&*DEJA_VU_MONO, 0).unwrap();
+
+    let mut indices = [0_u32; ALPHABET_SIZE];
+    b.iter(|| {
+        for (i, c) in ALPHABET.iter().enumerate() {
+            indices[i] = font.find_glyph_index(*c as u32);
+        }
+    });
+
+    assert_eq!(
+        indices.to_vec(),
+        vec![
+            36, 68, 37, 69, 38, 70, 39, 71, 40, 72, 41, 73, 42, 74, 43, 75, 44, 76, 45, 77, 46, 78,
+            47, 79, 48, 80, 49, 81, 50, 82, 51, 83, 52, 84, 53, 85, 54, 86, 55, 87, 56, 88, 57, 89,
+            58, 90, 59, 91, 58, 90, 61, 93, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28
+        ]
+    );
+}
+
+#[bench]
+fn find_glyph_index_gudea(b: &mut test::Bencher) {
+    let font = FontInfo::new(&*GUDEA, 0).unwrap();
+
+    let mut indices = [0_u32; ALPHABET_SIZE];
+    b.iter(|| {
+        for (i, c) in ALPHABET.iter().enumerate() {
+            indices[i] = font.find_glyph_index(*c as u32);
+        }
+    });
+
+    assert_eq!(
+        indices.to_vec(),
+        vec![
+            37, 69, 38, 70, 39, 71, 40, 72, 41, 73, 42, 74, 43, 75, 44, 76, 45, 77, 46, 78, 47, 79,
+            48, 80, 49, 81, 50, 82, 51, 83, 52, 84, 53, 85, 54, 86, 55, 87, 56, 88, 57, 89, 58, 90,
+            59, 91, 60, 92, 59, 91, 62, 94, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29
+        ]
+    );
+}
+
+/// (x0, x1, y0, y1)
+fn rect_to_tuple<T>(r: Rect<T>) -> (T, T, T, T) {
+    (r.x0, r.x1, r.y0, r.y1)
+}
+
+#[bench]
+fn get_glyph_box_deja_vu_mono(b: &mut test::Bencher) {
+    let font = FontInfo::new(&*DEJA_VU_MONO, 0).unwrap();
+
+    let indices: Vec<_> = ALPHABET
+        .iter()
+        .map(|c| font.find_glyph_index(*c as u32))
+        .collect();
+
+    let mut boxes = [None; ALPHABET_SIZE];
+    b.iter(|| {
+        for (i, glyph_index) in indices.iter().enumerate() {
+            boxes[i] = font.get_glyph_box(*glyph_index);
+        }
+    });
+
+    assert_eq!(rect_to_tuple(boxes[11].unwrap()), (195, 1063, 0, 1556));
+    assert_eq!(rect_to_tuple(boxes[34].unwrap()), (143, 1233, 0, 1493));
+    assert_eq!(rect_to_tuple(boxes[57].unwrap()), (143, 1069, -29, 1493));
+}
+
+#[bench]
+fn get_glyph_box_gudea(b: &mut test::Bencher) {
+    let font = FontInfo::new(&*GUDEA, 0).unwrap();
+
+    let indices: Vec<_> = ALPHABET
+        .iter()
+        .map(|c| font.find_glyph_index(*c as u32))
+        .collect();
+
+    let mut boxes = [None; ALPHABET_SIZE];
+    b.iter(|| {
+        for (i, glyph_index) in indices.iter().enumerate() {
+            boxes[i] = font.get_glyph_box(*glyph_index);
+        }
+    });
+
+    assert_eq!(rect_to_tuple(boxes[11].unwrap()), (35, 316, 0, 710));
+    assert_eq!(rect_to_tuple(boxes[34].unwrap()), (91, 571, 1, 701));
+    assert_eq!(rect_to_tuple(boxes[57].unwrap()), (63, 504, -6, 700));
+}
+
+#[bench]
+fn get_glyph_bitmap_box_subpixel_deja_vu_mono(b: &mut test::Bencher) {
+    let font = FontInfo::new(&*DEJA_VU_MONO, 0).unwrap();
+
+    let indices: Vec<_> = ALPHABET
+        .iter()
+        .map(|c| font.find_glyph_index(*c as u32))
+        .collect();
+
+    let (s_x, s_y) = (12.0, 14.5);
+    let scale_y = font.scale_for_pixel_height(s_y);
+    let scale_x = scale_y * s_x / s_y;
+
+    let mut boxes = [None; ALPHABET_SIZE];
+    b.iter(|| {
+        for (i, glyph_index) in indices.iter().enumerate() {
+            boxes[i] =
+                font.get_glyph_bitmap_box_subpixel(*glyph_index, scale_x, scale_y, 656.0, 1034.0);
+        }
+    });
+
+    assert_eq!(rect_to_tuple(boxes[11].unwrap()), (656, 662, 1024, 1034));
+    assert_eq!(rect_to_tuple(boxes[34].unwrap()), (656, 663, 1024, 1034));
+    assert_eq!(rect_to_tuple(boxes[57].unwrap()), (656, 662, 1024, 1035));
+}
+
+#[bench]
+fn get_glyph_bitmap_box_subpixel_gudea(b: &mut test::Bencher) {
+    let font = FontInfo::new(&*GUDEA, 0).unwrap();
+
+    let indices: Vec<_> = ALPHABET
+        .iter()
+        .map(|c| font.find_glyph_index(*c as u32))
+        .collect();
+
+    let (s_x, s_y) = (12.0, 14.5);
+    let scale_y = font.scale_for_pixel_height(s_y);
+    let scale_x = scale_y * s_x / s_y;
+
+    let mut boxes = [None; ALPHABET_SIZE];
+    b.iter(|| {
+        for (i, glyph_index) in indices.iter().enumerate() {
+            boxes[i] =
+                font.get_glyph_bitmap_box_subpixel(*glyph_index, scale_x, scale_y, 656.0, 1034.0);
+        }
+    });
+
+    assert_eq!(rect_to_tuple(boxes[11].unwrap()), (656, 660, 1025, 1034));
+    assert_eq!(rect_to_tuple(boxes[34].unwrap()), (656, 662, 1025, 1034));
+    assert_eq!(rect_to_tuple(boxes[57].unwrap()), (656, 661, 1025, 1035));
+}
+
+/// (x, y, cx, cy, type)
+fn vertex_to_tuple(vert: Vertex) -> (i16, i16, i16, i16, u8) {
+    (vert.x, vert.y, vert.cx, vert.cy, vert.vertex_type() as u8)
+}
+
+#[bench]
+fn get_glyph_shape_deja_vu_mono(b: &mut test::Bencher) {
+    let font = FontInfo::new(&*DEJA_VU_MONO, 0).unwrap();
+
+    let indices: Vec<_> = ALPHABET
+        .iter()
+        .map(|c| font.find_glyph_index(*c as u32))
+        .collect();
+
+    let mut shapes = vec![None; ALPHABET_SIZE];
+    b.iter(|| {
+        for (i, glyph_index) in indices.iter().enumerate() {
+            shapes[i] = font.get_glyph_shape(*glyph_index);
+        }
+    });
+
+    let shapes_11: Vec<_> = shapes[11]
+        .as_ref()
+        .unwrap()
+        .iter()
+        .map(|v| vertex_to_tuple(*v))
+        .collect();
+    assert_eq!(
+        shapes_11,
+        vec![
+            (1063, 1556, 0, 0, 1),
+            (1063, 1403, 0, 0, 2),
+            (854, 1403, 0, 0, 2),
+            (716, 1362, 755, 1403, 3),
+            (678, 1219, 678, 1322, 3),
+            (678, 1120, 0, 0, 2),
+            (1063, 1120, 0, 0, 2),
+            (1063, 977, 0, 0, 2),
+            (678, 977, 0, 0, 2),
+            (678, 0, 0, 0, 2),
+            (494, 0, 0, 0, 2),
+            (494, 977, 0, 0, 2),
+            (195, 977, 0, 0, 2),
+            (195, 1120, 0, 0, 2),
+            (494, 1120, 0, 0, 2),
+            (494, 1198, 0, 0, 2),
+            (578, 1469, 494, 1382, 3),
+            (842, 1556, 663, 1556, 3),
+            (1063, 1556, 0, 0, 2)
+        ]
+    );
+
+    let shapes_47: Vec<_> = shapes[47]
+        .as_ref()
+        .unwrap()
+        .iter()
+        .map(|v| vertex_to_tuple(*v))
+        .collect();
+    assert_eq!(
+        shapes_47,
+        vec![
+            (1118, 1120, 0, 0, 1),
+            (717, 584, 0, 0, 2),
+            (1157, 0, 0, 0, 2),
+            (944, 0, 0, 0, 2),
+            (616, 449, 0, 0, 2),
+            (289, 0, 0, 0, 2),
+            (76, 0, 0, 0, 2),
+            (516, 584, 0, 0, 2),
+            (115, 1120, 0, 0, 2),
+            (319, 1120, 0, 0, 2),
+            (616, 715, 0, 0, 2),
+            (911, 1120, 0, 0, 2),
+            (1118, 1120, 0, 0, 2)
+        ]
+    );
+}
+
+#[bench]
+fn get_glyph_shape_gudea(b: &mut test::Bencher) {
+    let font = FontInfo::new(&*GUDEA, 0).unwrap();
+
+    let indices: Vec<_> = ALPHABET
+        .iter()
+        .map(|c| font.find_glyph_index(*c as u32))
+        .collect();
+
+    let mut shapes = vec![None; ALPHABET_SIZE];
+    b.iter(|| {
+        for (i, glyph_index) in indices.iter().enumerate() {
+            shapes[i] = font.get_glyph_shape(*glyph_index);
+        }
+    });
+
+    let shapes_11: Vec<_> = shapes[11]
+        .as_ref()
+        .unwrap()
+        .iter()
+        .map(|v| vertex_to_tuple(*v))
+        .collect();
+    assert_eq!(
+        shapes_11,
+        vec![
+            (113, 500, 0, 0, 1),
+            (113, 596, 0, 0, 2),
+            (150, 683, 113, 657, 3),
+            (231, 710, 188, 710, 3),
+            (316, 697, 275, 710, 3),
+            (305, 643, 0, 0, 2),
+            (256, 649, 272, 649, 3),
+            (187, 582, 187, 649, 3),
+            (187, 500, 0, 0, 2),
+            (289, 500, 0, 0, 2),
+            (289, 440, 0, 0, 2),
+            (187, 440, 0, 0, 2),
+            (187, 0, 0, 0, 2),
+            (112, 0, 0, 0, 2),
+            (112, 440, 0, 0, 2),
+            (35, 440, 0, 0, 2),
+            (35, 500, 0, 0, 2),
+            (113, 500, 0, 0, 2)
+        ]
+    );
+
+    let shapes_47: Vec<_> = shapes[47]
+        .as_ref()
+        .unwrap()
+        .iter()
+        .map(|v| vertex_to_tuple(*v))
+        .collect();
+    assert_eq!(
+        shapes_47,
+        vec![
+            (113, 501, 0, 0, 1),
+            (218, 324, 0, 0, 2),
+            (323, 501, 0, 0, 2),
+            (406, 501, 0, 0, 2),
+            (259, 255, 0, 0, 2),
+            (412, 0, 0, 0, 2),
+            (329, 0, 0, 0, 2),
+            (218, 198, 0, 0, 2),
+            (107, 0, 0, 0, 2),
+            (24, 0, 0, 0, 2),
+            (177, 255, 0, 0, 2),
+            (30, 501, 0, 0, 2),
+            (113, 501, 0, 0, 2)
+        ]
+    );
+}
+
+#[bench]
+fn get_glyph_shape_compound_glyph_roboto_colon(b: &mut test::Bencher) {
+    let font = FontInfo::new(&*ROBOTO, 0).unwrap();
+
+    let colon_index = font.find_glyph_index(':' as u32);
+
+    let mut shape = None;
+    b.iter(|| {
+        shape = font.get_glyph_shape(colon_index);
+    });
+
+    let shape: Vec<_> = shape.unwrap().iter().map(|v| vertex_to_tuple(*v)).collect();
+
+    assert_eq!(
+        shape,
+        vec![
+            (134, 97, -10, 0, 1),
+            (162, 177, 134, 145, 3),
+            (248, 209, 191, 209, 3),
+            (334, 177, 305, 209, 3),
+            (364, 97, 364, 145, 3),
+            (334, 20, 364, 51, 3),
+            (248, -11, 305, -11, 3),
+            (162, 20, 191, -11, 3),
+            (134, 97, 134, 51, 3),
+            (135, 980, -9, 883, 1),
+            (163, 1060, 135, 1028, 3),
+            (249, 1092, 192, 1092, 3),
+            (335, 1060, 306, 1092, 3),
+            (365, 980, 365, 1028, 3),
+            (335, 903, 365, 934, 3),
+            (249, 872, 306, 872, 3),
+            (163, 903, 192, 872, 3),
+            (135, 980, 135, 934, 3)
+        ]
+    );
+}
+
+/// (advance_width, left_side_bearing)
+fn h_metrics_to_tuple(h: HMetrics) -> (i32, i32) {
+    (h.advance_width, h.left_side_bearing)
+}
+
+#[bench]
+fn get_glyph_h_metrics_deja_vu_mono(b: &mut test::Bencher) {
+    let font = FontInfo::new(&*DEJA_VU_MONO, 0).unwrap();
+
+    let indices: Vec<_> = ALPHABET
+        .iter()
+        .map(|c| font.find_glyph_index(*c as u32))
+        .collect();
+
+    let mut h_metrics = [HMetrics {
+        advance_width: 0,
+        left_side_bearing: 0,
+    }; ALPHABET_SIZE];
+    b.iter(|| {
+        for (i, glyph_index) in indices.iter().enumerate() {
+            h_metrics[i] = font.get_glyph_h_metrics(*glyph_index);
+        }
+    });
+
+    assert_eq!(h_metrics_to_tuple(h_metrics[11]), (1233, 195));
+    assert_eq!(h_metrics_to_tuple(h_metrics[25]), (1233, 109));
+    assert_eq!(h_metrics_to_tuple(h_metrics[49]), (1233, 0));
+}
+
+#[bench]
+fn get_glyph_h_metrics_gudea(b: &mut test::Bencher) {
+    let font = FontInfo::new(&*GUDEA, 0).unwrap();
+
+    let indices: Vec<_> = ALPHABET
+        .iter()
+        .map(|c| font.find_glyph_index(*c as u32))
+        .collect();
+
+    let mut h_metrics = [HMetrics {
+        advance_width: 0,
+        left_side_bearing: 0,
+    }; ALPHABET_SIZE];
+    b.iter(|| {
+        for (i, glyph_index) in indices.iter().enumerate() {
+            h_metrics[i] = font.get_glyph_h_metrics(*glyph_index);
+        }
+    });
+
+    assert_eq!(h_metrics_to_tuple(h_metrics[11]), (291, 35));
+    assert_eq!(h_metrics_to_tuple(h_metrics[25]), (850, 91));
+    assert_eq!(h_metrics_to_tuple(h_metrics[49]), (679, 11));
+}
+
+#[bench]
+fn scale_for_pixel_height_deja_vu_mono(b: &mut test::Bencher) {
+    let font = FontInfo::new(&*DEJA_VU_MONO, 0).unwrap();
+
+    let pixel_heights: [f32; 8] = [1.0, 12.0, 14.5, 25.5, 50.0, 112.2, 500.5, 657.5];
+
+    let mut scales = [0.0; 8];
+    b.iter(|| {
+        // repeat so its a similar number of calls to the other benchmarks
+        for _ in 0..test::black_box(8) {
+            for (i, pixel_height) in pixel_heights.iter().enumerate() {
+                scales[i] = font.scale_for_pixel_height(*pixel_height);
+            }
+        }
+    });
+
+    assert_relative_eq!(scales[0], 0.000_419_463_1);
+    assert_relative_eq!(scales[1], 0.005_033_557);
+    assert_relative_eq!(scales[2], 0.006_082_215);
+    assert_relative_eq!(scales[3], 0.010_696_309);
+    assert_relative_eq!(scales[4], 0.020_973_155);
+    assert_relative_eq!(scales[5], 0.047_063_757);
+    assert_relative_eq!(scales[6], 0.209_941_27);
+    assert_relative_eq!(scales[7], 0.275_796_98);
+}
+
+#[bench]
+fn scale_for_pixel_height_gudea(b: &mut test::Bencher) {
+    let font = FontInfo::new(&*GUDEA, 0).unwrap();
+
+    let pixel_heights: [f32; 8] = [1.0, 12.0, 14.5, 25.5, 50.0, 112.2, 500.5, 657.5];
+
+    let mut scales = [0.0; 8];
+    b.iter(|| {
+        // repeat so its a similar number of calls to the other benchmarks
+        for _ in 0..test::black_box(8) {
+            for (i, pixel_height) in pixel_heights.iter().enumerate() {
+                scales[i] = font.scale_for_pixel_height(*pixel_height);
+            }
+        }
+    });
+
+    assert_relative_eq!(scales[0], 0.000_809_061_5);
+    assert_relative_eq!(scales[1], 0.009_708_738);
+    assert_relative_eq!(scales[2], 0.011_731_392);
+    assert_relative_eq!(scales[3], 0.020_631_067);
+    assert_relative_eq!(scales[4], 0.040_453_073);
+    assert_relative_eq!(scales[5], 0.090_776_7);
+    assert_relative_eq!(scales[6], 0.404_935_27);
+    assert_relative_eq!(scales[7], 0.531_957_9);
+}
+
+#[bench]
+fn get_v_metrics_deja_vu_mono(b: &mut test::Bencher) {
+    let font = FontInfo::new(&*DEJA_VU_MONO, 0).unwrap();
+
+    let mut v_metrics = VMetrics {
+        ascent: 1,
+        descent: 2,
+        line_gap: 3,
+    };
+    b.iter(|| {
+        // repeat so its a similar number of calls to the other benchmarks
+        for _ in 0..test::black_box(ALPHABET_SIZE) {
+            v_metrics = font.get_v_metrics();
+        }
+    });
+
+    let VMetrics {
+        ascent,
+        descent,
+        line_gap,
+    } = v_metrics;
+    assert_eq!(ascent, 1901);
+    assert_eq!(descent, -483);
+    assert_eq!(line_gap, 0);
+}
+
+#[bench]
+fn get_v_metrics_gudea(b: &mut test::Bencher) {
+    let font = FontInfo::new(&*GUDEA, 0).unwrap();
+
+    let mut v_metrics = VMetrics {
+        ascent: 1,
+        descent: 2,
+        line_gap: 3,
+    };
+    b.iter(|| {
+        // repeat so its a similar number of calls to the other benchmarks
+        for _ in 0..test::black_box(ALPHABET_SIZE) {
+            v_metrics = font.get_v_metrics();
+        }
+    });
+
+    let VMetrics {
+        ascent,
+        descent,
+        line_gap,
+    } = v_metrics;
+    assert_eq!(ascent, 972);
+    assert_eq!(descent, -264);
+    assert_eq!(line_gap, 0);
+}
diff --git a/rustc_deps/vendor/stb_truetype/examples/fontnames.rs b/rustc_deps/vendor/stb_truetype/examples/fontnames.rs
new file mode 100644
index 0000000..f93564c
--- /dev/null
+++ b/rustc_deps/vendor/stb_truetype/examples/fontnames.rs
@@ -0,0 +1,51 @@
+#![allow(unknown_lints)]
+
+extern crate stb_truetype;
+
+use stb_truetype::FontInfo;
+use std::borrow::Cow;
+
+#[allow(cast_ptr_alignment)] // FIXME seems a bit dodgy
+fn main() {
+    let file = &include_bytes!("../fonts/Gudea-Regular.ttf")[..];
+    let font = FontInfo::new(Cow::Borrowed(file), 0).unwrap();
+
+    for info in font.get_font_name_strings() {
+        let (name, pl_en_la, na) = info;
+        let name = (match pl_en_la {
+            Some(stb_truetype::PlatformEncodingLanguageId::Mac(
+                Some(Ok(stb_truetype::MacEid::Roman)),
+                _,
+            )) => ::std::str::from_utf8(name).ok().map(Cow::Borrowed),
+            Some(stb_truetype::PlatformEncodingLanguageId::Microsoft(
+                Some(Ok(stb_truetype::MicrosoftEid::UnicodeBMP)),
+                _,
+            )) => {
+                let name16be = unsafe {
+                    ::std::slice::from_raw_parts(name.as_ptr() as *const u16, name.len() / 2)
+                };
+                let name16 = name16be
+                    .iter()
+                    .map(|&v| u16::from_be(v))
+                    .collect::<Vec<_>>();
+                String::from_utf16(&name16).ok().map(Cow::Owned)
+            }
+            Some(stb_truetype::PlatformEncodingLanguageId::Microsoft(
+                Some(Ok(stb_truetype::MicrosoftEid::UnicodeFull)),
+                _,
+            )) => {
+                let name16be = unsafe {
+                    ::std::slice::from_raw_parts(name.as_ptr() as *const u16, name.len() / 2)
+                };
+                let name16 = name16be
+                    .iter()
+                    .map(|&v| u16::from_be(v))
+                    .collect::<Vec<_>>();
+                String::from_utf16(&name16).ok().map(Cow::Owned)
+            }
+            Some(_) => Some(Cow::Borrowed("(Unknown encoding)")),
+            None => Some(Cow::Borrowed("(Unknown Platform ID)")),
+        }).unwrap_or(Cow::Borrowed("(Encoding error)"));
+        println!("{:?}, {:?}, {:?}", name, pl_en_la, na);
+    }
+}
diff --git a/rustc_deps/vendor/stb_truetype/examples/simple.rs b/rustc_deps/vendor/stb_truetype/examples/simple.rs
new file mode 100644
index 0000000..f5e849d
--- /dev/null
+++ b/rustc_deps/vendor/stb_truetype/examples/simple.rs
@@ -0,0 +1,24 @@
+extern crate stb_truetype;
+
+use stb_truetype::FontInfo;
+use std::borrow::Cow;
+fn main() {
+    let file = include_bytes!("../fonts/Gudea-Regular.ttf") as &[u8];
+    let font = FontInfo::new(Cow::Borrowed(file), 0).unwrap();
+    let vmetrics = font.get_v_metrics();
+    println!("{:?}", vmetrics);
+    let c = '\\';
+    let cp = c as u32;
+    let g = font.find_glyph_index(cp);
+    println!("{:?} -> {:?}", cp, g);
+    let r = font.get_glyph_box(g);
+    println!("{:?}", r);
+    let shape = font.get_glyph_shape(g);
+    println!("{:#?}", shape);
+    let hmetrics = font.get_glyph_h_metrics(g);
+    println!("{:?}", hmetrics);
+    let advance = font.get_codepoint_kern_advance('f' as u32, 'f' as u32);
+    println!("{:?}", advance);
+    let scale = font.scale_for_pixel_height(20.0);
+    println!("{:?}", scale);
+}
diff --git a/rustc_deps/vendor/stb_truetype/rustfmt.toml b/rustc_deps/vendor/stb_truetype/rustfmt.toml
new file mode 100644
index 0000000..e2447e3
--- /dev/null
+++ b/rustc_deps/vendor/stb_truetype/rustfmt.toml
@@ -0,0 +1,5 @@
+# rustfmt 0.3.x-nightly
+wrap_comments = true
+error_on_line_overflow = false
+use_field_init_shorthand = true
+condense_wildcard_suffixes = true
diff --git a/rustc_deps/vendor/stb_truetype/src/lib.rs b/rustc_deps/vendor/stb_truetype/src/lib.rs
new file mode 100644
index 0000000..384ef78
--- /dev/null
+++ b/rustc_deps/vendor/stb_truetype/src/lib.rs
@@ -0,0 +1,1284 @@
+#![allow(unknown_lints)]
+#![warn(clippy)]
+#![allow(too_many_arguments, cast_lossless, many_single_char_names,)]
+
+extern crate byteorder;
+
+use byteorder::{BigEndian as BE, ByteOrder};
+use std::ops::Deref;
+
+#[derive(Clone, Debug)]
+pub struct FontInfo<Data: Deref<Target = [u8]>> {
+    data: Data, // pointer to .ttf file
+    // fontstart: usize,       // offset of start of font
+    num_glyphs: u32, // number of glyphs, needed for range checking
+    loca: u32,
+    head: u32,
+    glyf: u32,
+    hhea: u32,
+    hmtx: u32,
+    name: u32,
+    kern: u32,                // table locations as offset from start of .ttf
+    index_map: u32,           // a cmap mapping for our chosen character encoding
+    index_to_loc_format: u32, // format needed to map from glyph index to glyph
+}
+
+#[derive(Copy, Clone, Debug)]
+#[repr(C)]
+pub struct Vertex {
+    pub x: i16,
+    pub y: i16,
+    pub cx: i16,
+    pub cy: i16,
+    type_: u8,
+}
+
+impl Vertex {
+    pub fn vertex_type(&self) -> VertexType {
+        match self.type_ {
+            1 => VertexType::MoveTo,
+            2 => VertexType::LineTo,
+            3 => VertexType::CurveTo,
+            type_ => panic!("Invalid vertex type: {}", type_),
+        }
+    }
+}
+
+#[test]
+fn test_vertex_type() {
+    fn v(type_: VertexType) -> Vertex {
+        Vertex {
+            x: 0,
+            y: 0,
+            cx: 0,
+            cy: 0,
+            type_: type_ as u8,
+        }
+    }
+    assert_eq!(v(VertexType::MoveTo).vertex_type(), VertexType::MoveTo);
+    assert_eq!(v(VertexType::LineTo).vertex_type(), VertexType::LineTo);
+    assert_eq!(v(VertexType::CurveTo).vertex_type(), VertexType::CurveTo);
+}
+
+#[test]
+#[should_panic]
+fn test_invalid_vertex_type() {
+    let v = Vertex {
+        x: 0,
+        y: 0,
+        cx: 0,
+        cy: 0,
+        type_: 255,
+    };
+    let s = match v.vertex_type() {
+        VertexType::MoveTo => "move to",
+        VertexType::LineTo => "line to",
+        VertexType::CurveTo => "curve to",
+    };
+    // With `Vertex::vertex_type` defined as `transmute` this would be undefined
+    // behavior:
+    println!("{}", s);
+}
+
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+#[repr(u8)]
+pub enum VertexType {
+    MoveTo = 1,
+    LineTo = 2,
+    CurveTo = 3,
+}
+
+#[derive(Copy, Clone, Debug)]
+pub struct Rect<T> {
+    pub x0: T,
+    pub y0: T,
+    pub x1: T,
+    pub y1: T,
+}
+
+#[derive(Copy, Clone, Debug)]
+pub struct HMetrics {
+    pub advance_width: i32,
+    pub left_side_bearing: i32,
+}
+
+#[derive(Copy, Clone, Debug)]
+pub struct VMetrics {
+    pub ascent: i32,
+    pub descent: i32,
+    pub line_gap: i32,
+}
+
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[repr(C)]
+pub enum PlatformId {
+    // platformID
+    Unicode = 0,
+    Mac = 1,
+    Iso = 2,
+    Microsoft = 3,
+}
+fn platform_id(v: u16) -> Option<PlatformId> {
+    use PlatformId::*;
+    match v {
+        0 => Some(Unicode),
+        1 => Some(Mac),
+        2 => Some(Iso),
+        3 => Some(Microsoft),
+        _ => None,
+    }
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[repr(C)]
+#[allow(non_camel_case_types)]
+pub enum UnicodeEid {
+    // encodingID for PLATFORM_ID_UNICODE
+    Unicode_1_0 = 0,
+    Unicode_1_1 = 1,
+    Iso_10646 = 2,
+    Unicode_2_0_Bmp = 3,
+    Unicode_2_0_Full = 4,
+}
+fn unicode_eid(v: u16) -> Option<UnicodeEid> {
+    use UnicodeEid::*;
+    match v {
+        0 => Some(Unicode_1_0),
+        1 => Some(Unicode_1_1),
+        2 => Some(Iso_10646),
+        3 => Some(Unicode_2_0_Bmp),
+        4 => Some(Unicode_2_0_Full),
+        _ => None,
+    }
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[repr(C)]
+pub enum MicrosoftEid {
+    // encodingID for PLATFORM_ID_MICROSOFT
+    Symbol = 0,
+    UnicodeBMP = 1,
+    Shiftjis = 2,
+    UnicodeFull = 10,
+}
+fn microsoft_eid(v: u16) -> Option<MicrosoftEid> {
+    use MicrosoftEid::*;
+    match v {
+        0 => Some(Symbol),
+        1 => Some(UnicodeBMP),
+        2 => Some(Shiftjis),
+        10 => Some(UnicodeFull),
+        _ => None,
+    }
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[repr(C)]
+pub enum MacEid {
+    // encodingID for PLATFORM_ID_MAC; same as Script Manager codes
+    Roman = 0,
+    Arabic = 4,
+    Japanese = 1,
+    Hebrew = 5,
+    ChineseTrad = 2,
+    Greek = 6,
+    Korean = 3,
+    Russian = 7,
+}
+fn mac_eid(v: u16) -> Option<MacEid> {
+    use MacEid::*;
+    match v {
+        0 => Some(Roman),
+        1 => Some(Japanese),
+        2 => Some(ChineseTrad),
+        3 => Some(Korean),
+        4 => Some(Arabic),
+        5 => Some(Hebrew),
+        6 => Some(Greek),
+        7 => Some(Russian),
+        _ => None,
+    }
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[repr(C)]
+pub enum MicrosoftLang {
+    // languageID for PLATFORM_ID_MICROSOFT; same as LCID...
+    // problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs
+    English = 0x0409,
+    Italian = 0x0410,
+    Chinese = 0x0804,
+    Japanese = 0x0411,
+    Dutch = 0x0413,
+    Korean = 0x0412,
+    French = 0x040c,
+    Russian = 0x0419,
+    German = 0x0407,
+    // Spanish = 0x0409,
+    Hebrew = 0x040d,
+    Swedish = 0x041D,
+}
+fn microsoft_lang(v: u16) -> Option<MicrosoftLang> {
+    use MicrosoftLang::*;
+    match v {
+        0x0409 => Some(English),
+        0x0804 => Some(Chinese),
+        0x0413 => Some(Dutch),
+        0x040c => Some(French),
+        0x0407 => Some(German),
+        0x040d => Some(Hebrew),
+        0x0410 => Some(Italian),
+        0x0411 => Some(Japanese),
+        0x0412 => Some(Korean),
+        0x0419 => Some(Russian),
+        0x041D => Some(Swedish),
+        _ => None,
+    }
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[repr(C)]
+pub enum MacLang {
+    // languageID for PLATFORM_ID_MAC
+    English = 0,
+    Japanese = 11,
+    Arabic = 12,
+    Korean = 23,
+    Dutch = 4,
+    Russian = 32,
+    French = 1,
+    Spanish = 6,
+    German = 2,
+    Swedish = 5,
+    Hebrew = 10,
+    ChineseSimplified = 33,
+    Italian = 3,
+    ChineseTrad = 19,
+}
+fn mac_lang(v: u16) -> Option<MacLang> {
+    use MacLang::*;
+    match v {
+        0 => Some(English),
+        12 => Some(Arabic),
+        4 => Some(Dutch),
+        1 => Some(French),
+        2 => Some(German),
+        10 => Some(Hebrew),
+        3 => Some(Italian),
+        11 => Some(Japanese),
+        23 => Some(Korean),
+        32 => Some(Russian),
+        6 => Some(Spanish),
+        5 => Some(Swedish),
+        33 => Some(ChineseSimplified),
+        19 => Some(ChineseTrad),
+        _ => None,
+    }
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub enum PlatformEncodingLanguageId {
+    Unicode(Option<Result<UnicodeEid, u16>>, Option<u16>),
+    Mac(Option<Result<MacEid, u16>>, Option<Result<MacLang, u16>>),
+    Iso(Option<u16>, Option<u16>),
+    Microsoft(
+        Option<Result<MicrosoftEid, u16>>,
+        Option<Result<MicrosoftLang, u16>>,
+    ),
+}
+fn platform_encoding_id(
+    platform_id: PlatformId,
+    encoding_id: Option<u16>,
+    language_id: Option<u16>,
+) -> PlatformEncodingLanguageId {
+    match platform_id {
+        PlatformId::Unicode => PlatformEncodingLanguageId::Unicode(
+            encoding_id.map(|id| unicode_eid(id).ok_or(id)),
+            language_id,
+        ),
+        PlatformId::Mac => PlatformEncodingLanguageId::Mac(
+            encoding_id.map(|id| mac_eid(id).ok_or(id)),
+            language_id.map(|id| mac_lang(id).ok_or(id)),
+        ),
+        PlatformId::Iso => PlatformEncodingLanguageId::Iso(encoding_id, language_id),
+        PlatformId::Microsoft => PlatformEncodingLanguageId::Microsoft(
+            encoding_id.map(|id| microsoft_eid(id).ok_or(id)),
+            language_id.map(|id| microsoft_lang(id).ok_or(id)),
+        ),
+    }
+}
+
+// # accessors to parse data from file
+
+// on platforms that don't allow misaligned reads, if we want to allow
+// truetype fonts that aren't padded to alignment, define
+// ALLOW_UNALIGNED_TRUETYPE
+
+/// Return `true` if `data` holds a font stored in a format this crate
+/// recognizes, according to its signature in the initial bytes.
+pub fn is_font(data: &[u8]) -> bool {
+    if data.len() >= 4 {
+        let tag = &data[0..4];
+        tag == [b'1', 0, 0, 0] || tag == b"typ1" || tag == b"OTTO" || tag == [0, 1, 0, 0]
+    } else {
+        false
+    }
+}
+
+/// Return `true` if `data` holds a TrueType Collection, according to its
+/// signature in the initial bytes. A TrueType Collection stores several fonts
+/// in a single file, allowing them to share data for glyphs they have in
+/// common.
+pub fn is_collection(data: &[u8]) -> bool {
+    data.len() >= 4 && &data[0..4] == b"ttcf"
+}
+
+fn find_table(data: &[u8], fontstart: usize, tag: &[u8]) -> u32 {
+    let num_tables = BE::read_u16(&data[fontstart + 4..]);
+    let tabledir = fontstart + 12;
+    for i in 0..num_tables {
+        let loc = tabledir + 16 * (i as usize);
+        if &data[loc..loc + 4] == tag {
+            return BE::read_u32(&data[loc + 8..]);
+        }
+    }
+    0
+}
+
+/// Each .ttf/.ttc file may have more than one font. Each font has a sequential
+/// index number starting from 0. Call this function to get the font offset for
+/// a given index; it returns None if the index is out of range. A regular .ttf
+/// file will only define one font and it always be at offset 0, so it will
+/// return Some(0) for index 0, and None for all other indices. You can just
+/// skip this step if you know it's that kind of font.
+pub fn get_font_offset_for_index(font_collection: &[u8], index: i32) -> Option<u32> {
+    // if it's just a font, there's only one valid index
+    if is_font(font_collection) {
+        return if index == 0 { Some(0) } else { None };
+    }
+    // check if it's a TTC
+    if is_collection(font_collection)
+        && (BE::read_u32(&font_collection[4..]) == 0x0001_0000
+            || BE::read_u32(&font_collection[4..]) == 0x0002_0000)
+    {
+        let n = BE::read_i32(&font_collection[8..]);
+        if index >= n {
+            return None;
+        }
+        return Some(BE::read_u32(&font_collection[12 + (index as usize) * 4..]));
+    }
+    None
+}
+
+macro_rules! read_ints {
+    ($n:expr, i16, $data:expr) => {{
+        let mut nums = [0; $n];
+        let data = $data;
+        BE::read_i16_into(&data[..$n * 2], &mut nums);
+        nums
+    }};
+    ($n:expr, u16, $data:expr) => {{
+        let mut nums = [0; $n];
+        let data = $data;
+        BE::read_u16_into(&data[..$n * 2], &mut nums);
+        nums
+    }};
+    ($n:expr, u32, $data:expr) => {{
+        let mut nums = [0; $n];
+        let data = $data;
+        BE::read_u32_into(&data[..$n * 4], &mut nums);
+        nums
+    }};
+}
+
+impl<Data: Deref<Target = [u8]>> FontInfo<Data> {
+    /// Given an offset into the file that defines a font, this function builds
+    /// the necessary cached info for the rest of the system.
+    pub fn new(data: Data, fontstart: usize) -> Option<FontInfo<Data>> {
+        let cmap = find_table(&data, fontstart, b"cmap"); // required
+        let loca = find_table(&data, fontstart, b"loca"); // required
+        let head = find_table(&data, fontstart, b"head"); // required
+        let glyf = find_table(&data, fontstart, b"glyf"); // required
+        let hhea = find_table(&data, fontstart, b"hhea"); // required
+        let hmtx = find_table(&data, fontstart, b"hmtx"); // required
+        let name = find_table(&data, fontstart, b"name"); // not required
+        let kern = find_table(&data, fontstart, b"kern"); // not required
+        if cmap == 0 || loca == 0 || head == 0 || glyf == 0 || hhea == 0 || hmtx == 0 {
+            return None;
+        }
+        let t = find_table(&data, fontstart, b"maxp");
+        let num_glyphs = if t != 0 {
+            BE::read_u16(&data[t as usize + 4..])
+        } else {
+            0xffff
+        };
+
+        // find a cmap encoding table we understand *now* to avoid searching
+        // later. (todo: could make this installable)
+        // the same regardless of glyph.
+        let num_tables = BE::read_u16(&data[cmap as usize + 2..]);
+        let mut index_map = 0;
+        for i in 0..num_tables {
+            let encoding_record = (cmap + 4 + 8 * (i as u32)) as usize;
+            // find an encoding we understand:
+            match platform_id(BE::read_u16(&data[encoding_record..])) {
+                Some(PlatformId::Microsoft) => {
+                    match microsoft_eid(BE::read_u16(&data[encoding_record + 2..])) {
+                        Some(MicrosoftEid::UnicodeBMP) | Some(MicrosoftEid::UnicodeFull) => {
+                            // MS/Unicode
+                            index_map = cmap + BE::read_u32(&data[encoding_record + 4..]);
+                        }
+                        _ => (),
+                    }
+                }
+                Some(PlatformId::Unicode) => {
+                    // Mac/iOS has these
+                    // all the encodingIDs are unicode, so we don't bother to check it
+                    index_map = cmap + BE::read_u32(&data[encoding_record + 4..]);
+                }
+                _ => (),
+            }
+        }
+        if index_map == 0 {
+            return None;
+        }
+        let index_to_loc_format = BE::read_u16(&data[head as usize + 50..]) as u32;
+        Some(FontInfo {
+            // fontstart: fontstart,
+            data,
+            loca,
+            head,
+            glyf,
+            hhea,
+            hmtx,
+            name,
+            kern,
+            num_glyphs: num_glyphs as u32,
+            index_map,
+            index_to_loc_format,
+        })
+    }
+
+    pub fn get_num_glyphs(&self) -> u32 {
+        self.num_glyphs
+    }
+
+    /// If you're going to perform multiple operations on the same character
+    /// and you want a speed-up, call this function with the character you're
+    /// going to process, then use glyph-based functions instead of the
+    /// codepoint-based functions.
+    pub fn find_glyph_index(&self, unicode_codepoint: u32) -> u32 {
+        let data = &self.data;
+        let index_map = &data[self.index_map as usize..]; //self.index_map as usize;
+
+        let format = BE::read_u16(index_map);
+        match format {
+            0 => {
+                // apple byte encoding
+                let bytes = BE::read_u16(&index_map[2..]);
+                if unicode_codepoint < bytes as u32 - 6 {
+                    return index_map[6 + unicode_codepoint as usize] as u32;
+                }
+                0
+            }
+            6 => {
+                let first = BE::read_u16(&index_map[6..]) as u32;
+                let count = BE::read_u16(&index_map[8..]) as u32;
+                if unicode_codepoint >= first && unicode_codepoint < first + count {
+                    return BE::read_u16(&index_map[10 + (unicode_codepoint - first) as usize * 2..])
+                        as u32;
+                }
+                0
+            }
+            2 => {
+                // @TODO: high-byte mapping for japanese/chinese/korean
+                panic!("Index map format unsupported: 2");
+            }
+            4 => {
+                // standard mapping for windows fonts: binary search collection of ranges
+                let segcount = BE::read_u16(&index_map[6..]) as usize >> 1;
+                let mut search_range = BE::read_u16(&index_map[8..]) as usize >> 1;
+                let mut entry_selector = BE::read_u16(&index_map[10..]);
+                let range_shift = BE::read_u16(&index_map[12..]) as usize >> 1;
+
+                // do a binary search of the segments
+                let end_count = self.index_map as usize + 14;
+                let mut search = end_count;
+
+                if unicode_codepoint > 0xffff {
+                    return 0;
+                }
+
+                // they lie from endCount .. endCount + segCount
+                // but searchRange is the nearest power of two, so...
+                if unicode_codepoint >= BE::read_u16(&data[search + range_shift * 2..]) as u32 {
+                    search += range_shift * 2;
+                }
+
+                // now decrement to bias correctly to find smallest
+                search -= 2;
+                while entry_selector != 0 {
+                    search_range >>= 1;
+                    let end = BE::read_u16(&data[search + search_range * 2..]) as u32;
+                    if unicode_codepoint > end {
+                        search += search_range * 2;
+                    }
+                    entry_selector -= 1;
+                }
+                search += 2;
+
+                {
+                    let item = (search - end_count) >> 1;
+                    assert!(
+                        unicode_codepoint <= BE::read_u16(&data[end_count + 2 * item..]) as u32
+                    );
+                    let start = BE::read_u16(&index_map[14 + segcount * 2 + 2 + 2 * item..]) as u32;
+                    if unicode_codepoint < start {
+                        return 0;
+                    }
+                    let offset =
+                        BE::read_u16(&index_map[14 + segcount * 6 + 2 + 2 * item..]) as usize;
+                    if offset == 0 {
+                        return (unicode_codepoint as i32 + BE::read_i16(
+                            &index_map[14 + segcount * 4 + 2 + 2 * item..],
+                        ) as i32) as u16 as u32;
+                    }
+                    BE::read_u16(
+                        &index_map[offset
+                                       + (unicode_codepoint - start) as usize * 2
+                                       + 14
+                                       + segcount * 6
+                                       + 2
+                                       + 2 * item..],
+                    ) as u32
+                }
+            }
+            12 | 13 => {
+                let mut low = 0u32;
+                let mut high = BE::read_u32(&index_map[12..]);
+                let groups = &index_map[16..];
+
+                // Binary search of the right group
+                while low < high {
+                    let mid = (low + high) / 2; // rounds down, so low <= mid < high
+                    let mid12 = (mid * 12) as usize;
+                    let group = &groups[mid12..mid12 + 12];
+                    let start_char = BE::read_u32(group);
+                    if unicode_codepoint < start_char {
+                        high = mid;
+                    } else if unicode_codepoint > BE::read_u32(&group[4..]) {
+                        low = mid + 1;
+                    } else {
+                        let start_glyph = BE::read_u32(&group[8..]);
+                        if format == 12 {
+                            return start_glyph + unicode_codepoint - start_char;
+                        } else {
+                            return start_glyph;
+                        }
+                    }
+                }
+
+                0
+            }
+            n => panic!("Index map format unsupported: {}", n),
+        }
+    }
+
+    /// Returns the series of vertices encoding the shape of the glyph for this
+    /// codepoint.
+    ///
+    /// The shape is a series of countours. Each one starts with
+    /// a moveto, then consists of a series of mixed
+    /// lineto and curveto segments. A lineto
+    /// draws a line from previous endpoint to its x,y; a curveto
+    /// draws a quadratic bezier from previous endpoint to
+    /// its x,y, using cx,cy as the bezier control point.
+    pub fn get_codepoint_shape(&self, unicode_codepoint: u32) -> Option<Vec<Vertex>> {
+        self.get_glyph_shape(self.find_glyph_index(unicode_codepoint))
+    }
+
+    fn get_glyf_offset(&self, glyph_index: u32) -> Option<u32> {
+        if glyph_index >= self.num_glyphs || self.index_to_loc_format >= 2 {
+            // glyph index out of range or unknown index->glyph map format
+            return None;
+        }
+
+        let [g1, g2] = if self.index_to_loc_format == 0 {
+            let d = &self.data[(self.loca + glyph_index * 2) as usize..];
+            let [g1, g2] = read_ints!(2, u16, d);
+            [g1 as u32 * 2, g2 as u32 * 2]
+        } else {
+            read_ints!(2, u32, &self.data[(self.loca + glyph_index * 4) as usize..])
+        };
+        if g1 == g2 {
+            None
+        } else {
+            Some(self.glyf + g1)
+        }
+    }
+
+    /// Like `get_codepoint_box`, but takes a glyph index. Use this if you have
+    /// cached the glyph index for a codepoint.
+    pub fn get_glyph_box(&self, glyph_index: u32) -> Option<Rect<i16>> {
+        let g = self.get_glyf_offset(glyph_index)? as usize;
+        let [x0, y0, x1, y1] = read_ints!(4, i16, &self.data[g + 2..]);
+        Some(Rect { x0, y0, x1, y1 })
+    }
+
+    /// Gets the bounding box of the visible part of the glyph, in unscaled
+    /// coordinates
+    pub fn get_codepoint_box(&self, codepoint: u32) -> Option<Rect<i16>> {
+        self.get_glyph_box(self.find_glyph_index(codepoint))
+    }
+
+    /// returns true if nothing is drawn for this glyph
+    pub fn is_glyph_empty(&self, glyph_index: u32) -> bool {
+        match self.get_glyf_offset(glyph_index) {
+            Some(g) => {
+                let number_of_contours = BE::read_i16(&self.data[g as usize..]);
+                number_of_contours == 0
+            }
+            None => true,
+        }
+    }
+
+    /// Like `get_codepoint_shape`, but takes a glyph index instead. Use this
+    /// if you have cached the glyph index for a codepoint.
+    pub fn get_glyph_shape(&self, glyph_index: u32) -> Option<Vec<Vertex>> {
+        let g = match self.get_glyf_offset(glyph_index) {
+            Some(g) => &self.data[g as usize..],
+            None => return None,
+        };
+
+        let number_of_contours = BE::read_i16(g);
+        let vertices: Vec<Vertex> = if number_of_contours > 0 {
+            self.glyph_shape_positive_contours(g, number_of_contours as usize)
+        } else if number_of_contours == -1 {
+            // Compound shapes
+            let mut more = true;
+            let mut comp = &g[10..];
+            let mut vertices = Vec::new();
+            while more {
+                let mut mtx = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0];
+
+                let [flags, gidx] = read_ints!(2, i16, comp);
+                comp = &comp[4..];
+                let gidx = gidx as u16;
+
+                if flags & 2 != 0 {
+                    // XY values
+                    if flags & 1 != 0 {
+                        // shorts
+                        let [a, b] = read_ints!(2, i16, comp);
+                        comp = &comp[4..];
+                        mtx[4] = a as f32;
+                        mtx[5] = b as f32;
+                    } else {
+                        mtx[4] = (comp[0] as i8) as f32;
+                        mtx[5] = (comp[1] as i8) as f32;
+                        comp = &comp[2..];
+                    }
+                } else {
+                    panic!("Matching points not supported.");
+                }
+                if flags & (1 << 3) != 0 {
+                    // WE_HAVE_A_SCALE
+                    mtx[0] = BE::read_i16(comp) as f32 / 16384.0;
+                    comp = &comp[2..];
+                    mtx[1] = 0.0;
+                    mtx[2] = 0.0;
+                    mtx[3] = mtx[0];
+                } else if flags & (1 << 6) != 0 {
+                    // WE_HAVE_AN_X_AND_YSCALE
+                    let [a, b] = read_ints!(2, i16, comp);
+                    comp = &comp[4..];
+                    mtx[0] = a as f32 / 16384.0;
+                    mtx[1] = 0.0;
+                    mtx[2] = 0.0;
+                    mtx[3] = b as f32 / 16384.0;
+                } else if flags & (1 << 7) != 0 {
+                    // WE_HAVE_A_TWO_BY_TWO
+                    let [a, b, c, d] = read_ints!(4, i16, comp);
+                    comp = &comp[8..];
+                    mtx[0] = a as f32 / 16384.0;
+                    mtx[1] = b as f32 / 16384.0;
+                    mtx[2] = c as f32 / 16384.0;
+                    mtx[3] = d as f32 / 16384.0;
+                }
+
+                // Find transformation scales.
+                let m = (mtx[0] * mtx[0] + mtx[1] * mtx[1]).sqrt();
+                let n = (mtx[2] * mtx[2] + mtx[3] * mtx[3]).sqrt();
+
+                // Get indexed glyph.
+                let mut comp_verts = self.get_glyph_shape(gidx as u32).unwrap_or_else(Vec::new);
+                if !comp_verts.is_empty() {
+                    // Transform vertices
+                    for v in &mut *comp_verts {
+                        let (x, y, cx, cy) = (v.x as f32, v.y as f32, v.cx as f32, v.cy as f32);
+                        *v = Vertex {
+                            type_: v.type_,
+                            x: (m * (mtx[0] * x + mtx[2] * y + mtx[4])) as i16,
+                            y: (n * (mtx[1] * x + mtx[3] * y + mtx[5])) as i16,
+                            cx: (m * (mtx[0] * cx + mtx[2] * cy + mtx[4])) as i16,
+                            cy: (n * (mtx[1] * cx + mtx[3] * cy + mtx[5])) as i16,
+                        };
+                    }
+                    // Append vertices.
+                    vertices.append(&mut comp_verts);
+                }
+                // More components ?
+                more = flags & (1 << 5) != 0;
+            }
+            vertices
+        } else if number_of_contours < 0 {
+            panic!("Contour format not supported.")
+        } else {
+            return None;
+        };
+        Some(vertices)
+    }
+
+    #[inline]
+    fn glyph_shape_positive_contours(
+        &self,
+        glyph_data: &[u8],
+        number_of_contours: usize,
+    ) -> Vec<Vertex> {
+        use VertexType::*;
+
+        struct FlagData {
+            flags: u8,
+            x: i16,
+            y: i16,
+        }
+
+        #[inline]
+        fn close_shape(
+            vertices: &mut Vec<Vertex>,
+            was_off: bool,
+            start_off: bool,
+            sx: i16,
+            sy: i16,
+            scx: i16,
+            scy: i16,
+            cx: i16,
+            cy: i16,
+        ) {
+            if start_off {
+                if was_off {
+                    vertices.push(Vertex {
+                        type_: CurveTo as u8,
+                        x: (cx + scx) >> 1,
+                        y: (cy + scy) >> 1,
+                        cx,
+                        cy,
+                    });
+                }
+                vertices.push(Vertex {
+                    type_: CurveTo as u8,
+                    x: sx,
+                    y: sy,
+                    cx: scx,
+                    cy: scy,
+                });
+            } else {
+                vertices.push(if was_off {
+                    Vertex {
+                        type_: CurveTo as u8,
+                        x: sx,
+                        y: sy,
+                        cx,
+                        cy,
+                    }
+                } else {
+                    Vertex {
+                        type_: LineTo as u8,
+                        x: sx,
+                        y: sy,
+                        cx: 0,
+                        cy: 0,
+                    }
+                });
+            }
+        }
+
+        let number_of_contours = number_of_contours as usize;
+        let mut start_off = false;
+        let mut was_off = false;
+        let end_points_of_contours = &glyph_data[10..];
+        let ins = BE::read_u16(&glyph_data[10 + number_of_contours * 2..]) as usize;
+        let mut points = &glyph_data[10 + number_of_contours * 2 + 2 + ins..];
+
+        let n = 1 + BE::read_u16(&end_points_of_contours[number_of_contours * 2 - 2..]) as usize;
+
+        let m = n + 2 * number_of_contours; // a loose bound on how many vertices we might need
+        let mut vertices: Vec<Vertex> = Vec::with_capacity(m);
+
+        let mut flag_data = Vec::with_capacity(n);
+
+        let mut next_move = 0;
+
+        // in first pass, we load uninterpreted data into the allocated array above
+
+        // first load flags
+        {
+            let mut flagcount = 0;
+            let mut flags = 0;
+            for _ in 0..n {
+                if flagcount == 0 {
+                    flags = points[0];
+                    if flags & 8 != 0 {
+                        flagcount = points[1];
+                        points = &points[2..];
+                    } else {
+                        points = &points[1..];
+                    }
+                } else {
+                    flagcount -= 1;
+                }
+                flag_data.push(FlagData { flags, x: 0, y: 0 });
+            }
+        }
+
+        // now load x coordinates
+        let mut x_coord = 0_i16;
+        for flag_data in &mut flag_data {
+            let flags = flag_data.flags;
+            if flags & 2 != 0 {
+                let dx = i16::from(points[0]);
+                points = &points[1..];
+                if flags & 16 != 0 {
+                    // ???
+                    x_coord += dx;
+                } else {
+                    x_coord -= dx;
+                }
+            } else if flags & 16 == 0 {
+                x_coord += BE::read_i16(points);
+                points = &points[2..];
+            }
+            flag_data.x = x_coord;
+        }
+
+        // now load y coordinates
+        let mut y_coord = 0_i16;
+        for flag_data in &mut flag_data {
+            let flags = flag_data.flags;
+            if flags & 4 != 0 {
+                let dy = i16::from(points[0]);
+                points = &points[1..];
+                if flags & 32 != 0 {
+                    y_coord += dy;
+                } else {
+                    y_coord -= dy;
+                }
+            } else if flags & 32 == 0 {
+                y_coord += BE::read_i16(points);
+                points = &points[2..];
+            }
+            flag_data.y = y_coord;
+        }
+
+        // now convert them to our format
+        let mut sx = 0;
+        let mut sy = 0;
+        let mut cx = 0;
+        let mut cy = 0;
+        let mut scx = 0;
+        let mut scy = 0;
+        let mut j = 0;
+
+        let mut iter = flag_data.into_iter().enumerate().peekable();
+
+        while let Some((index, FlagData { flags, x, y })) = iter.next() {
+            if next_move == index {
+                if index != 0 {
+                    close_shape(&mut vertices, was_off, start_off, sx, sy, scx, scy, cx, cy);
+                }
+
+                // now start the new one
+                start_off = flags & 1 == 0;
+                if start_off {
+                    // if we start off with an off-curve point, then when we need to find a
+                    // point on the curve where we can start, and we
+                    // need to save some state for
+                    // when we wraparound.
+                    scx = x;
+                    scy = y;
+
+                    let (next_flags, next_x, next_y) = {
+                        let peek = &iter.peek().unwrap().1;
+                        (peek.flags, peek.x, peek.y)
+                    };
+
+                    if next_flags & 1 == 0 {
+                        // next point is also a curve point, so interpolate an on-point curve
+                        sx = (x + next_x) >> 1;
+                        sy = (y + next_y) >> 1;
+                    } else {
+                        // otherwise just use the next point as our start point
+                        sx = next_x;
+                        sy = next_y;
+
+                        // we're using point i+1 as the starting point, so skip it
+                        let _ = iter.next();
+                    }
+                } else {
+                    sx = x;
+                    sy = y;
+                }
+                vertices.push(Vertex {
+                    type_: MoveTo as u8,
+                    x: sx,
+                    y: sy,
+                    cx: 0,
+                    cy: 0,
+                });
+                was_off = false;
+                next_move = 1 + BE::read_u16(&end_points_of_contours[j * 2..]) as usize;
+                j += 1;
+            } else if flags & 1 == 0 {
+                // if it's a curve
+                if was_off {
+                    // two off-curve control points in a row means interpolate an on-curve
+                    // midpoint
+                    vertices.push(Vertex {
+                        type_: CurveTo as u8,
+                        x: ((cx + x) >> 1),
+                        y: ((cy + y) >> 1),
+                        cx,
+                        cy,
+                    });
+                }
+                cx = x;
+                cy = y;
+                was_off = true;
+            } else {
+                vertices.push(if was_off {
+                    Vertex {
+                        type_: CurveTo as u8,
+                        x,
+                        y,
+                        cx,
+                        cy,
+                    }
+                } else {
+                    Vertex {
+                        type_: LineTo as u8,
+                        x,
+                        y,
+                        cx: 0,
+                        cy: 0,
+                    }
+                });
+                was_off = false;
+            }
+        }
+        close_shape(
+            &mut vertices,
+            // &mut num_vertices,
+            was_off,
+            start_off,
+            sx,
+            sy,
+            scx,
+            scy,
+            cx,
+            cy,
+        );
+
+        vertices
+    }
+
+    /// like `get_codepoint_h_metrics`, but takes a glyph index instead. Use
+    /// this if you have cached the glyph index for a codepoint.
+    pub fn get_glyph_h_metrics(&self, glyph_index: u32) -> HMetrics {
+        let num_of_long_hor_metrics = BE::read_u16(&self.data[self.hhea as usize + 34..]) as usize;
+        let glyph_index = glyph_index as usize;
+        if glyph_index < num_of_long_hor_metrics {
+            let data = &self.data[self.hmtx as usize + 4 * glyph_index..];
+            let [advance_width, left_side_bearing] = read_ints!(2, i16, data);
+            HMetrics {
+                advance_width: i32::from(advance_width),
+                left_side_bearing: i32::from(left_side_bearing),
+            }
+        } else {
+            HMetrics {
+                advance_width: BE::read_i16(
+                    &self.data[self.hmtx as usize + 4 * (num_of_long_hor_metrics - 1)..],
+                ) as i32,
+                left_side_bearing: BE::read_i16(
+                    &self.data[self.hmtx as usize
+                                   + 4 * num_of_long_hor_metrics
+                                   + 2 * (glyph_index as isize - num_of_long_hor_metrics as isize)
+                                       as usize..],
+                ) as i32,
+            }
+        }
+    }
+
+    /// like `get_codepoint_kern_advance`, but takes glyph indices instead. Use
+    /// this if you have cached the glyph indices for the codepoints.
+    pub fn get_glyph_kern_advance(&self, glyph_1: u32, glyph_2: u32) -> i32 {
+        let kern = &self.data[self.kern as usize..];
+        // we only look at the first table. it must be 'horizontal' and format 0
+        if self.kern == 0 || BE::read_u16(&kern[2..]) < 1 || BE::read_u16(&kern[8..]) != 1 {
+            // kern not present, OR
+            // no tables (need at least one), OR
+            // horizontal flag not set in format
+            return 0;
+        }
+
+        let mut l: i32 = 0;
+        let mut r: i32 = BE::read_u16(&kern[10..]) as i32 - 1;
+        let needle = glyph_1 << 16 | glyph_2;
+        while l <= r {
+            let m = (l + r) >> 1;
+            let straw = BE::read_u32(&kern[18 + (m as usize) * 6..]); // note: unaligned read
+            if needle < straw {
+                r = m - 1;
+            } else if needle > straw {
+                l = m + 1;
+            } else {
+                return BE::read_i16(&kern[22 + (m as usize) * 6..]) as i32;
+            }
+        }
+        0
+    }
+
+    /// an additional amount to add to the 'advance' value between cp1 and cp2
+    pub fn get_codepoint_kern_advance(&self, cp1: u32, cp2: u32) -> i32 {
+        if self.kern == 0 {
+            // if no kerning table, don't waste time looking up both codepoint->glyphs
+            0
+        } else {
+            self.get_glyph_kern_advance(self.find_glyph_index(cp1), self.find_glyph_index(cp2))
+        }
+    }
+
+    /// `left_side_bearing` is the offset from the current horizontal position
+    /// to the left edge of the character `advance_width` is the offset
+    /// from the current horizontal position to the next horizontal
+    /// position these are
+    /// expressed in unscaled
+    /// coordinates
+    pub fn get_codepoint_h_metrics(&self, codepoint: u32) -> HMetrics {
+        self.get_glyph_h_metrics(self.find_glyph_index(codepoint))
+    }
+
+    /// `ascent` is the coordinate above the baseline the font extends; descent
+    /// is the coordinate below the baseline the font extends (i.e. it is
+    /// typically negative) `line_gap` is the spacing between one row's
+    /// descent and the next row's ascent... so you should advance the
+    /// vertical position by `ascent -
+    /// descent + line_gap` these are expressed in unscaled coordinates, so
+    /// you must multiply by the scale factor for a given size
+    pub fn get_v_metrics(&self) -> VMetrics {
+        let hhea = &self.data[self.hhea as usize..];
+        let [ascent, descent, line_gap] = read_ints!(3, i16, &hhea[4..]);
+        VMetrics {
+            ascent: i32::from(ascent),
+            descent: i32::from(descent),
+            line_gap: i32::from(line_gap),
+        }
+    }
+
+    /// the bounding box around all possible characters
+    pub fn get_bounding_box(&self) -> Rect<i16> {
+        let head = &self.data[self.head as usize..];
+        Rect {
+            x0: BE::read_i16(&head[36..]),
+            y0: BE::read_i16(&head[38..]),
+            x1: BE::read_i16(&head[40..]),
+            y1: BE::read_i16(&head[42..]),
+        }
+    }
+
+    /// computes a scale factor to produce a font whose "height" is 'pixels'
+    /// tall. Height is measured as the distance from the highest ascender
+    /// to the lowest descender; in other words, it's equivalent to calling
+    /// GetFontVMetrics and computing:
+    ///       scale = pixels / (ascent - descent)
+    /// so if you prefer to measure height by the ascent only, use a similar
+    /// calculation.
+    pub fn scale_for_pixel_height(&self, height: f32) -> f32 {
+        let hhea = &self.data[self.hhea as usize..];
+        let fheight = {
+            let [a, b] = read_ints!(2, i16, &hhea[4..]);
+            f32::from(a) - f32::from(b)
+        };
+        height / fheight
+    }
+
+    /// Returns the units per EM square of this font.
+    pub fn units_per_em(&self) -> u16 {
+        BE::read_u16(&self.data[self.head as usize + 18..])
+    }
+
+    /// computes a scale factor to produce a font whose EM size is mapped to
+    /// `pixels` tall. This is probably what traditional APIs compute, but
+    /// I'm not positive.
+    pub fn scale_for_mapping_em_to_pixels(&self, pixels: f32) -> f32 {
+        pixels / (self.units_per_em() as f32)
+    }
+
+    /// like `get_codepoint_bitmap_box_subpixel`, but takes a glyph index
+    /// instead of a codepoint.
+    pub fn get_glyph_bitmap_box_subpixel(
+        &self,
+        glyph: u32,
+        scale_x: f32,
+        scale_y: f32,
+        shift_x: f32,
+        shift_y: f32,
+    ) -> Option<Rect<i32>> {
+        if let Some(glyph_box) = self.get_glyph_box(glyph) {
+            // move to integral bboxes (treating pixels as little squares, what pixels get
+            // touched?)
+            Some(Rect {
+                x0: (glyph_box.x0 as f32 * scale_x + shift_x).floor() as i32,
+                y0: (-glyph_box.y1 as f32 * scale_y + shift_y).floor() as i32,
+                x1: (glyph_box.x1 as f32 * scale_x + shift_x).ceil() as i32,
+                y1: (-glyph_box.y0 as f32 * scale_y + shift_y).ceil() as i32,
+            })
+        } else {
+            // e.g. space character
+            None
+        }
+    }
+
+    /// like `get_codepoint_bitmap_box`, but takes a glyph index instead of a
+    /// codepoint.
+    pub fn get_glyph_bitmap_box(
+        &self,
+        glyph: u32,
+        scale_x: f32,
+        scale_y: f32,
+    ) -> Option<Rect<i32>> {
+        self.get_glyph_bitmap_box_subpixel(glyph, scale_x, scale_y, 0.0, 0.0)
+    }
+
+    /// same as get_codepoint_bitmap_box, but you can specify a subpixel
+    /// shift for the character
+    pub fn get_codepoint_bitmap_box_subpixel(
+        &self,
+        codepoint: u32,
+        scale_x: f32,
+        scale_y: f32,
+        shift_x: f32,
+        shift_y: f32,
+    ) -> Option<Rect<i32>> {
+        self.get_glyph_bitmap_box_subpixel(
+            self.find_glyph_index(codepoint),
+            scale_x,
+            scale_y,
+            shift_x,
+            shift_y,
+        )
+    }
+
+    /// get the bounding box of the bitmap centered around the glyph origin; so
+    /// the bitmap width is x1-x0, height is y1-y0, and location to place
+    /// the bitmap top left is (left_side_bearing*scale, y0).
+    /// (Note that the bitmap uses y-increases-down, but the shape uses
+    /// y-increases-up, so CodepointBitmapBox and CodepointBox are inverted.)
+    pub fn get_codepoint_bitmap_box(
+        &self,
+        codepoint: u32,
+        scale_x: f32,
+        scale_y: f32,
+    ) -> Option<Rect<i32>> {
+        self.get_codepoint_bitmap_box_subpixel(codepoint, scale_x, scale_y, 0.0, 0.0)
+    }
+
+    pub fn get_font_name_strings(&self) -> FontNameIter<Data> {
+        let nm = self.name as usize;
+        if nm == 0 {
+            return FontNameIter {
+                font_info: &self,
+                string_offset: 0,
+                index: 0,
+                count: 0,
+            };
+        }
+        let count = BE::read_u16(&self.data[nm + 2..]) as usize;
+        let string_offset = nm + BE::read_u16(&self.data[nm + 4..]) as usize;
+
+        FontNameIter {
+            font_info: &self,
+            string_offset,
+            index: 0,
+            count,
+        }
+    }
+}
+
+#[derive(Clone, Copy)]
+pub struct FontNameIter<'a, Data: 'a + Deref<Target = [u8]>> {
+    /// Font info.
+    font_info: &'a FontInfo<Data>,
+    string_offset: usize,
+    /// Next index.
+    index: usize,
+    /// Number of name strings.
+    count: usize,
+}
+
+impl<'a, Data: 'a + Deref<Target = [u8]>> Iterator for FontNameIter<'a, Data> {
+    type Item = (&'a [u8], Option<PlatformEncodingLanguageId>, u16);
+
+    fn next(&mut self) -> Option<Self::Item> {
+        if self.index >= self.count {
+            return None;
+        }
+
+        let loc = self.font_info.name as usize + 6 + 12 * self.index;
+
+        let pl_id = platform_id(BE::read_u16(&self.font_info.data[loc..]));
+        let platform_encoding_language_id = pl_id.map(|pl_id| {
+            let encoding_id = BE::read_u16(&self.font_info.data[loc + 2..]);
+            let language_id = BE::read_u16(&self.font_info.data[loc + 4..]);
+            platform_encoding_id(pl_id, Some(encoding_id), Some(language_id))
+        });
+        // @TODO: Define an enum type for Name ID.
+        //        See https://www.microsoft.com/typography/otspec/name.htm, "Name IDs" section.
+        let name_id = BE::read_u16(&self.font_info.data[loc + 6..]);
+        let length = BE::read_u16(&self.font_info.data[loc + 8..]) as usize;
+        let offset = self.string_offset + BE::read_u16(&self.font_info.data[loc + 10..]) as usize;
+
+        self.index += 1;
+
+        Some((
+            &self.font_info.data[offset..offset + length],
+            platform_encoding_language_id,
+            name_id,
+        ))
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let remaining = self.count - self.index;
+        (remaining, Some(remaining))
+    }
+
+    fn count(self) -> usize {
+        self.count - self.index
+    }
+
+    fn last(mut self) -> Option<Self::Item> {
+        if self.index >= self.count || self.count == 0 {
+            return None;
+        }
+        self.index = self.count - 1;
+        self.next()
+    }
+
+    fn nth(&mut self, n: usize) -> Option<Self::Item> {
+        if n > self.count - self.index {
+            self.index = self.count;
+            return None;
+        }
+        self.index += n;
+        self.next()
+    }
+}
diff --git a/rustc_deps/vendor/stb_truetype/tests/mod.rs b/rustc_deps/vendor/stb_truetype/tests/mod.rs
new file mode 100644
index 0000000..931ff1e
--- /dev/null
+++ b/rustc_deps/vendor/stb_truetype/tests/mod.rs
@@ -0,0 +1,11 @@
+extern crate stb_truetype;
+
+mod tests {
+    use stb_truetype;
+
+    #[test]
+    fn is_font() {
+        assert!(stb_truetype::is_font(b"OTTO"));
+        assert!(!stb_truetype::is_font(b""));
+    }
+}