[tor-commits] [tor-rust-dependencies/master] Add digest-0.7.2 dependency for #24659.

nickm at torproject.org nickm at torproject.org
Tue May 8 22:49:44 UTC 2018


commit e92c124a41535bd2131b9506a7d95c68c9d8feda
Author: Isis Lovecruft <isis at torproject.org>
Date:   Tue May 8 21:28:03 2018 +0000

    Add digest-0.7.2 dependency for #24659.
---
 crates/digest-0.7.2/.cargo-checksum.json           |    1 +
 crates/digest-0.7.2/Cargo.toml                     |   30 +
 crates/digest-0.7.2/LICENSE-APACHE                 |  201 +++
 crates/digest-0.7.2/LICENSE-MIT                    |   25 +
 crates/digest-0.7.2/src/dev.rs                     |  171 +++
 crates/digest-0.7.2/src/digest.rs                  |   85 ++
 crates/digest-0.7.2/src/lib.rs                     |   96 ++
 crates/generic-array-0.9.0/.cargo-checksum.json    |    1 +
 crates/generic-array-0.9.0/.travis.yml             |   18 +
 crates/generic-array-0.9.0/Cargo.toml              |   32 +
 crates/generic-array-0.9.0/LICENSE                 |   21 +
 crates/generic-array-0.9.0/README.md               |   34 +
 crates/generic-array-0.9.0/rustfmt.toml            |    3 +
 crates/generic-array-0.9.0/src/arr.rs              |   57 +
 crates/generic-array-0.9.0/src/hex.rs              |  101 ++
 crates/generic-array-0.9.0/src/impl_serde.rs       |   68 +
 crates/generic-array-0.9.0/src/impls.rs            |  171 +++
 crates/generic-array-0.9.0/src/iter.rs             |  117 ++
 crates/generic-array-0.9.0/src/lib.rs              |  464 ++++++
 crates/generic-array-0.9.0/tests/hex.rs            |   44 +
 crates/generic-array-0.9.0/tests/import_name.rs    |   10 +
 crates/generic-array-0.9.0/tests/mod.rs            |  169 +++
 crates/typenum-1.9.0/.cargo-checksum.json          |    1 +
 crates/typenum-1.9.0/.travis.yml                   |   42 +
 crates/typenum-1.9.0/CHANGELOG.md                  |   52 +
 crates/typenum-1.9.0/Cargo.toml                    |   24 +
 crates/typenum-1.9.0/LICENSE                       |   21 +
 crates/typenum-1.9.0/README.md                     |   42 +
 crates/typenum-1.9.0/build/main.rs                 |  177 +++
 crates/typenum-1.9.0/build/op.rs                   |  483 +++++++
 crates/typenum-1.9.0/build/tests.rs                |  293 ++++
 crates/typenum-1.9.0/ghp-import/LICENSE            |   11 +
 crates/typenum-1.9.0/ghp-import/MANIFEST.in        |    2 +
 crates/typenum-1.9.0/ghp-import/Makefile           |    8 +
 crates/typenum-1.9.0/ghp-import/README.md          |   78 +
 crates/typenum-1.9.0/ghp-import/docs/build.py      |   22 +
 .../typenum-1.9.0/ghp-import/docs/images/bg_hr.png |  Bin 0 -> 943 bytes
 .../ghp-import/docs/images/blacktocat.png          |  Bin 0 -> 1428 bytes
 .../ghp-import/docs/images/icon_download.png       |  Bin 0 -> 1162 bytes
 .../ghp-import/docs/images/sprite_download.png     |  Bin 0 -> 16799 bytes
 .../typenum-1.9.0/ghp-import/docs/index.html.tmpl  |   42 +
 crates/typenum-1.9.0/ghp-import/docs/style.css     |  431 ++++++
 crates/typenum-1.9.0/ghp-import/ghp_import.py      |  248 ++++
 crates/typenum-1.9.0/ghp-import/requirements.txt   |    2 +
 crates/typenum-1.9.0/ghp-import/setup.py           |   41 +
 crates/typenum-1.9.0/src/array.rs                  |  269 ++++
 crates/typenum-1.9.0/src/bit.rs                    |  263 ++++
 crates/typenum-1.9.0/src/int.rs                    |  910 ++++++++++++
 crates/typenum-1.9.0/src/lib.rs                    |  143 ++
 crates/typenum-1.9.0/src/marker_traits.rs          |  112 ++
 crates/typenum-1.9.0/src/operator_aliases.rs       |  102 ++
 crates/typenum-1.9.0/src/private.rs                |  371 +++++
 crates/typenum-1.9.0/src/type_operators.rs         |  499 +++++++
 crates/typenum-1.9.0/src/uint.rs                   | 1499 ++++++++++++++++++++
 crates/typenum-1.9.0/tests/test.rs                 |    1 +
 55 files changed, 8108 insertions(+)

diff --git a/crates/digest-0.7.2/.cargo-checksum.json b/crates/digest-0.7.2/.cargo-checksum.json
new file mode 100644
index 0000000..9208e04
--- /dev/null
+++ b/crates/digest-0.7.2/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"ed88be5d30abfcaec2cb19506924dc34ccb835a18132ac4e2ada488d6fb5edfe","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"9e0dfd2dd4173a530e238cb6adb37aa78c34c6bc7444e0e10c1ab5d8881f63ba","src/dev.rs":"c824f834fa8b8c729024e4ec61138e89c26a56bfb6b50295600dddb5ff8fff62","src/digest.rs":"1e090459cd5775fa08cf973b717753992150b3dce92f17f854fb5bf4d705fef2","src/lib.rs":"b34d844aa0aedfeb6cfddff1504f43f86182c92384da30457fdc278571cafff3"},"package":"00a49051fef47a72c9623101b19bd71924a45cca838826caae3eaa4d00772603"}
\ No newline at end of file
diff --git a/crates/digest-0.7.2/Cargo.toml b/crates/digest-0.7.2/Cargo.toml
new file mode 100644
index 0000000..90c4ee3
--- /dev/null
+++ b/crates/digest-0.7.2/Cargo.toml
@@ -0,0 +1,30 @@
+# 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 = "digest"
+version = "0.7.2"
+authors = ["RustCrypto Developers"]
+description = "Traits for cryptographic hash functions"
+documentation = "https://docs.rs/digest"
+keywords = ["digest", "crypto", "hash"]
+categories = ["cryptography", "no-std"]
+license = "MIT/Apache-2.0"
+repository = "https://github.com/RustCrypto/traits"
+[dependencies.generic-array]
+version = "0.9"
+
+[features]
+dev = []
+std = []
+[badges.travis-ci]
+repository = "RustCrypto/traits"
diff --git a/crates/digest-0.7.2/LICENSE-APACHE b/crates/digest-0.7.2/LICENSE-APACHE
new file mode 100644
index 0000000..78173fa
--- /dev/null
+++ b/crates/digest-0.7.2/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/crates/digest-0.7.2/LICENSE-MIT b/crates/digest-0.7.2/LICENSE-MIT
new file mode 100644
index 0000000..8dcb85b
--- /dev/null
+++ b/crates/digest-0.7.2/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2017 Artyom Pavlov
+
+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/crates/digest-0.7.2/src/dev.rs b/crates/digest-0.7.2/src/dev.rs
new file mode 100644
index 0000000..35778cd
--- /dev/null
+++ b/crates/digest-0.7.2/src/dev.rs
@@ -0,0 +1,171 @@
+use super::{Digest, Input, VariableOutput, ExtendableOutput, XofReader};
+use core::fmt::Debug;
+
+pub struct Test {
+    pub name: &'static str,
+    pub input: &'static [u8],
+    pub output: &'static [u8],
+}
+
+#[macro_export]
+macro_rules! new_tests {
+    ( $( $name:expr ),*  ) => {
+        [$(
+            Test {
+                name: $name,
+                input: include_bytes!(concat!("data/", $name, ".input.bin")),
+                output: include_bytes!(concat!("data/", $name, ".output.bin")),
+            },
+        )*]
+    };
+    ( $( $name:expr ),+, ) => (new_tests!($($name),+))
+}
+
+pub fn main_test<D: Digest + Debug + Clone>(tests: &[Test]) {
+    // Test that it works when accepting the message all at once
+    for t in tests.iter() {
+        let mut sh = D::default();
+        sh.input(t.input);
+
+        let out = sh.result();
+
+        assert_eq!(out[..], t.output[..]);
+    }
+
+    // Test that it works when accepting the message in pieces
+    for t in tests.iter() {
+        let mut sh = D::default();
+        let len = t.input.len();
+        let mut left = len;
+        while left > 0 {
+            let take = (left + 1) / 2;
+            sh.input(&t.input[len - left..take + len - left]);
+            left = left - take;
+        }
+
+        let out = sh.result();
+
+        assert_eq!(out[..], t.output[..]);
+    }
+}
+
+pub fn variable_test<D>(tests: &[Test])
+    where D: Input + VariableOutput + Clone + Debug
+{
+    let mut buf = [0u8; 1024];
+    // Test that it works when accepting the message all at once
+    for t in tests.iter() {
+        let mut sh = D::new(t.output.len()).unwrap();
+        sh.process(t.input);
+
+        let out = sh.variable_result(&mut buf[..t.output.len()]).unwrap();
+
+        assert_eq!(out[..], t.output[..]);
+    }
+
+    // Test that it works when accepting the message in pieces
+    for t in tests.iter() {
+        let mut sh = D::new(t.output.len()).unwrap();
+        let len = t.input.len();
+        let mut left = len;
+        while left > 0 {
+            let take = (left + 1) / 2;
+            sh.process(&t.input[len - left..take + len - left]);
+            left = left - take;
+        }
+
+        let out = sh.variable_result(&mut buf[..t.output.len()]).unwrap();
+
+        assert_eq!(out[..], t.output[..]);
+    }
+}
+
+
+pub fn xof_test<D>(tests: &[Test])
+    where D: Input + ExtendableOutput + Default + Debug + Clone
+{
+    let mut buf = [0u8; 1024];
+    // Test that it works when accepting the message all at once
+    for t in tests.iter() {
+        let mut sh = D::default();
+        sh.process(t.input);
+
+        let out = &mut buf[..t.output.len()];
+        sh.xof_result().read(out);
+
+        assert_eq!(out[..], t.output[..]);
+    }
+
+    // Test that it works when accepting the message in pieces
+    for t in tests.iter() {
+        let mut sh = D::default();
+        let len = t.input.len();
+        let mut left = len;
+        while left > 0 {
+            let take = (left + 1) / 2;
+            sh.process(&t.input[len - left..take + len - left]);
+            left = left - take;
+        }
+
+        let out = &mut buf[..t.output.len()];
+        sh.xof_result().read(out);
+
+        assert_eq!(out[..], t.output[..]);
+    }
+
+    // Test reeading from reader byte by byte
+    for t in tests.iter() {
+        let mut sh = D::default();
+        sh.process(t.input);
+
+        let mut reader = sh.xof_result();
+        let out = &mut buf[..t.output.len()];
+        for chunk in out.chunks_mut(1) {
+            reader.read(chunk);
+        }
+
+        assert_eq!(out[..], t.output[..]);
+    }
+}
+
+pub fn one_million_a<D: Digest + Default + Debug + Clone>(expected: &[u8]) {
+    let mut sh = D::default();
+    for _ in 0..50000 {
+        sh.input(&[b'a'; 10]);
+    }
+    sh.input(&[b'a'; 500000]);
+    let out = sh.result();
+    assert_eq!(out[..], expected[..]);
+}
+
+
+#[macro_export]
+macro_rules! bench_digest {
+    ($name:ident, $engine:path, $bs:expr) => {
+        #[bench]
+        fn $name(b: &mut Bencher) {
+            let mut d = <$engine>::default();
+            let data = [0; $bs];
+
+            b.iter(|| {
+                d.input(&data);
+            });
+
+            b.bytes = $bs;
+        }
+    };
+
+    ($engine:path) => {
+        extern crate test;
+
+        use test::Bencher;
+        use digest::Digest;
+
+        bench_digest!(bench1_16, $engine, 1<<4);
+        bench_digest!(bench2_64, $engine, 1<<6);
+        bench_digest!(bench3_256, $engine, 1<<8);
+        bench_digest!(bench4_1k, $engine, 1<<10);
+        bench_digest!(bench5_4k, $engine, 1<<12);
+        bench_digest!(bench6_16k, $engine, 1<<14);
+    }
+}
diff --git a/crates/digest-0.7.2/src/digest.rs b/crates/digest-0.7.2/src/digest.rs
new file mode 100644
index 0000000..8439718
--- /dev/null
+++ b/crates/digest-0.7.2/src/digest.rs
@@ -0,0 +1,85 @@
+use super::{Input, BlockInput, FixedOutput};
+use generic_array::GenericArray;
+#[cfg(feature = "std")]
+use std::io;
+
+type Output<N> = GenericArray<u8, N>;
+
+/// The `Digest` trait specifies an interface common for digest functions.
+///
+/// It's a convinience wrapper around `Input`, `FixedOutput`, `BlockInput` and
+/// `Default` traits. It also provides additional convinience methods.
+pub trait Digest: Input + BlockInput + FixedOutput + Default {
+    /// Create new hasher instance
+    fn new() -> Self {
+        Self::default()
+    }
+
+    /// Digest input data. This method can be called repeatedly
+    /// for use with streaming messages.
+    fn input(&mut self, input: &[u8]) {
+        self.process(input);
+    }
+
+    /// Retrieve the digest result. This method consumes digest instance.
+    fn result(self) -> Output<Self::OutputSize> {
+        self.fixed_result()
+    }
+
+    /// Convinience function to compute hash of the `data`. It will handle
+    /// hasher creation, data feeding and finalization.
+    ///
+    /// Example:
+    ///
+    /// ```rust,ignore
+    /// println!("{:x}", sha2::Sha256::digest(b"Hello world"));
+    /// ```
+    #[inline]
+    fn digest(data: &[u8]) -> Output<Self::OutputSize> {
+        let mut hasher = Self::default();
+        hasher.process(data);
+        hasher.fixed_result()
+    }
+
+    /// Convinience function to compute hash of the string. It's equivalent to
+    /// `digest(input_string.as_bytes())`.
+    #[inline]
+    fn digest_str(str: &str) -> Output<Self::OutputSize> {
+        Self::digest(str.as_bytes())
+    }
+
+    /// Convinience function which takes `std::io::Read` as a source and computes
+    /// value of digest function `D`, e.g. SHA-2, SHA-3, BLAKE2, etc. using 1 KB
+    /// blocks.
+    ///
+    /// Usage example:
+    ///
+    /// ```rust,ignore
+    /// use std::fs;
+    /// use sha2::{Sha256, Digest};
+    ///
+    /// let mut file = fs::File::open("Cargo.toml")?;
+    /// let result = Sha256::digest_reader(&mut file)?;
+    /// println!("{:x}", result);
+    /// ```
+    #[cfg(feature = "std")]
+    #[inline]
+    fn digest_reader(source: &mut io::Read)
+        -> io::Result<Output<Self::OutputSize>>
+    {
+        let mut hasher = Self::default();
+
+        let mut buffer = [0u8; 1024];
+        loop {
+            let bytes_read = source.read(&mut buffer)?;
+            hasher.input(&buffer[..bytes_read]);
+            if bytes_read == 0 {
+                break;
+            }
+        }
+
+        Ok(hasher.result())
+    }
+}
+
+impl<D: Input + FixedOutput + BlockInput + Default> Digest for D {}
diff --git a/crates/digest-0.7.2/src/lib.rs b/crates/digest-0.7.2/src/lib.rs
new file mode 100644
index 0000000..f1a91cf
--- /dev/null
+++ b/crates/digest-0.7.2/src/lib.rs
@@ -0,0 +1,96 @@
+//! This crate provides traits for describing funcionality of cryptographic hash
+//! functions.
+//!
+//! By default std functionality in this crate disabled. (e.g. method for
+//! hashing `Read`ers) To enable it turn on `std` feature in your `Cargo.toml`
+//! for this crate.
+#![cfg_attr(not(feature = "std"), no_std)]
+pub extern crate generic_array;
+
+#[cfg(feature = "std")]
+use std as core;
+use generic_array::{GenericArray, ArrayLength};
+
+mod digest;
+#[cfg(feature = "dev")]
+pub mod dev;
+
+pub use digest::Digest;
+
+// `process` is choosen to not overlap with `input` method in the digest trait
+// change it on trait alias stabilization
+
+/// Trait for processing input data
+pub trait Input {
+    /// Digest input data. This method can be called repeatedly
+    /// for use with streaming messages.
+    fn process(&mut self, input: &[u8]);
+}
+
+/// Trait to indicate that digest function processes data in blocks of size
+/// `BlockSize`. Main usage of this trait is for implementing HMAC generically.
+pub trait BlockInput {
+    type BlockSize: ArrayLength<u8>;
+}
+
+/// Trait for returning digest result with the fixed size
+pub trait FixedOutput {
+    type OutputSize: ArrayLength<u8>;
+
+    /// Retrieve the digest result. This method consumes digest instance.
+    fn fixed_result(self) -> GenericArray<u8, Self::OutputSize>;
+}
+
+/// The error type for variable digest output
+#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
+pub struct InvalidLength;
+
+/// Trait for returning digest result with the varaible size
+pub trait VariableOutput: core::marker::Sized {
+    /// Create new hasher instance with given output size. Will return
+    /// `Err(InvalidLength)` in case if hasher can not work with the given
+    /// output size. Will always return an error if output size equals to zero.
+    fn new(output_size: usize) -> Result<Self, InvalidLength>;
+
+    /// Get output size of the hasher instance provided to the `new` method
+    fn output_size(&self) -> usize;
+
+    /// Retrieve the digest result into provided buffer. Length of the buffer
+    /// must be equal to output size provided to the `new` method, otherwise
+    /// `Err(InvalidLength)` will be returned
+    fn variable_result(self, buffer: &mut [u8]) -> Result<&[u8], InvalidLength>;
+}
+
+/// Trait for decribing readers which are used to extract extendable output
+/// from the resulting state of hash function.
+pub trait XofReader {
+    /// Read output into the `buffer`. Can be called unlimited number of times.
+    fn read(&mut self, buffer: &mut [u8]);
+}
+
+/// Trait which describes extendable output (XOF) of hash functions. Using this
+/// trait you first need to get structure which implements `XofReader`, using
+/// which you can read extendable output.
+pub trait ExtendableOutput {
+    type Reader: XofReader;
+
+    /// Finalize hash function and return XOF reader
+    fn xof_result(self) -> Self::Reader;
+}
+
+/// Macro for defining opaque `Debug` implementation. It will use the following
+/// format: "HasherName { ... }". While it's convinient to have it
+/// (e.g. for including in other structs), it could be undesirable to leak
+/// internall state, which can happen for example through uncareful logging.
+#[macro_export]
+macro_rules! impl_opaque_debug {
+    ($state:ty) => {
+        impl ::core::fmt::Debug for $state {
+            fn fmt(&self, f: &mut ::core::fmt::Formatter)
+                -> Result<(), ::core::fmt::Error>
+            {
+                write!(f, concat!(stringify!($state), " {{ ... }}"))
+            }
+        }
+    }
+}
diff --git a/crates/generic-array-0.9.0/.cargo-checksum.json b/crates/generic-array-0.9.0/.cargo-checksum.json
new file mode 100644
index 0000000..b6789fd
--- /dev/null
+++ b/crates/generic-array-0.9.0/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{".travis.yml":"e54c4d5b57dd91d875a36d2d57d68fef9c14bb0c31481f2e18877edf040f8676","Cargo.toml":"87ff65d640c137c26d338f96e21e769af1e1b2e7fa615b40a1bcc755448bb118","LICENSE":"ad4fcfaf8d5b12b97409c137a03d4a4e4b21024c65c54f976cc3b609c1bd5b0f","README.md":"9a1a45416eac57050036b13df6ec84d21d555e820726af3c782896bd9d37d94b","rustfmt.toml":"2a298b4ce1fe6e16b8f281a0035567b8eb15042ed3062729fd28224f29c2f75a","src/arr.rs":"cc1ea0a9ef6a524b90767cc8a89f6b939394a2948a645ed313c0bf5ce5a258a4","src/hex.rs":"bfbf304fb4dea6f7edc0569b38bf2ac7657ce089c5761891321722509e3b5076","src/impl_serde.rs":"805885478728b3c205b842d46deb377b7dd6dd4c4c50254064431f49f0981a2a","src/impls.rs":"8c54e294a82a2bf344bdcb9949b8a84903fb65698d6b1b1e0ab9f5e7847be64f","src/iter.rs":"e52217f04d0dc046f13ef2e3539b90eabd4d55bb85cf40f76ba0bf86d5e55ef0","src/lib.rs":"da93fa505eee94b40fce0fe98e26ed3bb4d2bc4d4869af01598b6e54fc9c0f8d","tests/hex.rs":"e909bc0564e7d52c5fcf172dfc0fac7085010c6a21d38581bf73a54ab2e256e1","tests/import_na
 me.rs":"1235729ecbde47fc9a38b3bf35c750a53ed55e3cf967c9d2b24fd759dc9e9e0c","tests/mod.rs":"f4100c5338906c038636f98f4d2b3d272f59580662afa89d915eafb96d7bbcf9"},"package":"ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"}
\ No newline at end of file
diff --git a/crates/generic-array-0.9.0/.travis.yml b/crates/generic-array-0.9.0/.travis.yml
new file mode 100644
index 0000000..e7432fa
--- /dev/null
+++ b/crates/generic-array-0.9.0/.travis.yml
@@ -0,0 +1,18 @@
+language: rust
+script:
+  - cd $TRAVIS_BUILD_DIR
+  - cargo build
+  - cargo test
+  - cargo build --features serde
+  - cargo test --features serde
+after_success: |-
+  [ $TRAVIS_BRANCH = master ] &&
+  [ $TRAVIS_PULL_REQUEST = false ] &&
+  cargo doc &&
+  echo "<meta http-equiv=refresh content=0;url=`echo $TRAVIS_REPO_SLUG | cut -d '/' -f 2`/index.html>" > target/doc/index.html &&
+  sudo pip install ghp-import &&
+  ghp-import -n target/doc &&
+  git push -fq https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages
+env:
+  global:
+    secure: te+DVowxg7YWHJHKRE2eEKEg5lK8IwK4aeKZ6rsDMaTcQFzP+jzSYJiodVuDMXy45sfDMCnkWmVmpfXFI5tCLBSqTDXXOZ0UpE2f4fI0d3inH6McEoXNM43HNZqvEWj6Uc4PzTSzkywcAhg39I08PRbp5zzdj+UhB0Ty++Twwjpipr2KQMNmu9RZEwPtbyjqE69yXkDWy1oM3o51uPnpK0RUH+ZE+B0StTG6CMzVY3gW+kQX96Ow+LYkhgn/YjfubVvKO7QHz8Nd1hOxg78tn1ZTHIazN7p3bJejpsZoU92cNCcx1xM0vV/rXNN1pLxzJOBxNC9tU9FNJAaLsg5kAVGZi8Xvu62nUmkpzki71/nilHBAUxJHGIyv0H52p4DyITEN8NzR5WkqN4qBv814Dpvna1Ua3TPqiYWP/LBb+xM27DuPHKuOifePNWehE84qhQMPgArQyiNCgfKaKbaiFO+J4jiUfEV/1aztuEFyHftLoRYstmHfMkhwYHfSf683QGjlqqoL3SFClp1sKAp8WO5b5ZasT9fOGaqPWi8g28/ZGIu67wocT/hJvXxwozAycsXV36JVHs1ab/ujRYMUbcnObx8E5taKLKhWn2jYWsrJ99bUag7F6wTz1erG0eboScTD8QgVY7Zfvz0Eh1MfePOhEJGZfETR80BypC9fZhY=
diff --git a/crates/generic-array-0.9.0/Cargo.toml b/crates/generic-array-0.9.0/Cargo.toml
new file mode 100644
index 0000000..07c6064
--- /dev/null
+++ b/crates/generic-array-0.9.0/Cargo.toml
@@ -0,0 +1,32 @@
+# 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 = "generic-array"
+version = "0.9.0"
+authors = ["Bartłomiej Kamiński <fizyk20 at gmail.com>"]
+description = "Generic types implementing functionality of arrays"
+documentation = "http://fizyk20.github.io/generic-array/generic_array/"
+license = "MIT"
+repository = "https://github.com/fizyk20/generic-array.git"
+
+[lib]
+name = "generic_array"
+[dependencies.typenum]
+version = "1.9"
+
+[dependencies.serde]
+version = "1.0"
+optional = true
+default-features = false
+[dev-dependencies.serde_json]
+version = "1.0"
diff --git a/crates/generic-array-0.9.0/LICENSE b/crates/generic-array-0.9.0/LICENSE
new file mode 100644
index 0000000..5968bcc
--- /dev/null
+++ b/crates/generic-array-0.9.0/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Bartłomiej Kamiński
+
+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.
\ No newline at end of file
diff --git a/crates/generic-array-0.9.0/README.md b/crates/generic-array-0.9.0/README.md
new file mode 100644
index 0000000..0864ed6
--- /dev/null
+++ b/crates/generic-array-0.9.0/README.md
@@ -0,0 +1,34 @@
+[![Crates.io](https://img.shields.io/crates/v/generic-array.svg)](https://crates.io/crates/generic-array)
+[![Build Status](https://travis-ci.org/fizyk20/generic-array.svg?branch=master)](https://travis-ci.org/fizyk20/generic-array)
+# generic-array
+
+This crate implements generic array types for Rust.
+
+[Documentation](http://fizyk20.github.io/generic-array/generic_array/)
+
+## Usage
+
+The Rust arrays `[T; N]` are problematic in that they can't be used generically with respect to `N`, so for example this won't work:
+
+```rust
+struct Foo<N> {
+	data: [i32; N]
+}
+```
+
+**generic-array** defines a new trait `ArrayLength<T>` and a struct `GenericArray<T, N: ArrayLength<T>>`, which let the above be implemented as:
+
+```rust
+struct Foo<N: ArrayLength<i32>> {
+	data: GenericArray<i32, N>
+}
+```
+
+To actually define a type implementing `ArrayLength`, you can use unsigned integer types defined in [typenum](https://github.com/paholg/typenum) crate - for example, `GenericArray<T, U5>` would work almost like `[T; 5]` :)
+
+In version 0.1.1 an `arr!` macro was introduced, allowing for creation of arrays as shown below:
+
+```rust
+let array = arr![u32; 1, 2, 3];
+assert_eq!(array[2], 3);
+```
diff --git a/crates/generic-array-0.9.0/rustfmt.toml b/crates/generic-array-0.9.0/rustfmt.toml
new file mode 100644
index 0000000..3dc0db2
--- /dev/null
+++ b/crates/generic-array-0.9.0/rustfmt.toml
@@ -0,0 +1,3 @@
+reorder_imports = true
+reorder_imported_names = true
+use_try_shorthand = true
diff --git a/crates/generic-array-0.9.0/src/arr.rs b/crates/generic-array-0.9.0/src/arr.rs
new file mode 100644
index 0000000..51d87f6
--- /dev/null
+++ b/crates/generic-array-0.9.0/src/arr.rs
@@ -0,0 +1,57 @@
+//! Implementation for `arr!` macro.
+
+use super::ArrayLength;
+use core::ops::Add;
+use typenum::U1;
+
+/// Helper trait for `arr!` macro
+pub trait AddLength<T, N: ArrayLength<T>>: ArrayLength<T> {
+    /// Resulting length
+    type Output: ArrayLength<T>;
+}
+
+impl<T, N1, N2> AddLength<T, N2> for N1
+where
+    N1: ArrayLength<T> + Add<N2>,
+    N2: ArrayLength<T>,
+    <N1 as Add<N2>>::Output: ArrayLength<T>,
+{
+    type Output = <N1 as Add<N2>>::Output;
+}
+
+/// Helper type for `arr!` macro
+pub type Inc<T, U> = <U as AddLength<T, U1>>::Output;
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! arr_impl {
+    ($T:ty; $N:ty, [$($x:expr),*], []) => ({
+	unsafe { $crate::transmute::<_, $crate::GenericArray<$T, $N>>([$($x),*]) }
+    });
+    ($T:ty; $N:ty, [], [$x1:expr]) => (
+        arr_impl!($T; $crate::arr::Inc<$T, $N>, [$x1 as $T], [])
+    );
+    ($T:ty; $N:ty, [], [$x1:expr, $($x:expr),+]) => (
+        arr_impl!($T; $crate::arr::Inc<$T, $N>, [$x1 as $T], [$($x),*])
+    );
+    ($T:ty; $N:ty, [$($y:expr),+], [$x1:expr]) => (
+        arr_impl!($T; $crate::arr::Inc<$T, $N>, [$($y),*, $x1 as $T], [])
+    );
+    ($T:ty; $N:ty, [$($y:expr),+], [$x1:expr, $($x:expr),+]) => (
+        arr_impl!($T; $crate::arr::Inc<$T, $N>, [$($y),*, $x1 as $T], [$($x),*])
+    );
+}
+
+/// Macro allowing for easy generation of Generic Arrays.
+/// Example: `let test = arr![u32; 1, 2, 3];`
+#[macro_export]
+macro_rules! arr {
+    ($T:ty;) => ({
+        unsafe { $crate::transmute::<[$T; 0], $crate::GenericArray<$T, $crate::typenum::U0>>([]) }
+    });
+    ($T:ty; $($x:expr),*) => (
+        arr_impl!($T; $crate::typenum::U0, [], [$($x),*])
+    );
+    ($($x:expr,)+) => (arr![$($x),*]);
+    () => ("""Macro requires a type, e.g. `let array = arr![u32; 1, 2, 3];`")
+}
diff --git a/crates/generic-array-0.9.0/src/hex.rs b/crates/generic-array-0.9.0/src/hex.rs
new file mode 100644
index 0000000..1ce5332
--- /dev/null
+++ b/crates/generic-array-0.9.0/src/hex.rs
@@ -0,0 +1,101 @@
+//! Generic array are commonly used as a return value for hash digests, so
+//! it's a good idea to allow to hexlify them easily. This module implements
+//! `std::fmt::LowerHex` and `std::fmt::UpperHex` traits.
+//!
+//! Example:
+//!
+//! ```rust
+//! # #[macro_use]
+//! # extern crate generic_array;
+//! # extern crate typenum;
+//! # fn main() {
+//! let array = arr![u8; 10, 20, 30];
+//! assert_eq!(format!("{:x}", array), "0a141e");
+//! # }
+//! ```
+//!
+
+use {ArrayLength, GenericArray};
+use core::fmt;
+use core::ops::Add;
+use core::str;
+use typenum::*;
+
+static LOWER_CHARS: &'static [u8] = b"0123456789abcdef";
+static UPPER_CHARS: &'static [u8] = b"0123456789ABCDEF";
+
+impl<T: ArrayLength<u8>> fmt::LowerHex for GenericArray<u8, T>
+where
+    T: Add<T>,
+    <T as Add<T>>::Output: ArrayLength<u8>,
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let max_digits = f.precision().unwrap_or_else(|| self.len());
+
+        if T::to_usize() < 1024 {
+            // For small arrays use a stack allocated
+            // buffer of 2x number of bytes
+            let mut res = GenericArray::<u8, Sum<T, T>>::default();
+
+            for (i, c) in self.iter().take(max_digits).enumerate() {
+                res[i * 2] = LOWER_CHARS[(c >> 4) as usize];
+                res[i * 2 + 1] = LOWER_CHARS[(c & 0xF) as usize];
+            }
+            f.write_str(
+                unsafe { str::from_utf8_unchecked(&res[..max_digits * 2]) },
+            )?;
+        } else {
+            // For large array use chunks of up to 1024 bytes (2048 hex chars)
+            let mut buf = [0u8; 2048];
+
+            for chunk in self[..max_digits].chunks(1024) {
+                for (i, c) in chunk.iter().enumerate() {
+                    buf[i * 2] = LOWER_CHARS[(c >> 4) as usize];
+                    buf[i * 2 + 1] = LOWER_CHARS[(c & 0xF) as usize];
+                }
+                f.write_str(unsafe {
+                    str::from_utf8_unchecked(&buf[..chunk.len() * 2])
+                })?;
+            }
+        }
+        Ok(())
+    }
+}
+
+impl<T: ArrayLength<u8>> fmt::UpperHex for GenericArray<u8, T>
+where
+    T: Add<T>,
+    <T as Add<T>>::Output: ArrayLength<u8>,
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let max_digits = f.precision().unwrap_or_else(|| self.len());
+
+        if T::to_usize() < 1024 {
+            // For small arrays use a stack allocated
+            // buffer of 2x number of bytes
+            let mut res = GenericArray::<u8, Sum<T, T>>::default();
+
+            for (i, c) in self.iter().take(max_digits).enumerate() {
+                res[i * 2] = UPPER_CHARS[(c >> 4) as usize];
+                res[i * 2 + 1] = UPPER_CHARS[(c & 0xF) as usize];
+            }
+            f.write_str(
+                unsafe { str::from_utf8_unchecked(&res[..max_digits * 2]) },
+            )?;
+        } else {
+            // For large array use chunks of up to 1024 bytes (2048 hex chars)
+            let mut buf = [0u8; 2048];
+
+            for chunk in self[..max_digits].chunks(1024) {
+                for (i, c) in chunk.iter().enumerate() {
+                    buf[i * 2] = UPPER_CHARS[(c >> 4) as usize];
+                    buf[i * 2 + 1] = UPPER_CHARS[(c & 0xF) as usize];
+                }
+                f.write_str(unsafe {
+                    str::from_utf8_unchecked(&buf[..chunk.len() * 2])
+                })?;
+            }
+        }
+        Ok(())
+    }
+}
diff --git a/crates/generic-array-0.9.0/src/impl_serde.rs b/crates/generic-array-0.9.0/src/impl_serde.rs
new file mode 100644
index 0000000..fd7f490
--- /dev/null
+++ b/crates/generic-array-0.9.0/src/impl_serde.rs
@@ -0,0 +1,68 @@
+//! Serde serialization/deserialization implementation
+
+use {ArrayLength, GenericArray};
+use core::fmt;
+use core::marker::PhantomData;
+use serde::{Deserialize, Deserializer, Serialize, Serializer};
+use serde::de::{self, SeqAccess, Visitor};
+
+impl<T, N> Serialize for GenericArray<T, N>
+where
+    T: Serialize,
+    N: ArrayLength<T>,
+{
+    #[inline]
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        serializer.collect_seq(self.iter())
+    }
+}
+
+struct GAVisitor<T, N> {
+    _t: PhantomData<T>,
+    _n: PhantomData<N>,
+}
+
+impl<'de, T, N> Visitor<'de> for GAVisitor<T, N>
+where
+    T: Deserialize<'de> + Default,
+    N: ArrayLength<T>,
+{
+    type Value = GenericArray<T, N>;
+
+    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        formatter.write_str("struct GenericArray")
+    }
+
+    fn visit_seq<A>(self, mut seq: A) -> Result<GenericArray<T, N>, A::Error>
+    where
+        A: SeqAccess<'de>,
+    {
+        let mut result = GenericArray::default();
+        for i in 0..N::to_usize() {
+            result[i] = seq.next_element()?.ok_or_else(
+                || de::Error::invalid_length(i, &self),
+            )?;
+        }
+        Ok(result)
+    }
+}
+
+impl<'de, T, N> Deserialize<'de> for GenericArray<T, N>
+where
+    T: Deserialize<'de> + Default,
+    N: ArrayLength<T>,
+{
+    fn deserialize<D>(deserializer: D) -> Result<GenericArray<T, N>, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        let visitor = GAVisitor {
+            _t: PhantomData,
+            _n: PhantomData,
+        };
+        deserializer.deserialize_seq(visitor)
+    }
+}
diff --git a/crates/generic-array-0.9.0/src/impls.rs b/crates/generic-array-0.9.0/src/impls.rs
new file mode 100644
index 0000000..3055876
--- /dev/null
+++ b/crates/generic-array-0.9.0/src/impls.rs
@@ -0,0 +1,171 @@
+use super::{ArrayLength, GenericArray};
+use core::borrow::{Borrow, BorrowMut};
+use core::cmp::Ordering;
+use core::fmt::{self, Debug};
+use core::hash::{Hash, Hasher};
+
+impl<T: Default, N> Default for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    #[inline]
+    fn default() -> Self {
+        Self::generate(|_| T::default())
+    }
+}
+
+impl<T: Clone, N> Clone for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    fn clone(&self) -> GenericArray<T, N> {
+        self.map_ref(|x| x.clone())
+    }
+}
+
+impl<T: Copy, N> Copy for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+    N::ArrayType: Copy,
+{
+}
+
+impl<T: PartialEq, N> PartialEq for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    fn eq(&self, other: &Self) -> bool {
+        **self == **other
+    }
+}
+impl<T: Eq, N> Eq for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+}
+
+impl<T: PartialOrd, N> PartialOrd for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    fn partial_cmp(&self, other: &GenericArray<T, N>) -> Option<Ordering> {
+        PartialOrd::partial_cmp(self.as_slice(), other.as_slice())
+    }
+}
+
+impl<T: Ord, N> Ord for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    fn cmp(&self, other: &GenericArray<T, N>) -> Ordering {
+        Ord::cmp(self.as_slice(), other.as_slice())
+    }
+}
+
+impl<T: Debug, N> Debug for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        self[..].fmt(fmt)
+    }
+}
+
+impl<T, N> Borrow<[T]> for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    fn borrow(&self) -> &[T] {
+        &self[..]
+    }
+}
+
+impl<T, N> BorrowMut<[T]> for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    fn borrow_mut(&mut self) -> &mut [T] {
+        &mut self[..]
+    }
+}
+
+impl<T, N> AsRef<[T]> for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    fn as_ref(&self) -> &[T] {
+        &self[..]
+    }
+}
+
+impl<T, N> AsMut<[T]> for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    fn as_mut(&mut self) -> &mut [T] {
+        &mut self[..]
+    }
+}
+
+impl<T: Hash, N> Hash for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    fn hash<H>(&self, state: &mut H)
+    where
+        H: Hasher,
+    {
+        Hash::hash(&self[..], state)
+    }
+}
+
+macro_rules! impl_from {
+    ($($n: expr => $ty: ty),*) => {
+        $(
+            impl<T> From<[T; $n]> for GenericArray<T, $ty> {
+                fn from(arr: [T; $n]) -> Self {
+                    use core::mem::{forget, transmute_copy};
+                    let x = unsafe { transmute_copy(&arr) };
+                    forget(arr);
+                    x
+                }
+            }
+        )*
+
+    }
+}
+
+impl_from! {
+    1  => ::typenum::U1,
+    2  => ::typenum::U2,
+    3  => ::typenum::U3,
+    4  => ::typenum::U4,
+    5  => ::typenum::U5,
+    6  => ::typenum::U6,
+    7  => ::typenum::U7,
+    8  => ::typenum::U8,
+    9  => ::typenum::U9,
+    10 => ::typenum::U10,
+    11 => ::typenum::U11,
+    12 => ::typenum::U12,
+    13 => ::typenum::U13,
+    14 => ::typenum::U14,
+    15 => ::typenum::U15,
+    16 => ::typenum::U16,
+    17 => ::typenum::U17,
+    18 => ::typenum::U18,
+    19 => ::typenum::U19,
+    20 => ::typenum::U20,
+    21 => ::typenum::U21,
+    22 => ::typenum::U22,
+    23 => ::typenum::U23,
+    24 => ::typenum::U24,
+    25 => ::typenum::U25,
+    26 => ::typenum::U26,
+    27 => ::typenum::U27,
+    28 => ::typenum::U28,
+    29 => ::typenum::U29,
+    30 => ::typenum::U30,
+    31 => ::typenum::U31,
+    32 => ::typenum::U32
+}
\ No newline at end of file
diff --git a/crates/generic-array-0.9.0/src/iter.rs b/crates/generic-array-0.9.0/src/iter.rs
new file mode 100644
index 0000000..b928276
--- /dev/null
+++ b/crates/generic-array-0.9.0/src/iter.rs
@@ -0,0 +1,117 @@
+//! `GenericArray` iterator implementation.
+
+use super::{ArrayLength, GenericArray};
+use core::{cmp, ptr};
+use core::mem::ManuallyDrop;
+
+/// An iterator that moves out of a `GenericArray`
+pub struct GenericArrayIter<T, N: ArrayLength<T>> {
+    // Invariants: index <= index_back <= N
+    // Only values in array[index..index_back] are alive at any given time.
+    // Values from array[..index] and array[index_back..] are already moved/dropped.
+    array: ManuallyDrop<GenericArray<T, N>>,
+    index: usize,
+    index_back: usize,
+}
+
+impl<T, N> IntoIterator for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    type Item = T;
+    type IntoIter = GenericArrayIter<T, N>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        GenericArrayIter {
+            array: ManuallyDrop::new(self),
+            index: 0,
+            index_back: N::to_usize(),
+        }
+    }
+}
+
+impl<T, N> Drop for GenericArrayIter<T, N>
+where
+    N: ArrayLength<T>,
+{
+    fn drop(&mut self) {
+        // Drop values that are still alive.
+        for p in &mut self.array[self.index..self.index_back] {
+            unsafe {
+                ptr::drop_in_place(p);
+            }
+        }
+    }
+}
+
+impl<T, N> Iterator for GenericArrayIter<T, N>
+where
+    N: ArrayLength<T>,
+{
+    type Item = T;
+
+    fn next(&mut self) -> Option<T> {
+        if self.len() > 0 {
+            unsafe {
+                let p = self.array.get_unchecked(self.index);
+                self.index += 1;
+                Some(ptr::read(p))
+            }
+        } else {
+            None
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let len = self.len();
+        (len, Some(len))
+    }
+
+    fn count(self) -> usize {
+        self.len()
+    }
+
+    fn nth(&mut self, n: usize) -> Option<T> {
+        // First consume values prior to the nth.
+        let ndrop = cmp::min(n, self.len());
+        for p in &mut self.array[self.index..self.index + ndrop] {
+            self.index += 1;
+            unsafe {
+                ptr::drop_in_place(p);
+            }
+        }
+
+        self.next()
+    }
+
+    fn last(mut self) -> Option<T> {
+        // Note, everything else will correctly drop first as `self` leaves scope.
+        self.next_back()
+    }
+}
+
+impl<T, N> DoubleEndedIterator for GenericArrayIter<T, N>
+where
+    N: ArrayLength<T>,
+{
+    fn next_back(&mut self) -> Option<T> {
+        if self.len() > 0 {
+            self.index_back -= 1;
+            unsafe {
+                let p = self.array.get_unchecked(self.index_back);
+                Some(ptr::read(p))
+            }
+        } else {
+            None
+        }
+    }
+}
+
+impl<T, N> ExactSizeIterator for GenericArrayIter<T, N>
+where
+    N: ArrayLength<T>,
+{
+    fn len(&self) -> usize {
+        self.index_back - self.index
+    }
+}
diff --git a/crates/generic-array-0.9.0/src/lib.rs b/crates/generic-array-0.9.0/src/lib.rs
new file mode 100644
index 0000000..ce478e5
--- /dev/null
+++ b/crates/generic-array-0.9.0/src/lib.rs
@@ -0,0 +1,464 @@
+//! This crate implements a structure that can be used as a generic array type.use
+//! Core Rust array types `[T; N]` can't be used generically with
+//! respect to `N`, so for example this:
+//!
+//! ```{should_fail}
+//! struct Foo<T, N> {
+//!     data: [T; N]
+//! }
+//! ```
+//!
+//! won't work.
+//!
+//! **generic-array** exports a `GenericArray<T,N>` type, which lets
+//! the above be implemented as:
+//!
+//! ```
+//! # use generic_array::{ArrayLength, GenericArray};
+//! struct Foo<T, N: ArrayLength<T>> {
+//!     data: GenericArray<T,N>
+//! }
+//! ```
+//!
+//! The `ArrayLength<T>` trait is implemented by default for
+//! [unsigned integer types](../typenum/uint/index.html) from
+//! [typenum](../typenum/index.html).
+//!
+//! For ease of use, an `arr!` macro is provided - example below:
+//!
+//! ```
+//! # #[macro_use]
+//! # extern crate generic_array;
+//! # extern crate typenum;
+//! # fn main() {
+//! let array = arr![u32; 1, 2, 3];
+//! assert_eq!(array[2], 3);
+//! # }
+//! ```
+
+//#![deny(missing_docs)]
+#![no_std]
+
+pub extern crate typenum;
+#[cfg(feature = "serde")]
+extern crate serde;
+
+mod hex;
+mod impls;
+
+#[cfg(feature = "serde")]
+pub mod impl_serde;
+
+use core::{mem, ptr, slice};
+
+use core::marker::PhantomData;
+use core::mem::ManuallyDrop;
+pub use core::mem::transmute;
+use core::ops::{Deref, DerefMut};
+
+use typenum::bit::{B0, B1};
+use typenum::uint::{UInt, UTerm, Unsigned};
+
+#[cfg_attr(test, macro_use)]
+pub mod arr;
+pub mod iter;
+pub use iter::GenericArrayIter;
+
+/// Trait making `GenericArray` work, marking types to be used as length of an array
+pub unsafe trait ArrayLength<T>: Unsigned {
+    /// Associated type representing the array type for the number
+    type ArrayType;
+}
+
+unsafe impl<T> ArrayLength<T> for UTerm {
+    #[doc(hidden)]
+    type ArrayType = ();
+}
+
+/// Internal type used to generate a struct of appropriate size
+#[allow(dead_code)]
+#[repr(C)]
+#[doc(hidden)]
+pub struct GenericArrayImplEven<T, U> {
+    parent1: U,
+    parent2: U,
+    _marker: PhantomData<T>,
+}
+
+impl<T: Clone, U: Clone> Clone for GenericArrayImplEven<T, U> {
+    fn clone(&self) -> GenericArrayImplEven<T, U> {
+        GenericArrayImplEven {
+            parent1: self.parent1.clone(),
+            parent2: self.parent2.clone(),
+            _marker: PhantomData,
+        }
+    }
+}
+
+impl<T: Copy, U: Copy> Copy for GenericArrayImplEven<T, U> {}
+
+/// Internal type used to generate a struct of appropriate size
+#[allow(dead_code)]
+#[repr(C)]
+#[doc(hidden)]
+pub struct GenericArrayImplOdd<T, U> {
+    parent1: U,
+    parent2: U,
+    data: T,
+}
+
+impl<T: Clone, U: Clone> Clone for GenericArrayImplOdd<T, U> {
+    fn clone(&self) -> GenericArrayImplOdd<T, U> {
+        GenericArrayImplOdd {
+            parent1: self.parent1.clone(),
+            parent2: self.parent2.clone(),
+            data: self.data.clone(),
+        }
+    }
+}
+
+impl<T: Copy, U: Copy> Copy for GenericArrayImplOdd<T, U> {}
+
+unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B0> {
+    #[doc(hidden)]
+    type ArrayType = GenericArrayImplEven<T, N::ArrayType>;
+}
+
+unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B1> {
+    #[doc(hidden)]
+    type ArrayType = GenericArrayImplOdd<T, N::ArrayType>;
+}
+
+/// Struct representing a generic array - `GenericArray<T, N>` works like [T; N]
+#[allow(dead_code)]
+pub struct GenericArray<T, U: ArrayLength<T>> {
+    data: U::ArrayType,
+}
+
+impl<T, N> Deref for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    type Target = [T];
+
+    fn deref(&self) -> &[T] {
+        unsafe { slice::from_raw_parts(self as *const Self as *const T, N::to_usize()) }
+    }
+}
+
+impl<T, N> DerefMut for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    fn deref_mut(&mut self) -> &mut [T] {
+        unsafe { slice::from_raw_parts_mut(self as *mut Self as *mut T, N::to_usize()) }
+    }
+}
+
+struct ArrayBuilder<T, N: ArrayLength<T>> {
+    array: ManuallyDrop<GenericArray<T, N>>,
+    position: usize,
+}
+
+impl<T, N: ArrayLength<T>> ArrayBuilder<T, N> {
+    fn new() -> ArrayBuilder<T, N> {
+        ArrayBuilder {
+            array: ManuallyDrop::new(unsafe { mem::uninitialized() }),
+            position: 0,
+        }
+    }
+
+    fn into_inner(self) -> GenericArray<T, N> {
+        let array = unsafe { ptr::read(&self.array) };
+
+        mem::forget(self);
+
+        ManuallyDrop::into_inner(array)
+    }
+}
+
+impl<T, N: ArrayLength<T>> Drop for ArrayBuilder<T, N> {
+    fn drop(&mut self) {
+        for value in self.array.iter_mut().take(self.position) {
+            unsafe {
+                ptr::drop_in_place(value);
+            }
+        }
+    }
+}
+
+struct ArrayConsumer<T, N: ArrayLength<T>> {
+    array: ManuallyDrop<GenericArray<T, N>>,
+    position: usize,
+}
+
+impl<T, N: ArrayLength<T>> ArrayConsumer<T, N> {
+    fn new(array: GenericArray<T, N>) -> ArrayConsumer<T, N> {
+        ArrayConsumer {
+            array: ManuallyDrop::new(array),
+            position: 0,
+        }
+    }
+}
+
+impl<T, N: ArrayLength<T>> Drop for ArrayConsumer<T, N> {
+    fn drop(&mut self) {
+        for i in self.position..N::to_usize() {
+            unsafe {
+                ptr::drop_in_place(self.array.get_unchecked_mut(i));
+            }
+        }
+    }
+}
+
+impl<T, N> GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    /// Initializes a new `GenericArray` instance using the given function.
+    ///
+    /// If the generator function panics while initializing the array,
+    /// any already initialized elements will be dropped.
+    pub fn generate<F>(f: F) -> GenericArray<T, N>
+    where
+        F: Fn(usize) -> T,
+    {
+        let mut destination = ArrayBuilder::new();
+
+        for (i, dst) in destination.array.iter_mut().enumerate() {
+            unsafe {
+                ptr::write(dst, f(i));
+            }
+
+            destination.position += 1;
+        }
+
+        destination.into_inner()
+    }
+
+    /// Map a function over a slice to a `GenericArray`.
+    ///
+    /// The length of the slice *must* be equal to the length of the array.
+    #[inline]
+    pub fn map_slice<S, F: Fn(&S) -> T>(s: &[S], f: F) -> GenericArray<T, N> {
+        assert_eq!(s.len(), N::to_usize());
+
+        Self::generate(|i| f(unsafe { s.get_unchecked(i) }))
+    }
+
+    /// Maps a `GenericArray` to another `GenericArray`.
+    ///
+    /// If the mapping function panics, any already initialized elements in the new array
+    /// will be dropped, AND any unused elements in the source array will also be dropped.
+    pub fn map<U, F>(self, f: F) -> GenericArray<U, N>
+    where
+        F: Fn(T) -> U,
+        N: ArrayLength<U>,
+    {
+        let mut source = ArrayConsumer::new(self);
+        let mut destination = ArrayBuilder::new();
+
+        for (dst, src) in destination.array.iter_mut().zip(source.array.iter()) {
+            unsafe {
+                ptr::write(dst, f(ptr::read(src)));
+            }
+
+            source.position += 1;
+            destination.position += 1;
+        }
+
+        destination.into_inner()
+    }
+
+    /// Maps a `GenericArray` to another `GenericArray` by reference.
+    ///
+    /// If the mapping function panics, any already initialized elements will be dropped.
+    #[inline]
+    pub fn map_ref<U, F>(&self, f: F) -> GenericArray<U, N>
+    where
+        F: Fn(&T) -> U,
+        N: ArrayLength<U>,
+    {
+        GenericArray::generate(|i| f(unsafe { self.get_unchecked(i) }))
+    }
+
+    /// Combines two `GenericArray` instances and iterates through both of them,
+    /// initializing a new `GenericArray` with the result of the zipped mapping function.
+    ///
+    /// If the mapping function panics, any already initialized elements in the new array
+    /// will be dropped, AND any unused elements in the source arrays will also be dropped.
+    pub fn zip<B, U, F>(self, rhs: GenericArray<B, N>, f: F) -> GenericArray<U, N>
+    where
+        F: Fn(T, B) -> U,
+        N: ArrayLength<B> + ArrayLength<U>,
+    {
+        let mut left = ArrayConsumer::new(self);
+        let mut right = ArrayConsumer::new(rhs);
+
+        let mut destination = ArrayBuilder::new();
+
+        for (dst, (lhs, rhs)) in
+            destination.array.iter_mut().zip(left.array.iter().zip(
+                right.array.iter(),
+            ))
+        {
+            unsafe {
+                ptr::write(dst, f(ptr::read(lhs), ptr::read(rhs)));
+            }
+
+            destination.position += 1;
+            left.position += 1;
+            right.position += 1;
+        }
+
+        destination.into_inner()
+    }
+
+    /// Combines two `GenericArray` instances and iterates through both of them by reference,
+    /// initializing a new `GenericArray` with the result of the zipped mapping function.
+    ///
+    /// If the mapping function panics, any already initialized elements will be dropped.
+    pub fn zip_ref<B, U, F>(&self, rhs: &GenericArray<B, N>, f: F) -> GenericArray<U, N>
+    where
+        F: Fn(&T, &B) -> U,
+        N: ArrayLength<B> + ArrayLength<U>,
+    {
+        GenericArray::generate(|i| unsafe {
+            f(self.get_unchecked(i), rhs.get_unchecked(i))
+        })
+    }
+
+    /// Extracts a slice containing the entire array.
+    #[inline]
+    pub fn as_slice(&self) -> &[T] {
+        self.deref()
+    }
+
+    /// Extracts a mutable slice containing the entire array.
+    #[inline]
+    pub fn as_mut_slice(&mut self) -> &mut [T] {
+        self.deref_mut()
+    }
+
+    /// Converts slice to a generic array reference with inferred length;
+    ///
+    /// Length of the slice must be equal to the length of the array.
+    #[inline]
+    pub fn from_slice(slice: &[T]) -> &GenericArray<T, N> {
+        assert_eq!(slice.len(), N::to_usize());
+
+        unsafe { &*(slice.as_ptr() as *const GenericArray<T, N>) }
+    }
+
+    /// Converts mutable slice to a mutable generic array reference
+    ///
+    /// Length of the slice must be equal to the length of the array.
+    #[inline]
+    pub fn from_mut_slice(slice: &mut [T]) -> &mut GenericArray<T, N> {
+        assert_eq!(slice.len(), N::to_usize());
+
+        unsafe { &mut *(slice.as_mut_ptr() as *mut GenericArray<T, N>) }
+    }
+}
+
+impl<T: Clone, N> GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    /// Construct a `GenericArray` from a slice by cloning its content
+    ///
+    /// Length of the slice must be equal to the length of the array
+    #[inline]
+    pub fn clone_from_slice(list: &[T]) -> GenericArray<T, N> {
+        Self::from_exact_iter(list.iter().cloned()).expect(
+            "Slice must be the same length as the array",
+        )
+    }
+}
+
+impl<T, N> GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    pub fn from_exact_iter<I>(iter: I) -> Option<Self>
+    where
+        I: IntoIterator<Item = T>,
+        <I as IntoIterator>::IntoIter: ExactSizeIterator,
+    {
+        let iter = iter.into_iter();
+
+        if iter.len() == N::to_usize() {
+            let mut destination = ArrayBuilder::new();
+
+            for (dst, src) in destination.array.iter_mut().zip(iter.into_iter()) {
+                unsafe {
+                    ptr::write(dst, src);
+                }
+
+                destination.position += 1;
+            }
+
+            let array = unsafe { ptr::read(&destination.array) };
+
+            mem::forget(destination);
+
+            Some(ManuallyDrop::into_inner(array))
+        } else {
+            None
+        }
+    }
+}
+
+impl<T, N> ::core::iter::FromIterator<T> for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+    T: Default,
+{
+    fn from_iter<I>(iter: I) -> GenericArray<T, N>
+    where
+        I: IntoIterator<Item = T>,
+    {
+        let mut destination = ArrayBuilder::new();
+
+        let defaults = ::core::iter::repeat(()).map(|_| T::default());
+
+        for (dst, src) in destination.array.iter_mut().zip(
+            iter.into_iter().chain(defaults),
+        )
+        {
+            unsafe {
+                ptr::write(dst, src);
+            }
+        }
+
+        destination.into_inner()
+    }
+}
+
+#[cfg(test)]
+mod test {
+    // Compile with:
+    // cargo rustc --lib --profile test --release --
+    //      -C target-cpu=native -C opt-level=3 --emit asm
+    // and view the assembly to make sure test_assembly generates
+    // SIMD instructions instead of a niave loop.
+
+    #[inline(never)]
+    pub fn black_box<T>(val: T) -> T {
+        use core::{mem, ptr};
+
+        let ret = unsafe { ptr::read_volatile(&val) };
+        mem::forget(val);
+        ret
+    }
+
+    #[test]
+    fn test_assembly() {
+        let a = black_box(arr![i32; 1, 3, 5, 7]);
+        let b = black_box(arr![i32; 2, 4, 6, 8]);
+
+        let c = a.zip_ref(&b, |l, r| l + r);
+
+        assert_eq!(c, arr![i32; 3, 7, 11, 15]);
+    }
+}
diff --git a/crates/generic-array-0.9.0/tests/hex.rs b/crates/generic-array-0.9.0/tests/hex.rs
new file mode 100644
index 0000000..aed69e4
--- /dev/null
+++ b/crates/generic-array-0.9.0/tests/hex.rs
@@ -0,0 +1,44 @@
+#[macro_use]
+extern crate generic_array;
+extern crate typenum;
+
+use generic_array::GenericArray;
+use std::str::from_utf8;
+use typenum::U2048;
+
+
+#[test]
+fn short_lower_hex() {
+    let ar = arr![u8; 10, 20, 30];
+    assert_eq!(format!("{:x}", ar), "0a141e");
+}
+
+#[test]
+fn short_upper_hex() {
+    let ar = arr![u8; 30, 20, 10];
+    assert_eq!(format!("{:X}", ar), "1E140A");
+}
+
+#[test]
+fn long_lower_hex() {
+    let ar = GenericArray::<u8, U2048>::default();
+    assert_eq!(format!("{:x}", ar), from_utf8(&[b'0'; 4096]).unwrap());
+}
+
+#[test]
+fn long_upper_hex() {
+    let ar = GenericArray::<u8, U2048>::default();
+    assert_eq!(format!("{:X}", ar), from_utf8(&[b'0'; 4096]).unwrap());
+}
+
+#[test]
+fn truncated_lower_hex() {
+    let ar = arr![u8; 10, 20, 30, 40, 50];
+    assert_eq!(format!("{:.2x}", ar), "0a14");
+}
+
+#[test]
+fn truncated_upper_hex() {
+    let ar = arr![u8; 30, 20, 10, 17, 0];
+    assert_eq!(format!("{:.4X}", ar), "1E140A11");
+}
diff --git a/crates/generic-array-0.9.0/tests/import_name.rs b/crates/generic-array-0.9.0/tests/import_name.rs
new file mode 100644
index 0000000..27653c9
--- /dev/null
+++ b/crates/generic-array-0.9.0/tests/import_name.rs
@@ -0,0 +1,10 @@
+#[macro_use]
+extern crate generic_array as gen_arr;
+
+use gen_arr::typenum;
+
+#[test]
+fn test_different_crate_name() {
+    let _: gen_arr::GenericArray<u32, typenum::U4> = arr![u32; 0, 1, 2, 3];
+    let _: gen_arr::GenericArray<u32, typenum::U0> = arr![u32;];
+}
diff --git a/crates/generic-array-0.9.0/tests/mod.rs b/crates/generic-array-0.9.0/tests/mod.rs
new file mode 100644
index 0000000..2a2f2e1
--- /dev/null
+++ b/crates/generic-array-0.9.0/tests/mod.rs
@@ -0,0 +1,169 @@
+#![recursion_limit="128"]
+#![no_std]
+#[macro_use]
+extern crate generic_array;
+use core::cell::Cell;
+use core::ops::Drop;
+use generic_array::GenericArray;
+use generic_array::typenum::{U1, U3, U4, U97};
+
+#[test]
+fn test() {
+    let mut list97 = [0; 97];
+    for i in 0..97 {
+        list97[i] = i as i32;
+    }
+    let l: GenericArray<i32, U97> = GenericArray::clone_from_slice(&list97);
+    assert_eq!(l[0], 0);
+    assert_eq!(l[1], 1);
+    assert_eq!(l[32], 32);
+    assert_eq!(l[56], 56);
+}
+
+#[test]
+fn test_drop() {
+    #[derive(Clone)]
+    struct TestDrop<'a>(&'a Cell<u32>);
+
+    impl<'a> Drop for TestDrop<'a> {
+        fn drop(&mut self) {
+            self.0.set(self.0.get() + 1);
+        }
+    }
+
+    let drop_counter = Cell::new(0);
+    {
+        let _: GenericArray<TestDrop, U3> =
+            arr![TestDrop; TestDrop(&drop_counter),
+                           TestDrop(&drop_counter),
+                           TestDrop(&drop_counter)];
+    }
+    assert_eq!(drop_counter.get(), 3);
+}
+
+#[test]
+fn test_arr() {
+    let test: GenericArray<u32, U3> = arr![u32; 1, 2, 3];
+    assert_eq!(test[1], 2);
+}
+
+#[test]
+fn test_copy() {
+    let test = arr![u32; 1, 2, 3];
+    let test2 = test;
+    // if GenericArray is not copy, this should fail as a use of a moved value
+    assert_eq!(test[1], 2);
+    assert_eq!(test2[0], 1);
+}
+
+#[test]
+fn test_iter_flat_map() {
+    assert!((0..5).flat_map(|i| arr![i32; 2 * i, 2 * i + 1]).eq(0..10));
+}
+
+#[derive(Debug, PartialEq, Eq)]
+struct NoClone<T>(T);
+
+#[test]
+fn test_from_slice() {
+    let arr = [1, 2, 3, 4];
+    let gen_arr = GenericArray::<_, U3>::from_slice(&arr[..3]);
+    assert_eq!(&arr[..3], gen_arr.as_slice());
+    let arr = [NoClone(1u32), NoClone(2), NoClone(3), NoClone(4)];
+    let gen_arr = GenericArray::<_, U3>::from_slice(&arr[..3]);
+    assert_eq!(&arr[..3], gen_arr.as_slice());
+}
+
+#[test]
+fn test_from_mut_slice() {
+    let mut arr = [1, 2, 3, 4];
+    {
+        let gen_arr = GenericArray::<_, U3>::from_mut_slice(&mut arr[..3]);
+        gen_arr[2] = 10;
+    }
+    assert_eq!(arr, [1, 2, 10, 4]);
+    let mut arr = [NoClone(1u32), NoClone(2), NoClone(3), NoClone(4)];
+    {
+        let gen_arr = GenericArray::<_, U3>::from_mut_slice(&mut arr[..3]);
+        gen_arr[2] = NoClone(10);
+    }
+    assert_eq!(arr, [NoClone(1), NoClone(2), NoClone(10), NoClone(4)]);
+}
+
+#[test]
+fn test_default() {
+    let arr = GenericArray::<u8, U1>::default();
+    assert_eq!(arr[0], 0);
+}
+
+#[test]
+fn test_from() {
+    let data = [(1, 2, 3), (4, 5, 6), (7, 8, 9)];
+    let garray: GenericArray<(usize, usize, usize), U3> = data.into();
+    assert_eq!(&data, garray.as_slice());
+}
+
+#[test]
+fn test_unit_macro() {
+    let arr = arr![f32; 3.14];
+    assert_eq!(arr[0], 3.14);
+}
+
+#[test]
+fn test_empty_macro() {
+    let _arr = arr![f32;];
+}
+
+#[test]
+fn test_cmp() {
+    arr![u8; 0x00].cmp(&arr![u8; 0x00]);
+}
+
+/// This test should cause a helpful compile error if uncommented.
+// #[test]
+// fn test_empty_macro2(){
+//     let arr = arr![];
+// }
+#[cfg(feature = "serde")]
+mod impl_serde {
+    extern crate serde_json;
+
+    use generic_array::GenericArray;
+    use generic_array::typenum::U6;
+
+    #[test]
+    fn test_serde_implementation() {
+        let array: GenericArray<f64, U6> = arr![f64; 0.0, 5.0, 3.0, 7.07192, 76.0, -9.0];
+        let string = serde_json::to_string(&array).unwrap();
+        assert_eq!(string, "[0.0,5.0,3.0,7.07192,76.0,-9.0]");
+
+        let test_array: GenericArray<f64, U6> = serde_json::from_str(&string).unwrap();
+        assert_eq!(test_array, array);
+    }
+}
+
+#[test]
+fn test_map() {
+    let b: GenericArray<i32, U4> = GenericArray::generate(|i| i as i32 * 4).map(|x| x - 3);
+
+    assert_eq!(b, arr![i32; -3, 1, 5, 9]);
+}
+
+#[test]
+fn test_zip() {
+    let a: GenericArray<_, U4> = GenericArray::generate(|i| i + 1);
+    let b: GenericArray<_, U4> = GenericArray::generate(|i| i as i32 * 4);
+
+    let c = a.zip(b, |r, l| r as i32 + l);
+
+    assert_eq!(c, arr![i32; 1, 6, 11, 16]);
+}
+
+#[test]
+fn test_from_iter() {
+    use core::iter::repeat;
+
+    let a: GenericArray<_, U4> = repeat(11).take(3).collect();
+
+    assert_eq!(a, arr![i32; 11, 11, 11, 0]);
+}
diff --git a/crates/typenum-1.9.0/.cargo-checksum.json b/crates/typenum-1.9.0/.cargo-checksum.json
new file mode 100644
index 0000000..a20d55e
--- /dev/null
+++ b/crates/typenum-1.9.0/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{".travis.yml":"978a9c6fe23dd921b9fef8aaaa51f2f9213a09ea4550799624437e3cfbe83fae","CHANGELOG.md":"67dfcd0f0210a552334aaa02cb2e2980a756e18104113aa6c5caf090f02ec100","Cargo.toml":"9ff5180d11639e7b77b6be3c791c19b8f742d52ad29a964b2106fc995fc39a58","LICENSE":"a825bd853ab71619a4923d7b4311221427848070ff44d990da39b0b274c1683f","README.md":"068cae213e6858db4fa1afd8ddb50c10867d0a812c6339bb6eccacc23c54895f","build/main.rs":"69d1cf7e903a07f325a207c7a032ca674844456b5618d0f2285e01f0b29f7e30","build/op.rs":"2a4c77bb83b2230afa5e141f693222732919eeba9fa00f2e165339411e58cffe","build/tests.rs":"ad13e2566a1b7d26d4864797a8eea864810c3b6f52e62791956d42640ea06846","ghp-import/LICENSE":"4cad12a37ce2df808fa1f2ceb356207fd0a007e441f769e43d76b1ff200468e9","ghp-import/MANIFEST.in":"014edf15a68a5ddc0cf29523154d988535979b16e244069e6c9bfd5809a36d7b","ghp-import/Makefile":"66948f41286a924305a77902f16fbba66d9ab6b7be0516e110341b4d3fb80441","ghp-import/README.md":"860b0df1e5710aaead9d958afadbacfe73a28990f5752f5
 9e3e992d3e974565e","ghp-import/docs/build.py":"cc34d0b0bbf4f80d324c06ace177ae8c5117fa7544d306aa8831876ad9e132ae","ghp-import/docs/images/bg_hr.png":"8d8593f4f2eade62591d25e184e5cb6a0d0c6bd18a7cae862b11f1c03aa69489","ghp-import/docs/images/blacktocat.png":"01609f52c83c1bf92878bcc87a15656205dcacbea51d198c72e252a87e256c11","ghp-import/docs/images/icon_download.png":"9e47c3a9c659a46c6eacce7e474ce663aec9baa2d0f0fe08ad895321b7299bab","ghp-import/docs/images/sprite_download.png":"cd25181e43c38322cb01b0a90ba98e7252538939a327c3f22e09f27f01a3a710","ghp-import/docs/index.html.tmpl":"d811ce4dde58cec6ee4bd5ad36836099a4d437b9a82b3a2f73aa3ef2fdfcf8c9","ghp-import/docs/style.css":"492e8ff0f5601af383fe02a1011291e36804bc9a5e41cf5fce66a431081f5789","ghp-import/ghp_import.py":"97e6d4314deb206d63f6a28cfc4e5cf1812429ba53930fc2e844dece7a9e2af3","ghp-import/requirements.txt":"55c0e950d7d4ec76f5d5997efb989906b32f432ba1fc4cb8a3696fcefb3a919a","ghp-import/setup.py":"36d8a3a84ae4ddd1ee70da55719e13e4d4f129d026a
 df70a98dc7f7cac03388c","src/array.rs":"65fa2b482d3025c5d4e827278b8ab85dba45f72f56a30e42f622b0d8e76a15db","src/bit.rs":"6a5c04ee206c982d556c742499e06100d464fd3e9aec1dde091febb740311ff5","src/int.rs":"0e00004a029d96b40931b942bc3b13e91bbd5f1c3fcaf3b58af010eff38ebccc","src/lib.rs":"1a4d13a7557bc09e0340cc87ef702e40badfea492b3cd9cbd36d0dde41b6658d","src/marker_traits.rs":"b118437d58f6bf96d196c09320f39ec2b52c94b31aac9d23ab530bd88c097f43","src/operator_aliases.rs":"ef7b53fafad39e1320f3999da9f241955d11f774dab513db3990ac317e556475","src/private.rs":"bba45b391a7b6c5e2a90460f26ba42549cf575626bb38f1f6df7550565b646c8","src/type_operators.rs":"ae7a9f5950a079010cb0a97588ca027eb67514a15e488be4689a71997c427cf8","src/uint.rs":"3e98ef7de23e8c0dbb48ff997a2974b1afdc25ca097655e35b3b7db0e3b8deed","tests/test.rs":"ed6fa25e8c0850ad3c02f576341754348adc29234a11e9c6dac119405485d73d"},"package":"13a99dc6780ef33c78780b826cf9d2a78840b72cae9474de4bcaf9051e60ebbd"}
\ No newline at end of file
diff --git a/crates/typenum-1.9.0/.travis.yml b/crates/typenum-1.9.0/.travis.yml
new file mode 100644
index 0000000..f6b411b
--- /dev/null
+++ b/crates/typenum-1.9.0/.travis.yml
@@ -0,0 +1,42 @@
+language: rust
+sudo: false
+rust:
+  - stable
+  - nightly
+  - beta
+cache: cargo
+
+notifications:
+  email:
+    recipients: paho at paholg.com
+
+before_script:
+  - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH
+  - export TRAVIS_CARGO_NIGHTLY_FEATURE=""
+  - test -x $HOME/.cargo/bin/rustfmt || cargo install rustfmt # Only install rustfmt if it's not there
+
+script:
+  - |
+    PATH=$PATH:~/.cargo/bin cargo fmt -- --write-mode=diff &&
+    travis-cargo build &&
+    travis-cargo test &&
+    # Note: The "no_std" flag is deprecated and this test remains to make sure we don't break compatibility.
+    travis-cargo --only stable test -- --features "no_std" &&
+    travis-cargo --only nightly test -- --features "clippy" &&
+    travis-cargo --only nightly test -- --features "i128" &&
+    travis-cargo --only stable doc
+
+after_success:
+  - travis-cargo --only stable doc-upload
+  - test $TRAVIS_PULL_REQUEST == "false" &&
+    test $TRAVIS_BRANCH == "master" &&
+    cargo publish --token ${CRATESIO_TOKEN}
+
+env:
+  global:
+    # GitHub SSH stuff
+    - COMMIT_AUTHOR_EMAIL: "paho at paholg.com"
+    # GH_TOKEN
+    - secure: "jEnVq9nswc2mm2A77SEI5C9ytubHrAGpMu9mqF+wr7GoaGee48LjA5OkawY3VHzreB+3djy3LO6h+JUTkKN699KRZt+RvyIBR+yY1C5O+5IwY3k5pZn/Bm4xJZfeGfRwnZ9UYl1iNEAy+yHverMcQC+Lv5wzCSRCmTa18FQpKBeYKsdXfPP1wa+PWbei3bBrO0tBxuiIA5BZUuK8QqYXluUPxKETvJxtdKgFOUbMbf4DDJ4igOrt9OZQQxKrTZWDy+5Hwv4wMh2cir3ExYuM/8dfBewxxGOty1dlZWAUAFsIJ6Ww/mhEAGtsPYjqh3tB5G5JEss2FSvLuYJcKpA9p/mf+K4tagRVF68AydjQISWVBjOarwln2+HzK9tcykfyO8fGIUNgf0ptuZETA95g3BxwKF3O0LvhGJG2QOas8Bjqpdrg3iDoT5QGy2j8DnQLL7HgM31oCvzu1BOqDn3EvRSjwWpmBpXFz/FeUoRdIX1fOZpgw3cYWTpsT/mqW+mUfO98wTHKn3QBOnskLwf9AteTmJwsdx9Kdc4e1a3BqJE/UGNZv16SnVNtun+zMQ3P84HplvCIXL5k2pUDAUpDQne9nxmZ5ADpQJQluDosA5ydtbl+Z6x2o+zGrBOlo1vxoL/x4uuAFYyiwh1DUGyNgN9x2m1A3WtqqzXX5H4XwZ0="
+    # CRATESIO_TOKEN
+    - secure: "cchJKaN5hM2ceBpLqDokhUWFUyFubTlrUxj8d/5JjDXOxVvpZQWQuPxihnSyz0U+GSY4HwUh8C9+jRe2i8UBmhS6pPMG4Bl0Xo2T1HU9ilWb43vSqsbg77UgQ2SELNd+7g1xSI/UTsaFH0YlTOw7DsF6plruVduyOy8C44Ox1nAo4hIgN1ThRs9nhKTWydREr2zRQ/7n4c99RnPQz54ITnrHx/Ks2bvy3zgTOP7CeiQQJKh521U5tuH23r48eljje7776UA4Jbs2j1LsnMaBsraadIzNMopEwaSE1oNLOobfWG9YzvyTZ2i4yElDX4A7tscwo631Ig5AUH2+QbvN2k0q2EKETQJ9Mov5OSmK3aeMSW1GA3hQ44Uvz0F7SZru8D84sKgfSXNbfck1hTVfBPPOpmUIKDb+rSthulYq2SW2XG9cpVXrJmhYD2WTNKEuSmw7imVbTCPS03dbbMoLchpmOBkcgLtcMNDyC94xdZYSkyz9+RCG0bEfwIu9oG7o6gv+8a42pgVSP8mfOOq0+MELHntIqumlmTO0jGGH10Prs4Pgs8eVn6S84w+oz8yrbYroVaqrI2TZl73KnOmvAlnYZdCSIBGV5XsTukzochfwgaTKWI2h2iK1yt6k5I5ZgOoVlTUPB4ElwhIDfgYhc7fltHd53EO81GHGDPSI49M="
diff --git a/crates/typenum-1.9.0/CHANGELOG.md b/crates/typenum-1.9.0/CHANGELOG.md
new file mode 100644
index 0000000..3040713
--- /dev/null
+++ b/crates/typenum-1.9.0/CHANGELOG.md
@@ -0,0 +1,52 @@
+# Changelog
+
+This project follows semantic versioning.
+
+### 1.9.0 (2017-05-14)
+- [added] The `Abs` type operater and corresponding `AbsVal` alias.
+- [added] The feature `i128` that enables creating 128-bit integers from typenums.
+- [added] The `assert_type!` and `assert_type_eq!` macros.
+- [added] Operators to the `op!` macro, including those performed by `cmp!`.
+- [fixed] Bug in `op!` macro involving functions and convoluted expressions.
+- [deprecated] The `cmp!` macro.
+
+### 1.8.0 (2017-04-12)
+- [added] The `op!` macro for conveniently performing type-level operations.
+- [added] The `cmp!` macro for conveniently performing type-level comparisons.
+- [added] Some comparison type-operators that are used by the `cmp!` macro.
+
+### 1.7.0 (2017-03-24)
+- [added] Type operators `Min` and `Max` with accompanying aliases `Minimum` and `Maximum`
+
+### 1.6.0 (2017-02-24)
+- [fixed] Bug in `Array` division.
+- [fixed] Bug where `Rem` would sometimes exit early with the wrong answer.
+- [added] `PartialDiv` operator that performs division as a partial function -- it's defined only
+  when there is no remainder.
+
+### 1.5.2 (2017-02-04)
+- [fixed] Bug between `Div` implementation and type system.
+
+### 1.5.1 (2016-11-08)
+- [fixed] Expanded implementation of `Pow` for primitives.
+
+### 1.5.0 (2016-11-03)
+- [added] Functions to the `Pow` and `Len` traits. This is *technically* a breaking change, but it
+  would only break someone's code if they have a custom impl for `Pow`. I would be very surprised
+  if that is anyone other than me.
+
+### 1.4.0 (2016-10-29)
+- [added] Type-level arrays of type-level integers. (PR #66)
+- [added] The types in this crate are now instantiable. (Issue #67, PR #68)
+
+### 1.3.1 (2016-03-31)
+- [fixed] Bug with recent nightlies.
+
+### 1.3.0 (2016-02-07)
+- [changed] Removed dependency on libstd. (Issue #53, PR #55)
+- [changed] Reorganized module structure. (PR #57)
+
+### 1.2.0 (2016-01-03)
+- [added] This change log!
+- [added] Convenience type aliases for operators. (Issue #48, PR #50)
+- [added] Types in this crate now derive all possible traits. (Issue #42, PR #51)
diff --git a/crates/typenum-1.9.0/Cargo.toml b/crates/typenum-1.9.0/Cargo.toml
new file mode 100644
index 0000000..589901b
--- /dev/null
+++ b/crates/typenum-1.9.0/Cargo.toml
@@ -0,0 +1,24 @@
+[package]
+  name = "typenum"
+  build = "build/main.rs"
+  version = "1.9.0"
+  authors = [
+    "Paho Lurie-Gregg <paho at paholg.com>",
+    "Andre Bogus <bogusandre at gmail.com>"
+  ]
+  documentation = "http://paholg.com/typenum"
+  repository = "https://github.com/paholg/typenum"
+  readme = "README.md"
+  license = "MIT/Apache-2.0"
+  description = "Typenum is a Rust library for type-level numbers evaluated at compile time. It currently supports bits, unsigned integers, and signed integers. It also provides a type-level array of type-level numbers, but its implementation is incomplete."
+  categories = ["no-std"]
+
+[lib]
+  name = "typenum"
+
+[features]
+  no_std = []
+  i128 = []
+
+[dependencies]
+  clippy = { version = "0.0.133", optional = true }
diff --git a/crates/typenum-1.9.0/LICENSE b/crates/typenum-1.9.0/LICENSE
new file mode 100644
index 0000000..e567a4d
--- /dev/null
+++ b/crates/typenum-1.9.0/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Paho Lurie-Gregg
+
+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/crates/typenum-1.9.0/README.md b/crates/typenum-1.9.0/README.md
new file mode 100644
index 0000000..6c66154
--- /dev/null
+++ b/crates/typenum-1.9.0/README.md
@@ -0,0 +1,42 @@
+[![crates.io](https://img.shields.io/crates/v/typenum.svg)](https://crates.io/crates/typenum)
+[![Build Status](https://travis-ci.org/paholg/typenum.svg?branch=master)](https://travis-ci.org/paholg/typenum)
+
+Typenum
+=====
+
+Typenum is a Rust library for type-level numbers evaluated at compile time. It currently
+supports bits, unsigned integers, and signed integers.
+
+Typenum depends only on libcore, and so is suitable for use on any platform!
+
+For the full documentation, go [here](http://paholg.com/typenum).
+
+### Importing
+
+While `typenum` is divided into several modules, they are all re-exported through the crate root,
+so you can import anything contained herein with `use typenum::whatever;`, ignoring the
+crate structure.
+
+You may also find it useful to treat the `consts` module as a prelude, perfoming a glob import.
+
+### Example
+
+Here is a trivial example of `typenum`'s use:
+
+```rust
+use typenum::{Sum, Exp, Integer, N2, P3, P4};
+
+type X = Sum<P3, P4>;
+assert_eq!(<X as Integer>::to_i32(), 7);
+
+type Y = Exp<N2, P3>;
+assert_eq!(<Y as Integer>::to_i32(), -8);
+```
+
+For a non-trivial example of its use, see one of the crates that depends on it. The full
+list is [here](https://crates.io/crates/typenum/reverse_dependencies). Of note are
+[dimensioned](https://crates.io/crates/dimensioned/) which does compile-time type
+checking for arbitrary unit systems and
+[generic-array](https://crates.io/crates/generic-array/) which provides arrays whose
+length you can generically refer to.
+
diff --git a/crates/typenum-1.9.0/build/main.rs b/crates/typenum-1.9.0/build/main.rs
new file mode 100644
index 0000000..8e86e4b
--- /dev/null
+++ b/crates/typenum-1.9.0/build/main.rs
@@ -0,0 +1,177 @@
+use std::env;
+use std::fs::File;
+use std::io::Write;
+use std::path::Path;
+use std::fmt;
+
+mod tests;
+mod op;
+
+pub enum UIntCode {
+    Term,
+    Zero(Box<UIntCode>),
+    One(Box<UIntCode>),
+}
+
+pub enum IntCode {
+    Zero,
+    Pos(Box<UIntCode>),
+    Neg(Box<UIntCode>),
+}
+
+impl fmt::Display for UIntCode {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            UIntCode::Term => write!(f, "UTerm"),
+            UIntCode::Zero(ref inner) => write!(f, "UInt<{}, B0>", inner),
+            UIntCode::One(ref inner) => write!(f, "UInt<{}, B1>", inner),
+        }
+    }
+}
+
+impl fmt::Display for IntCode {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            IntCode::Zero => write!(f, "Z0"),
+            IntCode::Pos(ref inner) => write!(f, "PInt<{}>", inner),
+            IntCode::Neg(ref inner) => write!(f, "NInt<{}>", inner),
+        }
+    }
+}
+
+pub fn gen_uint(u: u64) -> UIntCode {
+    let mut result = UIntCode::Term;
+    let mut x = 1u64 << 63;
+    while x > u {
+        x >>= 1
+    }
+    while x > 0 {
+        result = if x & u > 0 {
+            UIntCode::One(Box::new(result))
+        } else {
+            UIntCode::Zero(Box::new(result))
+        };
+        x >>= 1;
+    }
+    result
+}
+
+pub fn gen_int(i: i64) -> IntCode {
+    if i > 0 {
+        IntCode::Pos(Box::new(gen_uint(i as u64)))
+    } else if i < 0 {
+        IntCode::Neg(Box::new(gen_uint(i.abs() as u64)))
+    } else {
+        IntCode::Zero
+    }
+}
+
+#[cfg_attr(feature="no_std", deprecated(
+    since="1.3.0",
+    note="the `no_std` flag is no longer necessary and will be removed in the future"))]
+pub fn no_std() {}
+
+// fixme: get a warning when testing without this
+#[allow(dead_code)]
+fn main() {
+    let highest: u64 = 1024;
+
+
+    let first2: u32 = (highest as f64).log(2.0) as u32 + 1;
+    let first10: u32 = (highest as f64).log(10.0) as u32 + 1;
+    let uints = (0..(highest + 1))
+        .chain((first2..64).map(|i| 2u64.pow(i)))
+        .chain((first10..20).map(|i| 10u64.pow(i)));
+
+
+    let out_dir = env::var("OUT_DIR").unwrap();
+    let dest = Path::new(&out_dir).join("consts.rs");
+
+    let mut f = File::create(&dest).unwrap();
+
+    no_std();
+
+    // Header stuff here!
+    write!(f,
+           "
+/**
+Type aliases for many constants.
+
+This file is generated by typenum's build script.
+
+For unsigned integers, the format is `U` followed by the number. We define aliases for
+
+- Numbers 0 through {highest}
+- Powers of 2 below `u64::MAX`
+- Powers of 10 below `u64::MAX`
+
+These alias definitions look like this:
+
+```rust
+use typenum::{{B0, B1, UInt, UTerm}};
+
+# #[allow(dead_code)]
+type U6 = UInt<UInt<UInt<UTerm, B1>, B1>, B0>;
+```
+
+For positive signed integers, the format is `P` followed by the number and for negative
+signed integers it is `N` followed by the number. For the signed integer zero, we use
+`Z0`. We define aliases for
+
+- Numbers -{highest} through {highest}
+- Powers of 2 between `i64::MIN` and `i64::MAX`
+- Powers of 10 between `i64::MIN` and `i64::MAX`
+
+These alias definitions look like this:
+
+```rust
+use typenum::{{B0, B1, UInt, UTerm, PInt, NInt}};
+
+# #[allow(dead_code)]
+type P6 = PInt<UInt<UInt<UInt<UTerm, B1>, B1>, B0>>;
+# #[allow(dead_code)]
+type N6 = NInt<UInt<UInt<UInt<UTerm, B1>, B1>, B0>>;
+```
+
+# Example
+```rust
+# #[allow(unused_imports)]
+use typenum::{{U0, U1, U2, U3, U4, U5, U6}};
+# #[allow(unused_imports)]
+use typenum::{{N3, N2, N1, Z0, P1, P2, P3}};
+# #[allow(unused_imports)]
+use typenum::{{U774, N17, N10000, P1024, P4096}};
+```
+
+We also define the aliases `False` and `True` for `B0` and `B1`, respectively.
+*/
+#[allow(missing_docs)]
+pub mod consts {{
+    use uint::{{UInt, UTerm}};
+    use int::{{PInt, NInt}};
+
+    pub use bit::{{B0, B1}};
+    pub use int::Z0;
+
+    pub type True = B1;
+    pub type False = B0;
+",
+           highest = highest)
+            .unwrap();
+
+    for u in uints {
+        write!(f, "    pub type U{} = {};\n", u, gen_uint(u)).unwrap();
+        if u <= ::std::i64::MAX as u64 && u != 0 {
+            let i = u as i64;
+            write!(f,
+                   "    pub type P{i} = PInt<U{i}>; pub type N{i} = NInt<U{i}>;\n",
+                   i = i)
+                    .unwrap();
+        }
+    }
+    write!(f, "}}").unwrap();
+
+    tests::build_tests().unwrap();
+
+    op::write_op_macro().unwrap();
+}
diff --git a/crates/typenum-1.9.0/build/op.rs b/crates/typenum-1.9.0/build/op.rs
new file mode 100644
index 0000000..6fbef9b
--- /dev/null
+++ b/crates/typenum-1.9.0/build/op.rs
@@ -0,0 +1,483 @@
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+enum OpType {
+    Operator,
+    Function,
+}
+
+use self::OpType::*;
+
+struct Op {
+    token: &'static str,
+    operator: &'static str,
+    example: (&'static str, &'static str),
+    precedence: u8,
+    n_args: u8,
+    op_type: OpType,
+}
+
+pub fn write_op_macro() -> ::std::io::Result<()> {
+    let out_dir = ::std::env::var("OUT_DIR").unwrap();
+    let dest = ::std::path::Path::new(&out_dir).join("op.rs");
+    let mut f = ::std::fs::File::create(&dest).unwrap();
+
+    // Operator precedence is taken from
+    // https://doc.rust-lang.org/reference.html#operator-precedence
+    //
+    // We choose 16 as the highest precedence (functions are set to 255 but it doesn't matter
+    // for them).  We also only use operators that are left associative so we don't have to worry
+    // about that.
+    let ops = &[Op {
+                    token: "*",
+                    operator: "Prod",
+                    example: ("P2 * P3", "P6"),
+                    precedence: 16,
+                    n_args: 2,
+                    op_type: Operator,
+                },
+                Op {
+                    token: "/",
+                    operator: "Quot",
+                    example: ("P6 / P2", "P3"),
+                    precedence: 16,
+                    n_args: 2,
+                    op_type: Operator,
+                },
+                Op {
+                    token: "%",
+                    operator: "Mod",
+                    example: ("P5 % P3", "P2"),
+                    precedence: 16,
+                    n_args: 2,
+                    op_type: Operator,
+                },
+                Op {
+                    token: "+",
+                    operator: "Sum",
+                    example: ("P2 + P3", "P5"),
+                    precedence: 15,
+                    n_args: 2,
+                    op_type: Operator,
+                },
+                Op {
+                    token: "-",
+                    operator: "Diff",
+                    example: ("P2 - P3", "N1"),
+                    precedence: 15,
+                    n_args: 2,
+                    op_type: Operator,
+                },
+                Op {
+                    token: "<<",
+                    operator: "Shleft",
+                    example: ("U1 << U5", "U32"),
+                    precedence: 14,
+                    n_args: 2,
+                    op_type: Operator,
+                },
+                Op {
+                    token: ">>",
+                    operator: "Shright",
+                    example: ("U32 >> U5", "U1"),
+                    precedence: 14,
+                    n_args: 2,
+                    op_type: Operator,
+                },
+                Op {
+                    token: "&",
+                    operator: "And",
+                    example: ("U5 & U3", "U1"),
+                    precedence: 13,
+                    n_args: 2,
+                    op_type: Operator,
+                },
+                Op {
+                    token: "^",
+                    operator: "Xor",
+                    example: ("U5 ^ U3", "U6"),
+                    precedence: 12,
+                    n_args: 2,
+                    op_type: Operator,
+                },
+                Op {
+                    token: "|",
+                    operator: "Or",
+                    example: ("U5 | U3", "U7"),
+                    precedence: 11,
+                    n_args: 2,
+                    op_type: Operator,
+                },
+                Op {
+                    token: "==",
+                    operator: "Eq",
+                    example: ("P5 == P3 + P2", "True"),
+                    precedence: 10,
+                    n_args: 2,
+                    op_type: Operator,
+                },
+                Op {
+                    token: "!=",
+                    operator: "NotEq",
+                    example: ("P5 != P3 + P2", "False"),
+                    precedence: 10,
+                    n_args: 2,
+                    op_type: Operator,
+                },
+                Op {
+                    token: "<=",
+                    operator: "LeEq",
+                    example: ("P6 <= P3 + P2", "False"),
+                    precedence: 10,
+                    n_args: 2,
+                    op_type: Operator,
+                },
+                Op {
+                    token: ">=",
+                    operator: "GrEq",
+                    example: ("P6 >= P3 + P2", "True"),
+                    precedence: 10,
+                    n_args: 2,
+                    op_type: Operator,
+                },
+                Op {
+                    token: "<",
+                    operator: "Le",
+                    example: ("P4 < P3 + P2", "True"),
+                    precedence: 10,
+                    n_args: 2,
+                    op_type: Operator,
+                },
+                Op {
+                    token: ">",
+                    operator: "Gr",
+                    example: ("P5 < P3 + P2", "False"),
+                    precedence: 10,
+                    n_args: 2,
+                    op_type: Operator,
+                },
+                Op {
+                    token: "cmp",
+                    operator: "Compare",
+                    example: ("cmp(P2, P3)", "Less"),
+                    precedence: !0,
+                    n_args: 2,
+                    op_type: Function,
+                },
+                Op {
+                    token: "sqr",
+                    operator: "Square",
+                    example: ("sqr(P2)", "P4"),
+                    precedence: !0,
+                    n_args: 1,
+                    op_type: Function,
+                },
+                Op {
+                    token: "abs",
+                    operator: "AbsVal",
+                    example: ("abs(N2)", "P2"),
+                    precedence: !0,
+                    n_args: 1,
+                    op_type: Function,
+                },
+                Op {
+                    token: "cube",
+                    operator: "Cube",
+                    example: ("cube(P2)", "P8"),
+                    precedence: !0,
+                    n_args: 1,
+                    op_type: Function,
+                },
+                Op {
+                    token: "pow",
+                    operator: "Exp",
+                    example: ("pow(P2, P3)", "P8"),
+                    precedence: !0,
+                    n_args: 2,
+                    op_type: Function,
+                },
+                Op {
+                    token: "min",
+                    operator: "Minimum",
+                    example: ("min(P2, P3)", "P2"),
+                    precedence: !0,
+                    n_args: 2,
+                    op_type: Function,
+                },
+                Op {
+                    token: "max",
+                    operator: "Maximum",
+                    example: ("max(P2, P3)", "P3"),
+                    precedence: !0,
+                    n_args: 2,
+                    op_type: Function,
+                }];
+
+    use std::io::Write;
+    write!(f,
+           "
+/**
+Convenient type operations.
+
+Any types representing values must be able to be expressed as `ident`s. That means they need to be
+in scope.
+
+For example, `P5` is okay, but `typenum::P5` is not.
+
+You may combine operators arbitrarily, although doing so excessively may require raising the
+recursion limit.
+
+# Example
+```rust
+#![recursion_limit=\"128\"]
+#[macro_use] extern crate typenum;
+use typenum::consts::*;
+
+fn main() {{
+    assert_type!(
+        op!(min((P1 - P2) * (N3 + N7), P5 * (P3 + P4)) == P10)
+    );
+}}
+```
+Operators are evaluated based on the operator precedence outlined
+[here](https://doc.rust-lang.org/reference.html#operator-precedence).
+
+The full list of supported operators and functions is as follows:
+
+{}
+
+They all expand to type aliases defined in the `operator_aliases` module. Here is an expanded list,
+including examples:
+
+",
+           ops.iter()
+               .map(|op| format!("`{}`", op.token))
+               .collect::<Vec<_>>()
+               .join(", "))?;
+
+    //write!(f, "Token | Alias | Example\n ===|===|===\n")?;
+
+    for op in ops.iter() {
+        write!(f,
+               "---\nOperator `{token}`. Expands to `{operator}`.
+
+```rust
+# #[macro_use] extern crate typenum;
+# use typenum::*;
+# fn main() {{
+assert_type_eq!(op!({ex0}), {ex1});
+# }}
+```\n
+",
+               token = op.token,
+               operator = op.operator,
+               ex0 = op.example.0,
+               ex1 = op.example.1)?;
+    }
+
+    write!(f,
+           "*/
+#[macro_export]
+macro_rules! op {{
+    ($($tail:tt)*) => ( __op_internal__!($($tail)*) );
+}}
+
+    #[doc(hidden)]
+    #[macro_export]
+    macro_rules! __op_internal__ {{
+")?;
+
+    // We first us the shunting-yard algorithm to produce our tokens in Polish notation.
+    // See: https://en.wikipedia.org/wiki/Shunting-yard_algorithm
+
+    // Note: Due to macro asymmetry, "the top of the stack" refers to the first element, not the
+    // last
+
+    // -----------------------------------------------------------------------------------------
+    // Stage 1: There are tokens to be read:
+
+    // -------
+    // Case 1: Token is a function => Push it onto the stack:
+    for fun in ops.iter().filter(|f| f.op_type == Function) {
+        write!(f,
+               "
+(@stack[$($stack:ident,)*] @queue[$($queue:ident,)*] @tail: {f_token} $($tail:tt)*) => (
+    __op_internal__!(@stack[{f_op}, $($stack,)*] @queue[$($queue,)*] @tail: $($tail)*)
+);",
+               f_token = fun.token,
+               f_op = fun.operator)?;
+    }
+
+    // -------
+    // Case 2: Token is a comma => Until the top of the stack is a LParen,
+    //                             Pop operators from stack to queue
+
+    // Base case: Top of stack is LParen, ditch comma and continue
+    write!(f,
+           "
+(@stack[LParen, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail: , $($tail:tt)*) => (
+    __op_internal__!(@stack[LParen, $($stack,)*] @queue[$($queue,)*] @tail: $($tail)*)
+);")?;
+    // Recursive case: Not LParen, pop from stack to queue
+    write!(f,
+           "
+(@stack[$stack_top:ident, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail: , $($tail:tt)*) => (
+    __op_internal__!(@stack[$($stack,)*] @queue[$stack_top, $($queue,)*] @tail: , $($tail)*)
+);")?;
+
+    // -------
+    // Case 3: Token is an operator, o1:
+    for o1 in ops.iter().filter(|op| op.op_type == Operator) {
+        // If top of stack is operator o2 with o1.precedence <= o2.precedence,
+        // Then pop o2 off stack onto queue:
+        for o2 in ops.iter()
+                .filter(|op| op.op_type == Operator)
+                .filter(|o2| o1.precedence <= o2.precedence) {
+            write!(f,
+                   "
+(@stack[{o2_op}, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail: {o1_token} $($tail:tt)*) => (
+    __op_internal__!(@stack[$($stack,)*] @queue[{o2_op}, $($queue,)*] @tail: {o1_token} $($tail)*)
+);",
+                   o2_op = o2.operator,
+                   o1_token = o1.token)?;
+        }
+        // Base case: push o1 onto stack
+        write!(f,
+               "
+(@stack[$($stack:ident,)*] @queue[$($queue:ident,)*] @tail: {o1_token} $($tail:tt)*) => (
+    __op_internal__!(@stack[{o1_op}, $($stack,)*] @queue[$($queue,)*] @tail: $($tail)*)
+);",
+               o1_op = o1.operator,
+               o1_token = o1.token)?;
+    }
+
+    // -------
+    // Case 4: Token is "(": push it onto stack as "LParen". Also convert the ")" to "RParen" to
+    // appease the macro gods:
+    write!(f,
+           "
+(@stack[$($stack:ident,)*] @queue[$($queue:ident,)*] @tail: ( $($stuff:tt)* ) $($tail:tt)* )
+ => (
+    __op_internal__!(@stack[LParen, $($stack,)*] @queue[$($queue,)*]
+                     @tail: $($stuff)* RParen $($tail)*)
+);")?;
+
+    // -------
+    // Case 5: Token is "RParen":
+    //     1. Pop from stack to queue until we see an "LParen",
+    //     2. Kill the "LParen",
+    //     3. If the top of the stack is a function, pop it onto the queue
+    // 2. Base case:
+    write!(f,
+           "
+(@stack[LParen, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail: RParen $($tail:tt)*) => (
+    __op_internal__!(@rp3 @stack[$($stack,)*] @queue[$($queue,)*] @tail: $($tail)*)
+);")?;
+    // 1. Recursive case:
+    write!(f,
+           "
+(@stack[$stack_top:ident, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail: RParen $($tail:tt)*)
+ => (
+    __op_internal__!(@stack[$($stack,)*] @queue[$stack_top, $($queue,)*] @tail: RParen $($tail)*)
+);")?;
+    // 3. Check for function:
+    for fun in ops.iter().filter(|f| f.op_type == Function) {
+        write!(f,
+               "
+(@rp3 @stack[{fun_op}, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail: $($tail:tt)*) => (
+    __op_internal__!(@stack[$($stack,)*] @queue[{fun_op}, $($queue,)*] @tail: $($tail)*)
+);",
+               fun_op = fun.operator)?;
+    }
+    // 3. If no function found:
+    write!(f,
+           "
+(@rp3 @stack[$($stack:ident,)*] @queue[$($queue:ident,)*] @tail: $($tail:tt)*) => (
+    __op_internal__!(@stack[$($stack,)*] @queue[$($queue,)*] @tail: $($tail)*)
+);")?;
+
+    // -------
+    // Case 6: Token is a number: Push it onto the queue
+    write!(f,
+           "
+(@stack[$($stack:ident,)*] @queue[$($queue:ident,)*] @tail: $num:ident $($tail:tt)*) => (
+    __op_internal__!(@stack[$($stack,)*] @queue[$num, $($queue,)*] @tail: $($tail)*)
+);")?;
+
+    // -------
+    // Case 7: Out of tokens:
+    // Base case: Stack empty: Start evaluating
+    write!(f,
+           "
+(@stack[] @queue[$($queue:ident,)*] @tail: ) => (
+    __op_internal__!(@reverse[] @input: $($queue,)*)
+);")?;
+    // Recursive case: Pop stack to queue
+    write!(f,
+           "
+(@stack[$stack_top:ident, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail:) => (
+    __op_internal__!(@stack[$($stack,)*] @queue[$stack_top, $($queue,)*] @tail: )
+);")?;
+
+    // -----------------------------------------------------------------------------------------
+    // Stage 2: Reverse so we have RPN
+    write!(f,
+           "
+(@reverse[$($revved:ident,)*] @input: $head:ident, $($tail:ident,)* ) => (
+    __op_internal__!(@reverse[$head, $($revved,)*] @input: $($tail,)*)
+);")?;
+    write!(f,
+           "
+(@reverse[$($revved:ident,)*] @input: ) => (
+    __op_internal__!(@eval @stack[] @input[$($revved,)*])
+);")?;
+
+    // -----------------------------------------------------------------------------------------
+    // Stage 3: Evaluate in Reverse Polish Notation
+    // Operators / Operators with 2 args:
+    for op in ops.iter().filter(|op| op.n_args == 2) {
+        // Note: We have to switch $a and $b here, otherwise non-commutative functions are backwards
+        write!(f,
+               "
+(@eval @stack[$a:ty, $b:ty, $($stack:ty,)*] @input[{op}, $($tail:ident,)*]) => (
+    __op_internal__!(@eval @stack[$crate::{op}<$b, $a>, $($stack,)*] @input[$($tail,)*])
+);",
+               op = op.operator)?;
+    }
+    // Operators with 1 arg:
+    for op in ops.iter().filter(|op| op.n_args == 1) {
+        write!(f,
+               "
+(@eval @stack[$a:ty, $($stack:ty,)*] @input[{op}, $($tail:ident,)*]) => (
+    __op_internal__!(@eval @stack[$crate::{op}<$a>, $($stack,)*] @input[$($tail,)*])
+);",
+               op = op.operator)?;
+    }
+
+    // Wasn't a function or operator, so must be a value => push onto stack
+    write!(f,
+           "
+(@eval @stack[$($stack:ty,)*] @input[$head:ident, $($tail:ident,)*]) => (
+    __op_internal__!(@eval @stack[$head, $($stack,)*] @input[$($tail,)*])
+);")?;
+
+    // No input left:
+    write!(f,
+           "
+(@eval @stack[$stack:ty,] @input[]) => (
+    $stack
+);")?;
+
+    // -----------------------------------------------------------------------------------------
+    // Stage 0: Get it started
+    write!(f,
+           "
+($($tail:tt)* ) => (
+    __op_internal__!(@stack[] @queue[] @tail: $($tail)*)
+);")?;
+
+
+    write!(f,
+           "
+}}")?;
+
+    Ok(())
+}
diff --git a/crates/typenum-1.9.0/build/tests.rs b/crates/typenum-1.9.0/build/tests.rs
new file mode 100644
index 0000000..7c46037
--- /dev/null
+++ b/crates/typenum-1.9.0/build/tests.rs
@@ -0,0 +1,293 @@
+use std::{env, fs, io, fmt, path};
+
+use super::{gen_int, gen_uint};
+
+fn sign(i: i64) -> char {
+    if i > 0 {
+        'P'
+    } else if i < 0 {
+        'N'
+    } else {
+        '_'
+    }
+}
+
+struct UIntTest {
+    a: u64,
+    op: &'static str,
+    b: Option<u64>,
+    r: u64,
+}
+
+impl fmt::Display for UIntTest {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match self.b {
+            Some(b) => {
+                write!(f,
+                       "
+#[test]
+#[allow(non_snake_case)]
+fn test_{a}_{op}_{b}() {{
+    type A = {gen_a};
+    type B = {gen_b};
+    type U{r} = {result};
+
+    #[allow(non_camel_case_types)]
+    type U{a}{op}U{b} = <<A as {op}<B>>::Output as Same<U{r}>>::Output;
+
+    assert_eq!(<U{a}{op}U{b} as Unsigned>::to_u64(), <U{r} as Unsigned>::to_u64());
+}}",
+                       gen_a = gen_uint(self.a),
+                       gen_b = gen_uint(b),
+                       r = self.r,
+                       result = gen_uint(self.r),
+                       a = self.a,
+                       b = b,
+                       op = self.op)
+            }
+            None => {
+                write!(f,
+                       "
+#[test]
+#[allow(non_snake_case)]
+fn test_{a}_{op}() {{
+    type A = {gen_a};
+    type U{r} = {result};
+
+    #[allow(non_camel_case_types)]
+    type {op}U{a} = <<A as {op}>::Output as Same<U{r}>>::Output;
+    assert_eq!(<{op}U{a} as Unsigned>::to_u64(), <U{r} as Unsigned>::to_u64());
+}}",
+                       gen_a = gen_uint(self.a),
+                       r = self.r,
+                       result = gen_uint(self.r),
+                       a = self.a,
+                       op = self.op)
+            }
+        }
+    }
+}
+
+fn uint_binary_test(a: u64, op: &'static str, b: u64, result: u64) -> UIntTest {
+    UIntTest {
+        a: a,
+        op: op,
+        b: Option::Some(b),
+        r: result,
+    }
+}
+
+// fn uint_unary_test(op: &'static str, a: u64, result: u64) -> UIntTest {
+//     UIntTest { a: a, op: op, b: Option::None, r: result }
+// }
+
+struct IntBinaryTest {
+    a: i64,
+    op: &'static str,
+    b: i64,
+    r: i64,
+}
+
+impl fmt::Display for IntBinaryTest {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f,
+               "
+#[test]
+#[allow(non_snake_case)]
+fn test_{sa}{a}_{op}_{sb}{b}() {{
+    type A = {gen_a};
+    type B = {gen_b};
+    type {sr}{r} = {result};
+
+    #[allow(non_camel_case_types)]
+    type {sa}{a}{op}{sb}{b} = <<A as {op}<B>>::Output as Same<{sr}{r}>>::Output;
+
+    assert_eq!(<{sa}{a}{op}{sb}{b} as Integer>::to_i64(), <{sr}{r} as Integer>::to_i64());
+}}",
+               gen_a = gen_int(self.a),
+               gen_b = gen_int(self.b),
+               r = self.r.abs(),
+               sr = sign(self.r),
+               result = gen_int(self.r),
+               a = self.a.abs(),
+               b = self.b.abs(),
+               sa = sign(self.a),
+               sb = sign(self.b),
+               op = self.op)
+    }
+}
+
+fn int_binary_test(a: i64, op: &'static str, b: i64, result: i64) -> IntBinaryTest {
+    IntBinaryTest {
+        a: a,
+        op: op,
+        b: b,
+        r: result,
+    }
+}
+
+struct IntUnaryTest {
+    op: &'static str,
+    a: i64,
+    r: i64,
+}
+
+impl fmt::Display for IntUnaryTest {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f,
+               "
+#[test]
+#[allow(non_snake_case)]
+fn test_{sa}{a}_{op}() {{
+    type A = {gen_a};
+    type {sr}{r} = {result};
+
+    #[allow(non_camel_case_types)]
+    type {op}{sa}{a} = <<A as {op}>::Output as Same<{sr}{r}>>::Output;
+    assert_eq!(<{op}{sa}{a} as Integer>::to_i64(), <{sr}{r} as Integer>::to_i64());
+}}",
+               gen_a = gen_int(self.a),
+               r = self.r.abs(),
+               sr = sign(self.r),
+               result = gen_int(self.r),
+               a = self.a.abs(),
+               sa = sign(self.a),
+               op = self.op)
+    }
+}
+
+fn int_unary_test(op: &'static str, a: i64, result: i64) -> IntUnaryTest {
+    IntUnaryTest {
+        op: op,
+        a: a,
+        r: result,
+    }
+}
+
+fn uint_cmp_test(a: u64, b: u64) -> String {
+    format!("
+#[test]
+#[allow(non_snake_case)]
+fn test_{a}_cmp_{b}() {{
+    type A = {gen_a};
+    type B = {gen_b};
+
+    #[allow(non_camel_case_types)]
+    type U{a}CmpU{b} = <A as Cmp<B>>::Output;
+    assert_eq!(<U{a}CmpU{b} as Ord>::to_ordering(), Ordering::{result:?});
+}}",
+            a = a,
+            b = b,
+            gen_a = gen_uint(a),
+            gen_b = gen_uint(b),
+            result = a.cmp(&b))
+}
+
+fn int_cmp_test(a: i64, b: i64) -> String {
+    format!("
+#[test]
+#[allow(non_snake_case)]
+fn test_{sa}{a}_cmp_{sb}{b}() {{
+    type A = {gen_a};
+    type B = {gen_b};
+
+    #[allow(non_camel_case_types)]
+    type {sa}{a}Cmp{sb}{b} = <A as Cmp<B>>::Output;
+    assert_eq!(<{sa}{a}Cmp{sb}{b} as Ord>::to_ordering(), Ordering::{result:?});
+}}",
+            a = a.abs(),
+            b = b.abs(),
+            sa = sign(a),
+            sb = sign(b),
+            gen_a = gen_int(a),
+            gen_b = gen_int(b),
+            result = a.cmp(&b))
+}
+
+pub fn build_tests() -> Result<(), Box<::std::error::Error>> {
+    // will test all permutations of number pairs up to this (and down to its opposite for ints)
+    let high: i64 = 5;
+
+    let uints = (0u64..high as u64 + 1).flat_map(|a| (a..a + 1).cycle().zip((0..high as u64 + 1)));
+    let ints = (-high..high + 1).flat_map(|a| (a..a + 1).cycle().zip((-high..high + 1)));
+
+
+    let out_dir = env::var("OUT_DIR")?;
+    let dest = path::Path::new(&out_dir).join("tests.rs");
+    let f = fs::File::create(&dest)?;
+    let mut writer = io::BufWriter::new(&f);
+    use std::io::Write;
+    writer
+        .write(b"
+extern crate typenum;
+
+use std::ops::*;
+use std::cmp::Ordering;
+use typenum::*;
+")?;
+    use std::cmp;
+    // uint operators:
+    for (a, b) in uints {
+        write!(writer, "{}", uint_binary_test(a, "BitAnd", b, a & b))?;
+        write!(writer, "{}", uint_binary_test(a, "BitOr", b, a | b))?;
+        write!(writer, "{}", uint_binary_test(a, "BitXor", b, a ^ b))?;
+        write!(writer, "{}", uint_binary_test(a, "Shl", b, a << b))?;
+        write!(writer, "{}", uint_binary_test(a, "Shr", b, a >> b))?;
+        write!(writer, "{}", uint_binary_test(a, "Add", b, a + b))?;
+        write!(writer, "{}", uint_binary_test(a, "Min", b, cmp::min(a, b)))?;
+        write!(writer, "{}", uint_binary_test(a, "Max", b, cmp::max(a, b)))?;
+        if a >= b {
+            write!(writer, "{}", uint_binary_test(a, "Sub", b, a - b))?;
+        }
+        write!(writer, "{}", uint_binary_test(a, "Mul", b, a * b))?;
+        if b != 0 {
+            write!(writer, "{}", uint_binary_test(a, "Div", b, a / b))?;
+            write!(writer, "{}", uint_binary_test(a, "Rem", b, a % b))?;
+            if a % b == 0 {
+                write!(writer, "{}", uint_binary_test(a, "PartialDiv", b, a / b))?;
+            }
+        }
+        write!(writer, "{}", uint_binary_test(a, "Pow", b, a.pow(b as u32)))?;
+        write!(writer, "{}", uint_cmp_test(a, b))?;
+    }
+    // int operators:
+    for (a, b) in ints {
+        write!(writer, "{}", int_binary_test(a, "Add", b, a + b))?;
+        write!(writer, "{}", int_binary_test(a, "Sub", b, a - b))?;
+        write!(writer, "{}", int_binary_test(a, "Mul", b, a * b))?;
+        write!(writer, "{}", int_binary_test(a, "Min", b, cmp::min(a, b)))?;
+        write!(writer, "{}", int_binary_test(a, "Max", b, cmp::max(a, b)))?;
+        if b != 0 {
+            write!(writer, "{}", int_binary_test(a, "Div", b, a / b))?;
+            write!(writer, "{}", int_binary_test(a, "Rem", b, a % b))?;
+            if a % b == 0 {
+                write!(writer, "{}", int_binary_test(a, "PartialDiv", b, a / b))?;
+            }
+        }
+        if b >= 0 || a.abs() == 1 {
+            let result = if b < 0 {
+                if a == 1 {
+                    a
+                } else if a == -1 {
+                    a.pow((-b) as u32)
+                } else {
+                    unreachable!()
+                }
+            } else {
+                a.pow(b as u32)
+            };
+            write!(writer, "{}", int_binary_test(a, "Pow", b, result))?;
+        }
+        write!(writer, "{}", int_cmp_test(a, b))?;
+    }
+
+    // int unary operators:
+    for n in -high..high + 1 {
+        write!(writer, "{}", int_unary_test("Neg", n, -n))?;
+        write!(writer, "{}", int_unary_test("Abs", n, n.abs()))?;
+    }
+
+    writer.flush()?;
+
+    Ok(())
+}
diff --git a/crates/typenum-1.9.0/ghp-import/LICENSE b/crates/typenum-1.9.0/ghp-import/LICENSE
new file mode 100644
index 0000000..e7f63f0
--- /dev/null
+++ b/crates/typenum-1.9.0/ghp-import/LICENSE
@@ -0,0 +1,11 @@
+                           Tumbolia Public License
+
+Copyright 2013, Paul Davis <paul.joseph.davis at gmail.com>
+
+Copying and distribution of this file, with or without modification, are
+permitted in any medium without royalty provided the copyright notice and this
+notice are preserved.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. opan saurce LOL
diff --git a/crates/typenum-1.9.0/ghp-import/MANIFEST.in b/crates/typenum-1.9.0/ghp-import/MANIFEST.in
new file mode 100644
index 0000000..c1a7121
--- /dev/null
+++ b/crates/typenum-1.9.0/ghp-import/MANIFEST.in
@@ -0,0 +1,2 @@
+include LICENSE
+include README.md
diff --git a/crates/typenum-1.9.0/ghp-import/Makefile b/crates/typenum-1.9.0/ghp-import/Makefile
new file mode 100644
index 0000000..9e035e0
--- /dev/null
+++ b/crates/typenum-1.9.0/ghp-import/Makefile
@@ -0,0 +1,8 @@
+
+docs:
+	pyflakes ./ghp_import.py
+	./docs/build.py > docs/index.html
+	./ghp_import.py -p docs/
+
+
+.PHONY: docs
diff --git a/crates/typenum-1.9.0/ghp-import/README.md b/crates/typenum-1.9.0/ghp-import/README.md
new file mode 100644
index 0000000..c1f0f31
--- /dev/null
+++ b/crates/typenum-1.9.0/ghp-import/README.md
@@ -0,0 +1,78 @@
+GitHub Pages Import
+===================
+
+As part of [gunicorn][gunicorn], [Benoit Chesneau][benoit] and I have been
+starting to look at how to host documentation. There's the obvious method of
+using [GitHub's post-receive hook][github-post] to trigger doc builds and rsync
+to a webserver, but we ended up wanting to try out github's hosting to make the
+whole interface a bit more robust.
+
+[GitHub Pages][gh-pages] is a pretty awesome service that GitHub provides for
+hosting project documentation. The only thing is that it requires a
+`gh-pages` branch that is the site's document root. This means that keeping
+documentation sources in the branch with code is a bit difficult. And it really
+turns into a head scratcher for things like [Sphinx][sphinx] that want to
+access documentation sources and code sources at the same time.
+
+Then I stumbled across an interesting looking package called
+[github-tools][github-tools] that looked almost like what I wanted. It was a tad
+complicated and more involved than I wanted but it gave me an idear. Why not
+just write a script that can copy a directory to the `gh-pages` branch of the
+repository. This saves me from even having to think about the branch and
+everything becomes magical.
+
+This is what `ghp-import` was written for.
+
+[gunicorn]: http://www.gunicorn.com/ "Gunicorn"
+[benoit]: http://github.com/benoitc "Benoît Chesneau"
+[github-post]: https://help.github.com/articles/post-receive-hooks "GitHub Post-Receive Hook"
+[gh-pages]: http://pages.github.com/ "GitHub Pages"
+[sphinx]: http://sphinx.pocoo.org/ "Sphinx Documentation"
+[github-tools]: http://dinoboff.github.com/github-tools/ "github-tools"
+
+
+Big Fat Warning
+---------------
+
+This will **DESTROY** your `gh-pages` branch. If you love it, you'll want to
+take backups before playing with this. This script assumes that `gh-pages` is
+100% derivative. You should never edit files in your `gh-pages` branch by hand
+if you're using this script because you will lose your work.
+
+Usage
+-----
+
+    Usage: ghp-import [OPTIONS] DIRECTORY
+
+	Options:
+	  -n          Include a .nojekyll file in the branch.
+	  -c CNAME    Write a CNAME file with the given CNAME.
+	  -m MESG     The commit message to use on the target branch.
+	  -p          Push the branch to origin/{branch} after committing.
+	  -f          Force the push to the repository
+	  -r REMOTE   The name of the remote to push to. [origin]
+	  -b BRANCH   Name of the branch to write to. [gh-pages]
+	  -s          Use the shell when invoking Git. [False]
+	  -l          Follow symlinks when adding files. [False]
+	  -h, --help  show this help message and exit
+
+Its pretty simple. Inside your repository just run `ghp-import $DOCS_DIR`
+where `$DOCS_DIR` is the path to the **built** documentation. This will write a
+commit to your `gh-pages` branch with the current documents in it.
+
+If you specify `-p` it will also attempt to push the `gh-pages` branch to
+GitHub. By default it'll just run `git push origin gh-pages`. You can specify
+a different remote using the `-r` flag.
+
+You can specify a different branch with `-b`. This is useful for user and
+organization page, which are served from the `master` branch.
+
+Some Windows users report needing to pass Git commands through the shell which can be accomplished by passing `-s`.
+
+The `-l` option will cause the import to follow symlinks for users that have odd configurations that include symlinking outside of their documentation directory.
+
+License
+-------
+
+`ghp-import` is distributed under the Tumbolia Public License. See the LICENSE
+file for more information.
diff --git a/crates/typenum-1.9.0/ghp-import/docs/build.py b/crates/typenum-1.9.0/ghp-import/docs/build.py
new file mode 100755
index 0000000..ab0bbb7
--- /dev/null
+++ b/crates/typenum-1.9.0/ghp-import/docs/build.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+
+import os
+import StringIO
+
+import markdown
+
+
+def main():
+    base = os.path.abspath(os.path.dirname(__file__))
+    index = os.path.join(base, "index.html.tmpl")
+    readme = os.path.join(os.path.dirname(base), "README.md")
+
+    templ = open(index).read()
+
+    buf = StringIO.StringIO("rw")
+    markdown.markdownFromFile(input=readme, output=buf)
+
+    print templ.format(body=buf.getvalue())
+
+if __name__ == '__main__':
+    main()
diff --git a/crates/typenum-1.9.0/ghp-import/docs/images/bg_hr.png b/crates/typenum-1.9.0/ghp-import/docs/images/bg_hr.png
new file mode 100644
index 0000000..7973bd6
Binary files /dev/null and b/crates/typenum-1.9.0/ghp-import/docs/images/bg_hr.png differ
diff --git a/crates/typenum-1.9.0/ghp-import/docs/images/blacktocat.png b/crates/typenum-1.9.0/ghp-import/docs/images/blacktocat.png
new file mode 100644
index 0000000..6e264fe
Binary files /dev/null and b/crates/typenum-1.9.0/ghp-import/docs/images/blacktocat.png differ
diff --git a/crates/typenum-1.9.0/ghp-import/docs/images/icon_download.png b/crates/typenum-1.9.0/ghp-import/docs/images/icon_download.png
new file mode 100644
index 0000000..a2a287f
Binary files /dev/null and b/crates/typenum-1.9.0/ghp-import/docs/images/icon_download.png differ
diff --git a/crates/typenum-1.9.0/ghp-import/docs/images/sprite_download.png b/crates/typenum-1.9.0/ghp-import/docs/images/sprite_download.png
new file mode 100644
index 0000000..f2babd5
Binary files /dev/null and b/crates/typenum-1.9.0/ghp-import/docs/images/sprite_download.png differ
diff --git a/crates/typenum-1.9.0/ghp-import/docs/index.html.tmpl b/crates/typenum-1.9.0/ghp-import/docs/index.html.tmpl
new file mode 100644
index 0000000..0027767
--- /dev/null
+++ b/crates/typenum-1.9.0/ghp-import/docs/index.html.tmpl
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset='utf-8' />
+    <meta http-equiv="X-UA-Compatible" content="chrome=1" />
+    <meta name="description" content="ghp-import : Easily import docs to your gh-pages branch." />
+    <link rel="stylesheet" type="text/css" media="screen" href="style.css">
+
+    <title>ghp-import - GitHub Pages import tool</title>
+  </head>
+  <body>
+
+    <!-- HEADER -->
+    <div id="header_wrap" class="outer">
+        <header class="inner">
+          <a id="forkme_banner" href="https://github.com/davisp/ghp-import">View on GitHub</a>
+
+          <h1 id="project_title">ghp-import</h1>
+          <h2 id="project_tagline">Easily import docs to your gh-pages branch.</h2>
+            <section id="downloads">
+              <a class="zip_download_link" href="https://github.com/davisp/ghp-import/zipball/master">Download this project as a .zip file</a>
+              <a class="tar_download_link" href="https://github.com/davisp/ghp-import/tarball/master">Download this project as a tar.gz file</a>
+            </section>
+        </header>
+    </div>
+
+    <!-- MAIN CONTENT -->
+    <div id="main_content_wrap" class="outer">
+      <section id="main_content" class="inner">
+      {body}
+      </section>
+    </div>
+
+    <!-- FOOTER  -->
+    <div id="footer_wrap" class="outer">
+      <footer class="inner">
+        <p class="copyright">ghp-import maintained by <a href="https://github.com/davisp">davisp</a></p>
+        <p>Published with <a href="http://pages.github.com">GitHub Pages</a></p>
+      </footer>
+    </div>
+  </body>
+</html>
diff --git a/crates/typenum-1.9.0/ghp-import/docs/style.css b/crates/typenum-1.9.0/ghp-import/docs/style.css
new file mode 100644
index 0000000..2bd468a
--- /dev/null
+++ b/crates/typenum-1.9.0/ghp-import/docs/style.css
@@ -0,0 +1,431 @@
+/*******************************************************************************
+Slate Theme for GitHub Pages
+by Jason Costello, @jsncostello
+*******************************************************************************/
+
+ at import url(pygment_trac.css);
+
+/*******************************************************************************
+MeyerWeb Reset
+*******************************************************************************/
+
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed,
+figure, figcaption, footer, header, hgroup,
+menu, nav, output, ruby, section, summary,
+time, mark, audio, video {
+  margin: 0;
+  padding: 0;
+  border: 0;
+  font: inherit;
+  vertical-align: baseline;
+}
+
+/* HTML5 display-role reset for older browsers */
+article, aside, details, figcaption, figure,
+footer, header, hgroup, menu, nav, section {
+  display: block;
+}
+
+ol, ul {
+  list-style: none;
+}
+
+blockquote, q {
+}
+
+table {
+  border-collapse: collapse;
+  border-spacing: 0;
+}
+
+a:focus {
+  outline: none;
+}
+
+/*******************************************************************************
+Theme Styles
+*******************************************************************************/
+
+body {
+  box-sizing: border-box;
+  color:#373737;
+  background: #212121;
+  font-size: 16px;
+  font-family: 'Myriad Pro', Calibri, Helvetica, Arial, sans-serif;
+  line-height: 1.5;
+  -webkit-font-smoothing: antialiased;
+}
+
+h1, h2, h3, h4, h5, h6 {
+  margin: 10px 0;
+  font-weight: 700;
+  color:#222222;
+  font-family: 'Lucida Grande', 'Calibri', Helvetica, Arial, sans-serif;
+  letter-spacing: -1px;
+}
+
+h1 {
+  font-size: 36px;
+  font-weight: 700;
+}
+
+h2 {
+  padding-bottom: 10px;
+  font-size: 32px;
+  background: url('../images/bg_hr.png') repeat-x bottom;
+}
+
+h3 {
+  font-size: 24px;
+}
+
+h4 {
+  font-size: 21px;
+}
+
+h5 {
+  font-size: 18px;
+}
+
+h6 {
+  font-size: 16px;
+}
+
+p {
+  margin: 10px 0 15px 0;
+}
+
+footer p {
+  color: #f2f2f2;
+}
+
+a {
+  text-decoration: none;
+  color: #007edf;
+  text-shadow: none;
+
+  transition: color 0.5s ease;
+  transition: text-shadow 0.5s ease;
+  -webkit-transition: color 0.5s ease;
+  -webkit-transition: text-shadow 0.5s ease;
+  -moz-transition: color 0.5s ease;
+  -moz-transition: text-shadow 0.5s ease;
+  -o-transition: color 0.5s ease;
+  -o-transition: text-shadow 0.5s ease;
+  -ms-transition: color 0.5s ease;
+  -ms-transition: text-shadow 0.5s ease;
+}
+
+#main_content a:hover {
+  color: #0069ba;
+  text-shadow: #0090ff 0px 0px 2px;
+}
+
+footer a:hover {
+  color: #43adff;
+  text-shadow: #0090ff 0px 0px 2px;
+}
+
+em {
+  font-style: italic;
+}
+
+strong {
+  font-weight: bold;
+}
+
+img {
+  position: relative;
+  margin: 0 auto;
+  max-width: 739px;
+  padding: 5px;
+  margin: 10px 0 10px 0;
+  border: 1px solid #ebebeb;
+
+  box-shadow: 0 0 5px #ebebeb;
+  -webkit-box-shadow: 0 0 5px #ebebeb;
+  -moz-box-shadow: 0 0 5px #ebebeb;
+  -o-box-shadow: 0 0 5px #ebebeb;
+  -ms-box-shadow: 0 0 5px #ebebeb;
+}
+
+pre, code {
+  width: 100%;
+  color: #222;
+  background-color: #fff;
+
+  font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace;
+  font-size: 14px;
+
+  border-radius: 2px;
+  -moz-border-radius: 2px;
+  -webkit-border-radius: 2px;
+
+
+
+}
+
+pre {
+  width: 100%;
+  padding: 10px;
+  box-shadow: 0 0 10px rgba(0,0,0,.1);
+  overflow: auto;
+}
+
+code {
+  padding: 3px;
+  margin: 0 3px;
+  box-shadow: 0 0 10px rgba(0,0,0,.1);
+}
+
+pre code {
+  display: block;
+  box-shadow: none;
+}
+
+blockquote {
+  color: #666;
+  margin-bottom: 20px;
+  padding: 0 0 0 20px;
+  border-left: 3px solid #bbb;
+}
+
+ul, ol, dl {
+  margin-bottom: 15px
+}
+
+ul li {
+  list-style: inside;
+  padding-left: 20px;
+}
+
+ol li {
+  list-style: decimal inside;
+  padding-left: 20px;
+}
+
+dl dt {
+  font-weight: bold;
+}
+
+dl dd {
+  padding-left: 20px;
+  font-style: italic;
+}
+
+dl p {
+  padding-left: 20px;
+  font-style: italic;
+}
+
+hr {
+  height: 1px;
+  margin-bottom: 5px;
+  border: none;
+  background: url('../images/bg_hr.png') repeat-x center;
+}
+
+table {
+  border: 1px solid #373737;
+  margin-bottom: 20px;
+  text-align: left;
+ }
+
+th {
+  font-family: 'Lucida Grande', 'Helvetica Neue', Helvetica, Arial, sans-serif;
+  padding: 10px;
+  background: #373737;
+  color: #fff;
+ }
+
+td {
+  padding: 10px;
+  border: 1px solid #373737;
+ }
+
+form {
+  background: #f2f2f2;
+  padding: 20px;
+}
+
+img {
+  width: 100%;
+  max-width: 100%;
+}
+
+/*******************************************************************************
+Full-Width Styles
+*******************************************************************************/
+
+.outer {
+  width: 100%;
+}
+
+.inner {
+  position: relative;
+  max-width: 640px;
+  padding: 20px 10px;
+  margin: 0 auto;
+}
+
+#forkme_banner {
+  display: block;
+  position: absolute;
+  top:0;
+  right: 10px;
+  z-index: 10;
+  padding: 10px 50px 10px 10px;
+  color: #fff;
+  background: url('../images/blacktocat.png') #0090ff no-repeat 95% 50%;
+  font-weight: 700;
+  box-shadow: 0 0 10px rgba(0,0,0,.5);
+  border-bottom-left-radius: 2px;
+  border-bottom-right-radius: 2px;
+}
+
+#header_wrap {
+  background: #212121;
+  background: -moz-linear-gradient(top, #373737, #212121);
+  background: -webkit-linear-gradient(top, #373737, #212121);
+  background: -ms-linear-gradient(top, #373737, #212121);
+  background: -o-linear-gradient(top, #373737, #212121);
+  background: linear-gradient(top, #373737, #212121);
+}
+
+#header_wrap .inner {
+  padding: 50px 10px 30px 10px;
+}
+
+#project_title {
+  margin: 0;
+  color: #fff;
+  font-size: 42px;
+  font-weight: 700;
+  text-shadow: #111 0px 0px 10px;
+}
+
+#project_tagline {
+  color: #fff;
+  font-size: 24px;
+  font-weight: 300;
+  background: none;
+  text-shadow: #111 0px 0px 10px;
+}
+
+#downloads {
+  position: absolute;
+  width: 210px;
+  z-index: 10;
+  bottom: -40px;
+  right: 0;
+  height: 70px;
+  background: url('../images/icon_download.png') no-repeat 0% 90%;
+}
+
+.zip_download_link {
+  display: block;
+  float: right;
+  width: 90px;
+  height:70px;
+  text-indent: -5000px;
+  overflow: hidden;
+  background: url(../images/sprite_download.png) no-repeat bottom left;
+}
+
+.tar_download_link {
+  display: block;
+  float: right;
+  width: 90px;
+  height:70px;
+  text-indent: -5000px;
+  overflow: hidden;
+  background: url(../images/sprite_download.png) no-repeat bottom right;
+  margin-left: 10px;
+}
+
+.zip_download_link:hover {
+  background: url(../images/sprite_download.png) no-repeat top left;
+}
+
+.tar_download_link:hover {
+  background: url(../images/sprite_download.png) no-repeat top right;
+}
+
+#main_content_wrap {
+  background: #f2f2f2;
+  border-top: 1px solid #111;
+  border-bottom: 1px solid #111;
+}
+
+#main_content {
+  padding-top: 40px;
+}
+
+#footer_wrap {
+  background: #212121;
+}
+
+
+
+/*******************************************************************************
+Small Device Styles
+*******************************************************************************/
+
+ at media screen and (max-width: 480px) {
+  body {
+    font-size:14px;
+  }
+
+  #downloads {
+    display: none;
+  }
+
+  .inner {
+    min-width: 320px;
+    max-width: 480px;
+  }
+
+  #project_title {
+  font-size: 32px;
+  }
+
+  h1 {
+    font-size: 28px;
+  }
+
+  h2 {
+    font-size: 24px;
+  }
+
+  h3 {
+    font-size: 21px;
+  }
+
+  h4 {
+    font-size: 18px;
+  }
+
+  h5 {
+    font-size: 14px;
+  }
+
+  h6 {
+    font-size: 12px;
+  }
+
+  code, pre {
+    min-width: 320px;
+    max-width: 480px;
+    font-size: 11px;
+  }
+
+}
diff --git a/crates/typenum-1.9.0/ghp-import/ghp_import.py b/crates/typenum-1.9.0/ghp-import/ghp_import.py
new file mode 100755
index 0000000..41f4376
--- /dev/null
+++ b/crates/typenum-1.9.0/ghp-import/ghp_import.py
@@ -0,0 +1,248 @@
+#! /usr/bin/env python
+#
+# This file is part of the ghp-import package released under
+# the Tumbolia Public License. See the LICENSE file for more
+# information.
+
+import errno
+import optparse as op
+import os
+import subprocess as sp
+import sys
+import time
+import unicodedata
+
+__usage__ = "%prog [OPTIONS] DIRECTORY"
+
+
+if sys.version_info[0] == 3:
+    def enc(text):
+        if isinstance(text, bytes):
+            return text
+        return text.encode()
+
+    def dec(text):
+        if isinstance(text, bytes):
+            return text.decode('utf-8')
+        return text
+
+    def write(pipe, data):
+        try:
+            pipe.stdin.write(data)
+        except IOError as e:
+            if e.errno != errno.EPIPE:
+                raise
+else:
+    def enc(text):
+        if isinstance(text, unicode):
+            return text.encode('utf-8')
+        return text
+
+    def dec(text):
+        if isinstance(text, unicode):
+            return text
+        return text.decode('utf-8')
+
+    def write(pipe, data):
+        pipe.stdin.write(data)
+
+
+class Git(object):
+    def __init__(self, use_shell=False):
+        self.use_shell = use_shell
+
+        self.cmd = None
+        self.pipe = None
+        self.stderr = None
+        self.stdout = None
+
+    def check_repo(self, parser):
+        if self.call('rev-parse') != 0:
+            error = self.stderr
+            if not error:
+                error = "Unknown Git error"
+            error = dec(error)
+            if error.startswith("fatal: "):
+                error = error[len("fatal: "):]
+            parser.error(error)
+
+    def try_rebase(self, remote, branch):
+        rc = self.call('rev-list', '--max-count=1', '%s/%s' % (remote, branch))
+        if rc != 0:
+            return True
+        rev = dec(self.stdout.strip())
+        rc = self.call('update-ref', 'refs/heads/%s' % branch, rev)
+        if rc != 0:
+            return False
+        return True
+
+    def get_config(self, key):
+        self.call('config', key)
+        return self.stdout.strip()
+
+    def get_prev_commit(self, branch):
+        rc = self.call('rev-list', '--max-count=1', branch, '--')
+        if rc != 0:
+            return None
+        return dec(self.stdout).strip()
+
+    def open(self, *args, **kwargs):
+        self.cmd = ['git'] + list(args)
+        if sys.version_info >= (3, 2, 0):
+            kwargs['universal_newlines'] = False
+        for k in 'stdin stdout stderr'.split():
+            kwargs[k] = sp.PIPE
+        kwargs['shell'] = self.use_shell
+        self.pipe = sp.Popen(self.cmd, **kwargs)
+        return self.pipe
+
+    def call(self, *args, **kwargs):
+        self.open(*args, **kwargs)
+        (self.stdout, self.stderr) = self.pipe.communicate()
+        return self.pipe.wait()
+
+    def check_call(self, *args, **kwargs):
+        kwargs["shell"] = self.use_shell
+        sp.check_call(['git'] + list(args), **kwargs)
+
+
+def normalize_path(path):
+    # Fix unicode pathnames on OS X
+    # See: http://stackoverflow.com/a/5582439/44289
+    if sys.platform == "darwin":
+        return unicodedata.normalize("NFKC", dec(path))
+    return path
+
+
+def mk_when(timestamp=None):
+    if timestamp is None:
+        timestamp = int(time.time())
+    currtz = time.strftime('%z')
+    return "%s %s" % (timestamp, currtz)
+
+
+def start_commit(pipe, git, branch, message):
+    uname = dec(git.get_config("user.name"))
+    email = dec(git.get_config("user.email"))
+    write(pipe, enc('commit refs/heads/%s\n' % branch))
+    write(pipe, enc('committer %s <%s> %s\n' % (uname, email, mk_when())))
+    write(pipe, enc('data %d\n%s\n' % (len(enc(message)), message)))
+    head = git.get_prev_commit(branch)
+    if head:
+        write(pipe, enc('from %s\n' % head))
+    write(pipe, enc('deleteall\n'))
+
+
+def add_file(pipe, srcpath, tgtpath):
+    with open(srcpath, "rb") as handle:
+        if os.access(srcpath, os.X_OK):
+            write(pipe, enc('M 100755 inline %s\n' % tgtpath))
+        else:
+            write(pipe, enc('M 100644 inline %s\n' % tgtpath))
+        data = handle.read()
+        write(pipe, enc('data %d\n' % len(data)))
+        write(pipe, enc(data))
+        write(pipe, enc('\n'))
+
+
+def add_nojekyll(pipe):
+    write(pipe, enc('M 100644 inline .nojekyll\n'))
+    write(pipe, enc('data 0\n'))
+    write(pipe, enc('\n'))
+
+
+def add_cname(pipe, cname):
+    write(pipe, enc('M 100644 inline CNAME\n'))
+    write(pipe, enc('data %d\n%s\n' % (len(enc(cname)), cname)))
+
+
+def gitpath(fname):
+    norm = os.path.normpath(fname)
+    return "/".join(norm.split(os.path.sep))
+
+
+def run_import(git, srcdir, opts):
+    cmd = ['git', 'fast-import', '--date-format=raw', '--quiet']
+    kwargs = {
+        "stdin": sp.PIPE,
+        "shell": opts.use_shell
+    }
+    if sys.version_info >= (3, 2, 0):
+        kwargs["universal_newlines"] = False
+    pipe = sp.Popen(cmd, **kwargs)
+    start_commit(pipe, git, opts.branch, opts.mesg)
+    for path, dnames, fnames in os.walk(srcdir, followlinks=opts.followlinks):
+        for fn in fnames:
+            fpath = os.path.join(path, fn)
+            fpath = normalize_path(fpath)
+            gpath = gitpath(os.path.relpath(fpath, start=srcdir))
+            add_file(pipe, fpath, gpath)
+    if opts.nojekyll:
+        add_nojekyll(pipe)
+    if opts.cname is not None:
+        add_cname(pipe, opts.cname)
+    write(pipe, enc('\n'))
+    pipe.stdin.close()
+    if pipe.wait() != 0:
+        sys.stdout.write(enc("Failed to process commit.\n"))
+
+
+def options():
+    return [
+        op.make_option('-n', '--no-jekyll', dest='nojekyll', default=False,
+            action="store_true",
+            help='Include a .nojekyll file in the branch.'),
+        op.make_option('-c', '--cname', dest='cname', default=None,
+            help='Write a CNAME file with the given CNAME.'),
+        op.make_option('-m', '--message', dest='mesg',
+            default='Update documentation',
+            help='The commit message to use on the target branch.'),
+        op.make_option('-p', '--push', dest='push', default=False,
+            action='store_true',
+            help='Push the branch to origin/{branch} after committing.'),
+        op.make_option('-f', '--force', dest='force',
+            default=False, action='store_true',
+            help='Force the push to the repository'),
+        op.make_option('-r', '--remote', dest='remote', default='origin',
+            help='The name of the remote to push to. [%default]'),
+        op.make_option('-b', '--branch', dest='branch', default='gh-pages',
+            help='Name of the branch to write to. [%default]'),
+        op.make_option('-s', '--shell', dest='use_shell', default=False,
+            action='store_true',
+            help='Use the shell when invoking Git. [%default]'),
+        op.make_option('-l', '--follow-links', dest='followlinks',
+            default=False, action='store_true',
+            help='Follow symlinks when adding files. [%default]')
+    ]
+
+
+def main():
+    parser = op.OptionParser(usage=__usage__, option_list=options())
+    opts, args = parser.parse_args()
+
+    if len(args) == 0:
+        parser.error("No import directory specified.")
+
+    if len(args) > 1:
+        parser.error("Unknown arguments specified: %s" % ', '.join(args[1:]))
+
+    if not os.path.isdir(args[0]):
+        parser.error("Not a directory: %s" % args[0])
+
+    git = Git(use_shell=opts.use_shell)
+    git.check_repo(parser)
+
+    if not git.try_rebase(opts.remote, opts.branch):
+        parser.error("Failed to rebase %s branch." % opts.branch)
+
+    run_import(git, args[0], opts)
+
+    if opts.push:
+        if opts.force:
+            git.check_call('push', opts.remote, opts.branch, '--force')
+        else:
+            git.check_call('push', opts.remote, opts.branch)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/crates/typenum-1.9.0/ghp-import/requirements.txt b/crates/typenum-1.9.0/ghp-import/requirements.txt
new file mode 100644
index 0000000..a07c43d
--- /dev/null
+++ b/crates/typenum-1.9.0/ghp-import/requirements.txt
@@ -0,0 +1,2 @@
+markdown
+pyflakes
diff --git a/crates/typenum-1.9.0/ghp-import/setup.py b/crates/typenum-1.9.0/ghp-import/setup.py
new file mode 100644
index 0000000..32cae4c
--- /dev/null
+++ b/crates/typenum-1.9.0/ghp-import/setup.py
@@ -0,0 +1,41 @@
+import io
+import os
+import sys
+
+try:
+    from setuptools import setup
+except ImportError:
+    from distutils.core import setup
+
+LONG_DESC_PATH = os.path.join(os.path.dirname(__file__), "README.md")
+LONG_DESC = io.open(LONG_DESC_PATH, encoding = "utf-8").read()
+
+setup(
+    name = "ghp-import",
+    version = "0.5.5",
+    description = "Copy your docs directly to the gh-pages branch.",
+    long_description = LONG_DESC,
+    author = "Paul Joseph Davis",
+    author_email = "paul.joseph.davis at gmail.com",
+    license = "Tumbolia Public License",
+    url = "http://github.com/davisp/ghp-import",
+    zip_safe = False,
+
+    classifiers = [
+        "Development Status :: 3 - Alpha",
+        "Intended Audience :: Developers",
+        'Natural Language :: English',
+        "Operating System :: OS Independent",
+        "Programming Language :: Python",
+        "Programming Language :: Python :: 2",
+        "Programming Language :: Python :: 3",
+    ],
+
+    py_modules = ["ghp_import"],
+
+    entry_points = {
+        "console_scripts": [
+            "ghp-import = ghp_import:main",
+        ],
+    }
+)
diff --git a/crates/typenum-1.9.0/src/array.rs b/crates/typenum-1.9.0/src/array.rs
new file mode 100644
index 0000000..075decd
--- /dev/null
+++ b/crates/typenum-1.9.0/src/array.rs
@@ -0,0 +1,269 @@
+//! A type-level array of type-level numbers.
+//!
+//! It is not very featureful right now, and should be considered a work in progress.
+
+use core::marker::PhantomData;
+use core::ops::{Add, Sub, Mul, Div};
+
+use super::*;
+
+/// The terminating type for type arrays.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug)]
+pub struct ATerm;
+
+impl TypeArray for ATerm {}
+
+/// `TArr` is a type that acts as an array of types. It is defined similarly to `UInt`, only its
+/// values can be more than bits, and it is designed to act as an array. So you can only add two if
+/// they have the same number of elements, for example.
+///
+/// This array is only really designed to contain `Integer` types. If you use it with others, you
+/// may find it lacking functionality.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug)]
+pub struct TArr<V, A> {
+    _marker: PhantomData<(V, A)>,
+}
+
+impl<V, A> TypeArray for TArr<V, A> {}
+
+/// Create a new type-level arrray. Only usable on Rust 1.13.0 or newer.
+///
+/// There's not a whole lot you can do with it right now.
+///
+/// # Example
+/// ```rust
+/// #[macro_use]
+/// extern crate typenum;
+/// use typenum::consts::*;
+///
+/// type Array = tarr![P3, N4, Z0, P38];
+/// # fn main() { let _: Array; }
+#[macro_export]
+macro_rules! tarr {
+    () => ( $crate::ATerm );
+    ($n:ty) => ( $crate::TArr<$n, $crate::ATerm> );
+    ($n:ty,) => ( $crate::TArr<$n, $crate::ATerm> );
+    ($n:ty, $($tail:ty),+) => ( $crate::TArr<$n, tarr![$($tail),+]> );
+    ($n:ty, $($tail:ty),+,) => ( $crate::TArr<$n, tarr![$($tail),+]> );
+}
+
+// ---------------------------------------------------------------------------------------
+// Length
+
+/// Length of `ATerm` by itself is 0
+impl Len for ATerm {
+    type Output = U0;
+    fn len(&self) -> Self::Output {
+        UTerm
+    }
+}
+
+/// Size of a `TypeArray`
+impl<V, A> Len for TArr<V, A>
+    where A: Len,
+          Length<A>: Add<B1>,
+          Sum<Length<A>, B1>: Unsigned
+{
+    type Output = Add1<Length<A>>;
+    fn len(&self) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+// ---------------------------------------------------------------------------------------
+// Add arrays
+// Note that two arrays are only addable if they are the same length.
+
+impl Add<ATerm> for ATerm {
+    type Output = ATerm;
+    fn add(self, _: ATerm) -> Self::Output {
+        ATerm
+    }
+}
+
+impl<Al, Vl, Ar, Vr> Add<TArr<Vr, Ar>> for TArr<Vl, Al>
+    where Al: Add<Ar>,
+          Vl: Add<Vr>
+{
+    type Output = TArr<Sum<Vl, Vr>, Sum<Al, Ar>>;
+    fn add(self, _: TArr<Vr, Ar>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+// ---------------------------------------------------------------------------------------
+// Subtract arrays
+// Note that two arrays are only subtractable if they are the same length.
+
+impl Sub<ATerm> for ATerm {
+    type Output = ATerm;
+    fn sub(self, _: ATerm) -> Self::Output {
+        ATerm
+    }
+}
+
+impl<Vl, Al, Vr, Ar> Sub<TArr<Vr, Ar>> for TArr<Vl, Al>
+    where Vl: Sub<Vr>,
+          Al: Sub<Ar>
+{
+    type Output = TArr<Diff<Vl, Vr>, Diff<Al, Ar>>;
+    fn sub(self, _: TArr<Vr, Ar>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+// ---------------------------------------------------------------------------------------
+// Multiply an array by a scalar
+
+impl<Rhs> Mul<Rhs> for ATerm {
+    type Output = ATerm;
+    fn mul(self, _: Rhs) -> Self::Output {
+        ATerm
+    }
+}
+
+impl<V, A, Rhs> Mul<Rhs> for TArr<V, A>
+    where V: Mul<Rhs>,
+          A: Mul<Rhs>
+{
+    type Output = TArr<Prod<V, Rhs>, Prod<A, Rhs>>;
+    fn mul(self, _: Rhs) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+impl Mul<ATerm> for Z0 {
+    type Output = ATerm;
+    fn mul(self, _: ATerm) -> Self::Output {
+        ATerm
+    }
+}
+
+impl<U> Mul<ATerm> for PInt<U>
+    where U: Unsigned + NonZero
+{
+    type Output = ATerm;
+    fn mul(self, _: ATerm) -> Self::Output {
+        ATerm
+    }
+}
+
+impl<U> Mul<ATerm> for NInt<U>
+    where U: Unsigned + NonZero
+{
+    type Output = ATerm;
+    fn mul(self, _: ATerm) -> Self::Output {
+        ATerm
+    }
+}
+
+impl<V, A> Mul<TArr<V, A>> for Z0
+    where Z0: Mul<A>
+{
+    type Output = TArr<Z0, Prod<Z0, A>>;
+    fn mul(self, _: TArr<V, A>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+impl<V, A, U> Mul<TArr<V, A>> for PInt<U>
+    where U: Unsigned + NonZero,
+          PInt<U>: Mul<A> + Mul<V>
+{
+    type Output = TArr<Prod<PInt<U>, V>, Prod<PInt<U>, A>>;
+    fn mul(self, _: TArr<V, A>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+impl<V, A, U> Mul<TArr<V, A>> for NInt<U>
+    where U: Unsigned + NonZero,
+          NInt<U>: Mul<A> + Mul<V>
+{
+    type Output = TArr<Prod<NInt<U>, V>, Prod<NInt<U>, A>>;
+    fn mul(self, _: TArr<V, A>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+// ---------------------------------------------------------------------------------------
+// Divide an array by a scalar
+
+impl<Rhs> Div<Rhs> for ATerm {
+    type Output = ATerm;
+    fn div(self, _: Rhs) -> Self::Output {
+        ATerm
+    }
+}
+
+impl<V, A, Rhs> Div<Rhs> for TArr<V, A>
+    where V: Div<Rhs>,
+          A: Div<Rhs>
+{
+    type Output = TArr<Quot<V, Rhs>, Quot<A, Rhs>>;
+    fn div(self, _: Rhs) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+// ---------------------------------------------------------------------------------------
+// Partial Divide an array by a scalar
+
+impl<Rhs> PartialDiv<Rhs> for ATerm {
+    type Output = ATerm;
+    fn partial_div(self, _: Rhs) -> Self::Output {
+        ATerm
+    }
+}
+
+impl<V, A, Rhs> PartialDiv<Rhs> for TArr<V, A>
+    where V: PartialDiv<Rhs>,
+          A: PartialDiv<Rhs>
+{
+    type Output = TArr<PartialQuot<V, Rhs>, PartialQuot<A, Rhs>>;
+    fn partial_div(self, _: Rhs) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+// ---------------------------------------------------------------------------------------
+// Modulo an array by a scalar
+use core::ops::Rem;
+
+impl<Rhs> Rem<Rhs> for ATerm {
+    type Output = ATerm;
+    fn rem(self, _: Rhs) -> Self::Output {
+        ATerm
+    }
+}
+
+impl<V, A, Rhs> Rem<Rhs> for TArr<V, A>
+    where V: Rem<Rhs>,
+          A: Rem<Rhs>
+{
+    type Output = TArr<Mod<V, Rhs>, Mod<A, Rhs>>;
+    fn rem(self, _: Rhs) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+// ---------------------------------------------------------------------------------------
+// Negate an array
+use core::ops::Neg;
+
+impl Neg for ATerm {
+    type Output = ATerm;
+    fn neg(self) -> Self::Output {
+        ATerm
+    }
+}
+
+impl<V, A> Neg for TArr<V, A>
+    where V: Neg,
+          A: Neg
+{
+    type Output = TArr<Negate<V>, Negate<A>>;
+    fn neg(self) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
diff --git a/crates/typenum-1.9.0/src/bit.rs b/crates/typenum-1.9.0/src/bit.rs
new file mode 100644
index 0000000..96d75d4
--- /dev/null
+++ b/crates/typenum-1.9.0/src/bit.rs
@@ -0,0 +1,263 @@
+//! Type-level bits.
+//!
+//! These are rather simple and are used as the building blocks of the
+//! other number types in this crate.
+//!
+//!
+//! **Type operators** implemented:
+//!
+//! - From `core::ops`: `BitAnd`, `BitOr`, `BitXor`, and `Not`.
+//! - From `typenum`: `Same` and `Cmp`.
+//!
+
+use core::ops::{BitAnd, BitOr, BitXor, Not};
+use {NonZero, Cmp, Greater, Less, Equal};
+
+pub use marker_traits::Bit;
+
+/// The type-level bit 0.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
+pub struct B0;
+
+impl B0 {
+    /// Instantiates a singleton representing this bit.
+    #[inline]
+    pub fn new() -> B0 {
+        B0
+    }
+}
+
+/// The type-level bit 1.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
+pub struct B1;
+
+impl B1 {
+    /// Instantiates a singleton representing this bit.
+    #[inline]
+    pub fn new() -> B1 {
+        B1
+    }
+}
+
+impl Bit for B0 {
+    #[inline]
+    fn to_u8() -> u8 {
+        0
+    }
+    #[inline]
+    fn to_bool() -> bool {
+        false
+    }
+}
+
+impl Bit for B1 {
+    #[inline]
+    fn to_u8() -> u8 {
+        1
+    }
+    #[inline]
+    fn to_bool() -> bool {
+        true
+    }
+}
+
+impl NonZero for B1 {}
+
+// macro for testing operation results. Uses `Same` to ensure the types are equal and
+// not just the values they evaluate to.
+macro_rules! test_bit_op {
+    ($op:ident $Lhs:ident = $Answer:ident) => (
+        {
+            type Test = <<$Lhs as $op>::Output as ::Same<$Answer>>::Output;
+            assert_eq!(<$Answer as Bit>::to_u8(), <Test as Bit>::to_u8());
+        }
+        );
+    ($Lhs:ident $op:ident $Rhs:ident = $Answer:ident) => (
+        {
+            type Test = <<$Lhs as $op<$Rhs>>::Output as ::Same<$Answer>>::Output;
+            assert_eq!(<$Answer as Bit>::to_u8(), <Test as Bit>::to_u8());
+        }
+        );
+}
+
+/// Not of 0 (!0 = 1)
+impl Not for B0 {
+    type Output = B1;
+    fn not(self) -> Self::Output {
+        B1
+    }
+}
+/// Not of 1 (!1 = 0)
+impl Not for B1 {
+    type Output = B0;
+    fn not(self) -> Self::Output {
+        B0
+    }
+}
+
+/// And with 0 ( 0 & B = 0)
+impl<Rhs: Bit> BitAnd<Rhs> for B0 {
+    type Output = B0;
+    fn bitand(self, _: Rhs) -> Self::Output {
+        B0
+    }
+}
+
+/// And with 1 ( 1 & 0 = 0)
+impl BitAnd<B0> for B1 {
+    type Output = B0;
+    fn bitand(self, _: B0) -> Self::Output {
+        B0
+    }
+}
+
+/// And with 1 ( 1 & 1 = 1)
+impl BitAnd<B1> for B1 {
+    type Output = B1;
+    fn bitand(self, _: B1) -> Self::Output {
+        B1
+    }
+}
+
+/// Or with 0 ( 0 | 0 = 0)
+impl BitOr<B0> for B0 {
+    type Output = B0;
+    fn bitor(self, _: B0) -> Self::Output {
+        B0
+    }
+}
+
+/// Or with 0 ( 0 | 1 = 1)
+impl BitOr<B1> for B0 {
+    type Output = B1;
+    fn bitor(self, _: B1) -> Self::Output {
+        B1
+    }
+}
+
+/// Or with 1 ( 1 | B = 1)
+impl<Rhs: Bit> BitOr<Rhs> for B1 {
+    type Output = B1;
+    fn bitor(self, _: Rhs) -> Self::Output {
+        B1
+    }
+}
+
+/// Xor between 0 and 0 ( 0 ^ 0 = 0)
+impl BitXor<B0> for B0 {
+    type Output = B0;
+    fn bitxor(self, _: B0) -> Self::Output {
+        B0
+    }
+}
+/// Xor between 1 and 0 ( 1 ^ 0 = 1)
+impl BitXor<B0> for B1 {
+    type Output = B1;
+    fn bitxor(self, _: B0) -> Self::Output {
+        B1
+    }
+}
+/// Xor between 0 and 1 ( 0 ^ 1 = 1)
+impl BitXor<B1> for B0 {
+    type Output = B1;
+    fn bitxor(self, _: B1) -> Self::Output {
+        B1
+    }
+}
+/// Xor between 1 and 1 ( 1 ^ 1 = 0)
+impl BitXor<B1> for B1 {
+    type Output = B0;
+    fn bitxor(self, _: B1) -> Self::Output {
+        B0
+    }
+}
+
+#[test]
+fn bit_operations() {
+    test_bit_op!(Not B0 = B1);
+    test_bit_op!(Not B1 = B0);
+
+    test_bit_op!(B0 BitAnd B0 = B0);
+    test_bit_op!(B0 BitAnd B1 = B0);
+    test_bit_op!(B1 BitAnd B0 = B0);
+    test_bit_op!(B1 BitAnd B1 = B1);
+
+    test_bit_op!(B0 BitOr B0 = B0);
+    test_bit_op!(B0 BitOr B1 = B1);
+    test_bit_op!(B1 BitOr B0 = B1);
+    test_bit_op!(B1 BitOr B1 = B1);
+
+    test_bit_op!(B0 BitXor B0 = B0);
+    test_bit_op!(B0 BitXor B1 = B1);
+    test_bit_op!(B1 BitXor B0 = B1);
+    test_bit_op!(B1 BitXor B1 = B0);
+}
+
+impl Cmp<B0> for B0 {
+    type Output = Equal;
+}
+
+impl Cmp<B1> for B0 {
+    type Output = Less;
+}
+
+impl Cmp<B0> for B1 {
+    type Output = Greater;
+}
+
+impl Cmp<B1> for B1 {
+    type Output = Equal;
+}
+
+
+use Min;
+impl Min<B0> for B0 {
+    type Output = B0;
+    fn min(self, _: B0) -> B0 {
+        self
+    }
+}
+impl Min<B1> for B0 {
+    type Output = B0;
+    fn min(self, _: B1) -> B0 {
+        self
+    }
+}
+impl Min<B0> for B1 {
+    type Output = B0;
+    fn min(self, rhs: B0) -> B0 {
+        rhs
+    }
+}
+impl Min<B1> for B1 {
+    type Output = B1;
+    fn min(self, _: B1) -> B1 {
+        self
+    }
+}
+
+use Max;
+impl Max<B0> for B0 {
+    type Output = B0;
+    fn max(self, _: B0) -> B0 {
+        self
+    }
+}
+impl Max<B1> for B0 {
+    type Output = B1;
+    fn max(self, rhs: B1) -> B1 {
+        rhs
+    }
+}
+impl Max<B0> for B1 {
+    type Output = B1;
+    fn max(self, _: B0) -> B1 {
+        self
+    }
+}
+impl Max<B1> for B1 {
+    type Output = B1;
+    fn max(self, _: B1) -> B1 {
+        self
+    }
+}
diff --git a/crates/typenum-1.9.0/src/int.rs b/crates/typenum-1.9.0/src/int.rs
new file mode 100644
index 0000000..2d1c0f7
--- /dev/null
+++ b/crates/typenum-1.9.0/src/int.rs
@@ -0,0 +1,910 @@
+//! Type-level signed integers.
+//!
+//!
+//! Type **operators** implemented:
+//!
+//! From `core::ops`: `Add`, `Sub`, `Mul`, `Div`, and `Rem`.
+//! From `typenum`: `Same`, `Cmp`, and `Pow`.
+//!
+//! Rather than directly using the structs defined in this module, it is recommended that
+//! you import and use the relevant aliases from the [consts](../consts/index.html) module.
+//!
+//! Note that operators that work on the underlying structure of the number are
+//! intentionally not implemented. This is because this implementation of signed integers
+//! does *not* use twos-complement, and implementing them would require making arbitrary
+//! choices, causing the results of such operators to be difficult to reason about.
+//!
+//! # Example
+//! ```rust
+//! use std::ops::{Add, Sub, Mul, Div, Rem};
+//! use typenum::{Integer, N3, P2};
+//!
+//! assert_eq!(<N3 as Add<P2>>::Output::to_i32(), -1);
+//! assert_eq!(<N3 as Sub<P2>>::Output::to_i32(), -5);
+//! assert_eq!(<N3 as Mul<P2>>::Output::to_i32(), -6);
+//! assert_eq!(<N3 as Div<P2>>::Output::to_i32(), -1);
+//! assert_eq!(<N3 as Rem<P2>>::Output::to_i32(), -1);
+//! ```
+//!
+
+use core::ops::{Neg, Add, Sub, Mul, Div, Rem};
+use core::marker::PhantomData;
+
+use {NonZero, Pow, Cmp, Greater, Equal, Less};
+use uint::{Unsigned, UInt};
+use bit::{Bit, B0, B1};
+use private::{PrivateIntegerAdd, PrivateDivInt, PrivateRem};
+use consts::{U0, U1, P1, N1};
+
+pub use marker_traits::Integer;
+
+/// Type-level signed integers with positive sign.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
+pub struct PInt<U: Unsigned + NonZero> {
+    _marker: PhantomData<U>,
+}
+
+/// Type-level signed integers with negative sign.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
+pub struct NInt<U: Unsigned + NonZero> {
+    _marker: PhantomData<U>,
+}
+
+impl<U: Unsigned + NonZero> PInt<U> {
+    /// Instantiates a singleton representing this strictly positive integer.
+    #[inline]
+    pub fn new() -> PInt<U> {
+        PInt { _marker: PhantomData }
+    }
+}
+
+impl<U: Unsigned + NonZero> NInt<U> {
+    /// Instantiates a singleton representing this strictly negative integer.
+    #[inline]
+    pub fn new() -> NInt<U> {
+        NInt { _marker: PhantomData }
+    }
+}
+
+
+/// The type-level signed integer 0.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
+pub struct Z0;
+
+impl Z0 {
+    /// Instantiates a singleton representing the integer 0.
+    #[inline]
+    pub fn new() -> Z0 {
+        Z0
+    }
+}
+
+impl<U: Unsigned + NonZero> NonZero for PInt<U> {}
+impl<U: Unsigned + NonZero> NonZero for NInt<U> {}
+
+impl Integer for Z0 {
+    #[inline]
+    fn to_i8() -> i8 {
+        0
+    }
+    #[inline]
+    fn to_i16() -> i16 {
+        0
+    }
+    #[inline]
+    fn to_i32() -> i32 {
+        0
+    }
+    #[inline]
+    fn to_i64() -> i64 {
+        0
+    }
+    #[cfg(feature="i128")]
+    #[inline]
+    fn to_i128() -> i128 {
+        0
+    }
+    #[inline]
+    fn to_isize() -> isize {
+        0
+    }
+}
+
+impl<U: Unsigned + NonZero> Integer for PInt<U> {
+    #[inline]
+    fn to_i8() -> i8 {
+        <U as Unsigned>::to_i8()
+    }
+    #[inline]
+    fn to_i16() -> i16 {
+        <U as Unsigned>::to_i16()
+    }
+    #[inline]
+    fn to_i32() -> i32 {
+        <U as Unsigned>::to_i32()
+    }
+    #[inline]
+    fn to_i64() -> i64 {
+        <U as Unsigned>::to_i64()
+    }
+    #[cfg(feature="i128")]
+    #[inline]
+    fn to_i128() -> i128 {
+        <U as Unsigned>::to_i128()
+    }
+    #[inline]
+    fn to_isize() -> isize {
+        <U as Unsigned>::to_isize()
+    }
+}
+
+impl<U: Unsigned + NonZero> Integer for NInt<U> {
+    #[inline]
+    fn to_i8() -> i8 {
+        -<U as Unsigned>::to_i8()
+    }
+    #[inline]
+    fn to_i16() -> i16 {
+        -<U as Unsigned>::to_i16()
+    }
+    #[inline]
+    fn to_i32() -> i32 {
+        -<U as Unsigned>::to_i32()
+    }
+    #[inline]
+    fn to_i64() -> i64 {
+        -<U as Unsigned>::to_i64()
+    }
+    #[cfg(feature="i128")]
+    #[inline]
+    fn to_i128() -> i128 {
+        -<U as Unsigned>::to_i128()
+    }
+    #[inline]
+    fn to_isize() -> isize {
+        -<U as Unsigned>::to_isize()
+    }
+}
+
+// macro for testing operation results. Uses `Same` to ensure the types are equal and
+// not just the values they evaluate to.
+macro_rules! test_int_op {
+    ($op:ident $Lhs:ident = $Answer:ident) => (
+        {
+            type Test = <<$Lhs as $op>::Output as ::Same<$Answer>>::Output;
+            assert_eq!(<$Answer as Integer>::to_i64(), <Test as Integer>::to_i64());
+        }
+        );
+    ($Lhs:ident $op:ident $Rhs:ident = $Answer:ident) => (
+        {
+            type Test = <<$Lhs as $op<$Rhs>>::Output as ::Same<$Answer>>::Output;
+            assert_eq!(<$Answer as Integer>::to_i64(), <Test as Integer>::to_i64());
+        }
+        );
+}
+
+// ---------------------------------------------------------------------------------------
+// Neg
+
+/// `-Z0 = Z0`
+impl Neg for Z0 {
+    type Output = Z0;
+    fn neg(self) -> Self::Output {
+        Z0
+    }
+}
+
+/// `-PInt = NInt`
+impl<U: Unsigned + NonZero> Neg for PInt<U> {
+    type Output = NInt<U>;
+    fn neg(self) -> Self::Output {
+        NInt::new()
+    }
+}
+
+/// `-NInt = PInt`
+impl<U: Unsigned + NonZero> Neg for NInt<U> {
+    type Output = PInt<U>;
+    fn neg(self) -> Self::Output {
+        PInt::new()
+    }
+}
+
+// ---------------------------------------------------------------------------------------
+// Add
+
+/// `Z0 + I = I`
+impl<I: Integer> Add<I> for Z0 {
+    type Output = I;
+    fn add(self, _: I) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+/// `PInt + Z0 = PInt`
+impl<U: Unsigned + NonZero> Add<Z0> for PInt<U> {
+    type Output = PInt<U>;
+    fn add(self, _: Z0) -> Self::Output {
+        PInt::new()
+    }
+}
+
+/// `NInt + Z0 = NInt`
+impl<U: Unsigned + NonZero> Add<Z0> for NInt<U> {
+    type Output = NInt<U>;
+    fn add(self, _: Z0) -> Self::Output {
+        NInt::new()
+    }
+}
+
+/// `P(Ul) + P(Ur) = P(Ul + Ur)`
+impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<PInt<Ur>> for PInt<Ul>
+    where Ul: Add<Ur>,
+          <Ul as Add<Ur>>::Output: Unsigned + NonZero
+{
+    type Output = PInt<<Ul as Add<Ur>>::Output>;
+    fn add(self, _: PInt<Ur>) -> Self::Output {
+        PInt::new()
+    }
+}
+
+/// `N(Ul) + N(Ur) = N(Ul + Ur)`
+impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<NInt<Ur>> for NInt<Ul>
+    where Ul: Add<Ur>,
+          <Ul as Add<Ur>>::Output: Unsigned + NonZero
+{
+    type Output = NInt<<Ul as Add<Ur>>::Output>;
+    fn add(self, _: NInt<Ur>) -> Self::Output {
+        NInt::new()
+    }
+}
+
+/// `P(Ul) + N(Ur)`: We resolve this with our `PrivateAdd`
+impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<NInt<Ur>> for PInt<Ul>
+    where Ul: Cmp<Ur> + PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>
+{
+    type Output = <Ul as PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>>::Output;
+    fn add(self, _: NInt<Ur>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+/// `N(Ul) + P(Ur)`: We resolve this with our `PrivateAdd`
+// We just do the same thing as above, swapping Lhs and Rhs
+impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<PInt<Ur>> for NInt<Ul>
+    where Ur: Cmp<Ul> + PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>
+{
+    type Output = <Ur as PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>>::Output;
+    fn add(self, _: PInt<Ur>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+/// `P + N = 0` where `P == N`
+impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Equal, N> for P {
+    type Output = Z0;
+}
+
+/// `P + N = Positive` where `P > N`
+impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Greater, N> for P
+    where P: Sub<N>,
+          <P as Sub<N>>::Output: Unsigned + NonZero
+{
+    type Output = PInt<<P as Sub<N>>::Output>;
+}
+
+/// `P + N = Negative` where `P < N`
+impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Less, N> for P
+    where N: Sub<P>,
+          <N as Sub<P>>::Output: Unsigned + NonZero
+{
+    type Output = NInt<<N as Sub<P>>::Output>;
+}
+
+// ---------------------------------------------------------------------------------------
+// Sub
+
+/// `Z0 - Z0 = Z0`
+impl Sub<Z0> for Z0 {
+    type Output = Z0;
+    fn sub(self, _: Z0) -> Self::Output {
+        Z0
+    }
+}
+
+/// `Z0 - P = N`
+impl<U: Unsigned + NonZero> Sub<PInt<U>> for Z0 {
+    type Output = NInt<U>;
+    fn sub(self, _: PInt<U>) -> Self::Output {
+        NInt::new()
+    }
+}
+
+/// `Z0 - N = P`
+impl<U: Unsigned + NonZero> Sub<NInt<U>> for Z0 {
+    type Output = PInt<U>;
+    fn sub(self, _: NInt<U>) -> Self::Output {
+        PInt::new()
+    }
+}
+
+/// `PInt - Z0 = PInt`
+impl<U: Unsigned + NonZero> Sub<Z0> for PInt<U> {
+    type Output = PInt<U>;
+    fn sub(self, _: Z0) -> Self::Output {
+        PInt::new()
+    }
+}
+
+/// `NInt - Z0 = NInt`
+impl<U: Unsigned + NonZero> Sub<Z0> for NInt<U> {
+    type Output = NInt<U>;
+    fn sub(self, _: Z0) -> Self::Output {
+        NInt::new()
+    }
+}
+
+/// `P(Ul) - N(Ur) = P(Ul + Ur)`
+impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<NInt<Ur>> for PInt<Ul>
+    where Ul: Add<Ur>,
+          <Ul as Add<Ur>>::Output: Unsigned + NonZero
+{
+    type Output = PInt<<Ul as Add<Ur>>::Output>;
+    fn sub(self, _: NInt<Ur>) -> Self::Output {
+        PInt::new()
+    }
+}
+
+/// `N(Ul) - P(Ur) = N(Ul + Ur)`
+impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<PInt<Ur>> for NInt<Ul>
+    where Ul: Add<Ur>,
+          <Ul as Add<Ur>>::Output: Unsigned + NonZero
+{
+    type Output = NInt<<Ul as Add<Ur>>::Output>;
+    fn sub(self, _: PInt<Ur>) -> Self::Output {
+        NInt::new()
+    }
+}
+
+/// `P(Ul) - P(Ur)`: We resolve this with our `PrivateAdd`
+impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<PInt<Ur>> for PInt<Ul>
+    where Ul: Cmp<Ur> + PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>
+{
+    type Output = <Ul as PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>>::Output;
+    fn sub(self, _: PInt<Ur>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+/// `N(Ul) - N(Ur)`: We resolve this with our `PrivateAdd`
+// We just do the same thing as above, swapping Lhs and Rhs
+impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<NInt<Ur>> for NInt<Ul>
+    where Ur: Cmp<Ul> + PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>
+{
+    type Output = <Ur as PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>>::Output;
+    fn sub(self, _: NInt<Ur>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+// ---------------------------------------------------------------------------------------
+// Mul
+
+/// `Z0 * I = Z0`
+impl<I: Integer> Mul<I> for Z0 {
+    type Output = Z0;
+    fn mul(self, _: I) -> Self::Output {
+        Z0
+    }
+}
+
+/// `P * Z0 = Z0`
+impl<U: Unsigned + NonZero> Mul<Z0> for PInt<U> {
+    type Output = Z0;
+    fn mul(self, _: Z0) -> Self::Output {
+        Z0
+    }
+}
+
+/// `N * Z0 = Z0`
+impl<U: Unsigned + NonZero> Mul<Z0> for NInt<U> {
+    type Output = Z0;
+    fn mul(self, _: Z0) -> Self::Output {
+        Z0
+    }
+}
+
+/// P(Ul) * P(Ur) = P(Ul * Ur)
+impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<PInt<Ur>> for PInt<Ul>
+    where Ul: Mul<Ur>,
+          <Ul as Mul<Ur>>::Output: Unsigned + NonZero
+{
+    type Output = PInt<<Ul as Mul<Ur>>::Output>;
+    fn mul(self, _: PInt<Ur>) -> Self::Output {
+        PInt::new()
+    }
+}
+
+/// N(Ul) * N(Ur) = P(Ul * Ur)
+impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<NInt<Ur>> for NInt<Ul>
+    where Ul: Mul<Ur>,
+          <Ul as Mul<Ur>>::Output: Unsigned + NonZero
+{
+    type Output = PInt<<Ul as Mul<Ur>>::Output>;
+    fn mul(self, _: NInt<Ur>) -> Self::Output {
+        PInt::new()
+    }
+}
+
+/// P(Ul) * N(Ur) = N(Ul * Ur)
+impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<NInt<Ur>> for PInt<Ul>
+    where Ul: Mul<Ur>,
+          <Ul as Mul<Ur>>::Output: Unsigned + NonZero
+{
+    type Output = NInt<<Ul as Mul<Ur>>::Output>;
+    fn mul(self, _: NInt<Ur>) -> Self::Output {
+        NInt::new()
+    }
+}
+
+/// N(Ul) * P(Ur) = N(Ul * Ur)
+impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<PInt<Ur>> for NInt<Ul>
+    where Ul: Mul<Ur>,
+          <Ul as Mul<Ur>>::Output: Unsigned + NonZero
+{
+    type Output = NInt<<Ul as Mul<Ur>>::Output>;
+    fn mul(self, _: PInt<Ur>) -> Self::Output {
+        NInt::new()
+    }
+}
+
+// ---------------------------------------------------------------------------------------
+// Div
+
+/// `Z0 / I = Z0` where `I != 0`
+impl<I: Integer + NonZero> Div<I> for Z0 {
+    type Output = Z0;
+    fn div(self, _: I) -> Self::Output {
+        Z0
+    }
+}
+
+macro_rules! impl_int_div {
+    ($A:ident, $B:ident, $R:ident) => (
+        /// `$A<Ul> / $B<Ur> = $R<Ul / Ur>`
+        impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Div<$B<Ur>> for $A<Ul>
+            where Ul: Cmp<Ur>,
+                  $A<Ul>: PrivateDivInt<<Ul as Cmp<Ur>>::Output, $B<Ur>>
+        {
+            type Output = <$A<Ul> as PrivateDivInt<
+                <Ul as Cmp<Ur>>::Output,
+                $B<Ur>>>::Output;
+            fn div(self, _: $B<Ur>) -> Self::Output {
+                unsafe { ::core::mem::uninitialized() }
+            }
+        }
+        impl<Ul, Ur> PrivateDivInt<Less, $B<Ur>> for $A<Ul>
+            where Ul: Unsigned + NonZero, Ur: Unsigned + NonZero,
+        {
+            type Output = Z0;
+        }
+        impl<Ul, Ur> PrivateDivInt<Equal, $B<Ur>> for $A<Ul>
+            where Ul: Unsigned + NonZero, Ur: Unsigned + NonZero,
+        {
+            type Output = $R<U1>;
+        }
+        impl<Ul, Ur> PrivateDivInt<Greater, $B<Ur>> for $A<Ul>
+            where Ul: Unsigned + NonZero + Div<Ur>,
+                  Ur: Unsigned + NonZero,
+                  <Ul as Div<Ur>>::Output: Unsigned + NonZero,
+        {
+            type Output = $R<<Ul as Div<Ur>>::Output>;
+        }
+        );
+}
+
+impl_int_div!(PInt, PInt, PInt);
+impl_int_div!(PInt, NInt, NInt);
+impl_int_div!(NInt, PInt, NInt);
+impl_int_div!(NInt, NInt, PInt);
+
+// ---------------------------------------------------------------------------------------
+// PartialDiv
+
+use {PartialDiv, Quot};
+
+impl<M, N> PartialDiv<N> for M
+    where M: Integer + Div<N> + Rem<N, Output = Z0>
+{
+    type Output = Quot<M, N>;
+    fn partial_div(self, _: N) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+// ---------------------------------------------------------------------------------------
+// Cmp
+
+/// 0 == 0
+impl Cmp<Z0> for Z0 {
+    type Output = Equal;
+}
+
+/// 0 > -X
+impl<U: Unsigned + NonZero> Cmp<NInt<U>> for Z0 {
+    type Output = Greater;
+}
+
+/// 0 < X
+impl<U: Unsigned + NonZero> Cmp<PInt<U>> for Z0 {
+    type Output = Less;
+}
+
+/// X > 0
+impl<U: Unsigned + NonZero> Cmp<Z0> for PInt<U> {
+    type Output = Greater;
+}
+
+/// -X < 0
+impl<U: Unsigned + NonZero> Cmp<Z0> for NInt<U> {
+    type Output = Less;
+}
+
+/// -X < Y
+impl<P: Unsigned + NonZero, N: Unsigned + NonZero> Cmp<PInt<P>> for NInt<N> {
+    type Output = Less;
+}
+
+/// X > - Y
+impl<P: Unsigned + NonZero, N: Unsigned + NonZero> Cmp<NInt<N>> for PInt<P> {
+    type Output = Greater;
+}
+
+/// X <==> Y
+impl<Pl: Cmp<Pr> + Unsigned + NonZero, Pr: Unsigned + NonZero> Cmp<PInt<Pr>> for PInt<Pl> {
+    type Output = <Pl as Cmp<Pr>>::Output;
+}
+
+/// -X <==> -Y
+impl<Nl: Unsigned + NonZero, Nr: Cmp<Nl> + Unsigned + NonZero> Cmp<NInt<Nr>> for NInt<Nl> {
+    type Output = <Nr as Cmp<Nl>>::Output;
+}
+
+macro_rules! test_ord {
+    ($Lhs:ident > $Rhs:ident) => (
+        {
+            type Test = <$Lhs as Cmp<$Rhs>>::Output;
+            assert_eq!(::core::cmp::Ordering::Greater, <Test as Ord>::to_ordering());
+        }
+        );
+    ($Lhs:ident == $Rhs:ident) => (
+        {
+            type Test = <$Lhs as Cmp<$Rhs>>::Output;
+            assert_eq!(::core::cmp::Ordering::Equal, <Test as Ord>::to_ordering());
+        }
+        );
+    ($Lhs:ident < $Rhs:ident) => (
+        {
+            type Test = <$Lhs as Cmp<$Rhs>>::Output;
+            assert_eq!(::core::cmp::Ordering::Less, <Test as Ord>::to_ordering());
+        }
+        );
+}
+
+// ---------------------------------------------------------------------------------------
+// Rem
+
+/// `Z0 % I = Z0` where `I != 0`
+impl<I: Integer + NonZero> Rem<I> for Z0 {
+    type Output = Z0;
+    fn rem(self, _: I) -> Self::Output {
+        Z0
+    }
+}
+
+macro_rules! impl_int_rem {
+    ($A:ident, $B:ident, $R:ident) => (
+        /// `$A<Ul> % $B<Ur> = $R<Ul % Ur>`
+        impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Rem<$B<Ur>> for $A<Ul>
+            where Ul: Rem<Ur>,
+                  $A<Ul>: PrivateRem<<Ul as Rem<Ur>>::Output, $B<Ur>>
+        {
+            type Output = <$A<Ul> as PrivateRem<
+                <Ul as Rem<Ur>>::Output,
+                $B<Ur>>>::Output;
+            fn rem(self, _: $B<Ur>) -> Self::Output {
+                unsafe { ::core::mem::uninitialized() }
+            }
+        }
+        impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> PrivateRem<U0, $B<Ur>> for $A<Ul> {
+            type Output = Z0;
+        }
+        impl<Ul, Ur, U, B> PrivateRem<UInt<U, B>, $B<Ur>> for $A<Ul>
+            where Ul: Unsigned + NonZero, Ur: Unsigned + NonZero, U: Unsigned, B: Bit,
+        {
+            type Output = $R<UInt<U, B>>;
+        }
+        );
+}
+
+impl_int_rem!(PInt, PInt, PInt);
+impl_int_rem!(PInt, NInt, PInt);
+impl_int_rem!(NInt, PInt, NInt);
+impl_int_rem!(NInt, NInt, NInt);
+
+// ---------------------------------------------------------------------------------------
+// Pow
+
+/// 0^0 = 1
+impl Pow<Z0> for Z0 {
+    type Output = P1;
+    fn powi(self, _: Z0) -> Self::Output {
+        P1::new()
+    }
+}
+
+/// 0^P = 0
+impl<U: Unsigned + NonZero> Pow<PInt<U>> for Z0 {
+    type Output = Z0;
+    fn powi(self, _: PInt<U>) -> Self::Output {
+        Z0
+    }
+}
+
+/// 0^N = 0
+impl<U: Unsigned + NonZero> Pow<NInt<U>> for Z0 {
+    type Output = Z0;
+    fn powi(self, _: NInt<U>) -> Self::Output {
+        Z0
+    }
+}
+
+/// 1^N = 1
+impl<U: Unsigned + NonZero> Pow<NInt<U>> for P1 {
+    type Output = P1;
+    fn powi(self, _: NInt<U>) -> Self::Output {
+        P1::new()
+    }
+}
+
+/// (-1)^N = 1 if N is even
+impl<U: Unsigned> Pow<NInt<UInt<U, B0>>> for N1 {
+    type Output = P1;
+    fn powi(self, _: NInt<UInt<U, B0>>) -> Self::Output {
+        P1::new()
+    }
+}
+
+/// (-1)^N = -1 if N is odd
+impl<U: Unsigned> Pow<NInt<UInt<U, B1>>> for N1 {
+    type Output = N1;
+    fn powi(self, _: NInt<UInt<U, B1>>) -> Self::Output {
+        N1::new()
+    }
+}
+
+/// P^0 = 1
+impl<U: Unsigned + NonZero> Pow<Z0> for PInt<U> {
+    type Output = P1;
+    fn powi(self, _: Z0) -> Self::Output {
+        P1::new()
+    }
+}
+
+/// N^0 = 1
+impl<U: Unsigned + NonZero> Pow<Z0> for NInt<U> {
+    type Output = P1;
+    fn powi(self, _: Z0) -> Self::Output {
+        P1::new()
+    }
+}
+
+/// P(Ul)^P(Ur) = P(Ul^Ur)
+impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Pow<PInt<Ur>> for PInt<Ul>
+    where Ul: Pow<Ur>,
+          <Ul as Pow<Ur>>::Output: Unsigned + NonZero
+{
+    type Output = PInt<<Ul as Pow<Ur>>::Output>;
+    fn powi(self, _: PInt<Ur>) -> Self::Output {
+        PInt::new()
+    }
+}
+
+/// N(Ul)^P(Ur) = P(Ul^Ur) if Ur is even
+impl<Ul: Unsigned + NonZero, Ur: Unsigned> Pow<PInt<UInt<Ur, B0>>> for NInt<Ul>
+    where Ul: Pow<UInt<Ur, B0>>,
+          <Ul as Pow<UInt<Ur, B0>>>::Output: Unsigned + NonZero
+{
+    type Output = PInt<<Ul as Pow<UInt<Ur, B0>>>::Output>;
+    fn powi(self, _: PInt<UInt<Ur, B0>>) -> Self::Output {
+        PInt::new()
+    }
+}
+
+/// N(Ul)^P(Ur) = N(Ul^Ur) if Ur is odd
+impl<Ul: Unsigned + NonZero, Ur: Unsigned> Pow<PInt<UInt<Ur, B1>>> for NInt<Ul>
+    where Ul: Pow<UInt<Ur, B1>>,
+          <Ul as Pow<UInt<Ur, B1>>>::Output: Unsigned + NonZero
+{
+    type Output = NInt<<Ul as Pow<UInt<Ur, B1>>>::Output>;
+    fn powi(self, _: PInt<UInt<Ur, B1>>) -> Self::Output {
+        NInt::new()
+    }
+}
+
+// ---------------------------------------------------------------------------------------
+// Min
+use {Min, Minimum, Max, Maximum};
+
+impl Min<Z0> for Z0 {
+    type Output = Z0;
+    fn min(self, _: Z0) -> Self::Output {
+        self
+    }
+}
+
+impl<U> Min<PInt<U>> for Z0
+    where U: Unsigned + NonZero
+{
+    type Output = Z0;
+    fn min(self, _: PInt<U>) -> Self::Output {
+        self
+    }
+}
+
+impl<U> Min<NInt<U>> for Z0
+    where U: Unsigned + NonZero
+{
+    type Output = NInt<U>;
+    fn min(self, rhs: NInt<U>) -> Self::Output {
+        rhs
+    }
+}
+
+impl<U> Min<Z0> for PInt<U>
+    where U: Unsigned + NonZero
+{
+    type Output = Z0;
+    fn min(self, rhs: Z0) -> Self::Output {
+        rhs
+    }
+}
+
+impl<U> Min<Z0> for NInt<U>
+    where U: Unsigned + NonZero
+{
+    type Output = NInt<U>;
+    fn min(self, _: Z0) -> Self::Output {
+        self
+    }
+}
+
+impl<Ul, Ur> Min<PInt<Ur>> for PInt<Ul>
+    where Ul: Unsigned + NonZero + Min<Ur>,
+          Ur: Unsigned + NonZero,
+          Minimum<Ul, Ur>: Unsigned + NonZero
+{
+    type Output = PInt<Minimum<Ul, Ur>>;
+    fn min(self, _: PInt<Ur>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+impl<Ul, Ur> Min<PInt<Ur>> for NInt<Ul>
+    where Ul: Unsigned + NonZero,
+          Ur: Unsigned + NonZero
+{
+    type Output = NInt<Ul>;
+    fn min(self, _: PInt<Ur>) -> Self::Output {
+        self
+    }
+}
+
+impl<Ul, Ur> Min<NInt<Ur>> for PInt<Ul>
+    where Ul: Unsigned + NonZero,
+          Ur: Unsigned + NonZero
+{
+    type Output = NInt<Ur>;
+    fn min(self, rhs: NInt<Ur>) -> Self::Output {
+        rhs
+    }
+}
+
+impl<Ul, Ur> Min<NInt<Ur>> for NInt<Ul>
+    where Ul: Unsigned + NonZero + Max<Ur>,
+          Ur: Unsigned + NonZero,
+          Maximum<Ul, Ur>: Unsigned + NonZero
+{
+    type Output = NInt<Maximum<Ul, Ur>>;
+    fn min(self, _: NInt<Ur>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+// ---------------------------------------------------------------------------------------
+// Max
+
+impl Max<Z0> for Z0 {
+    type Output = Z0;
+    fn max(self, _: Z0) -> Self::Output {
+        self
+    }
+}
+
+impl<U> Max<PInt<U>> for Z0
+    where U: Unsigned + NonZero
+{
+    type Output = PInt<U>;
+    fn max(self, rhs: PInt<U>) -> Self::Output {
+        rhs
+    }
+}
+
+impl<U> Max<NInt<U>> for Z0
+    where U: Unsigned + NonZero
+{
+    type Output = Z0;
+    fn max(self, _: NInt<U>) -> Self::Output {
+        self
+    }
+}
+
+impl<U> Max<Z0> for PInt<U>
+    where U: Unsigned + NonZero
+{
+    type Output = PInt<U>;
+    fn max(self, _: Z0) -> Self::Output {
+        self
+    }
+}
+
+impl<U> Max<Z0> for NInt<U>
+    where U: Unsigned + NonZero
+{
+    type Output = Z0;
+    fn max(self, rhs: Z0) -> Self::Output {
+        rhs
+    }
+}
+
+impl<Ul, Ur> Max<PInt<Ur>> for PInt<Ul>
+    where Ul: Unsigned + NonZero + Max<Ur>,
+          Ur: Unsigned + NonZero,
+          Maximum<Ul, Ur>: Unsigned + NonZero
+{
+    type Output = PInt<Maximum<Ul, Ur>>;
+    fn max(self, _: PInt<Ur>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+impl<Ul, Ur> Max<PInt<Ur>> for NInt<Ul>
+    where Ul: Unsigned + NonZero,
+          Ur: Unsigned + NonZero
+{
+    type Output = PInt<Ur>;
+    fn max(self, rhs: PInt<Ur>) -> Self::Output {
+        rhs
+    }
+}
+
+impl<Ul, Ur> Max<NInt<Ur>> for PInt<Ul>
+    where Ul: Unsigned + NonZero,
+          Ur: Unsigned + NonZero
+{
+    type Output = PInt<Ul>;
+    fn max(self, _: NInt<Ur>) -> Self::Output {
+        self
+    }
+}
+
+impl<Ul, Ur> Max<NInt<Ur>> for NInt<Ul>
+    where Ul: Unsigned + NonZero + Min<Ur>,
+          Ur: Unsigned + NonZero,
+          Minimum<Ul, Ur>: Unsigned + NonZero
+{
+    type Output = NInt<Minimum<Ul, Ur>>;
+    fn max(self, _: NInt<Ur>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
diff --git a/crates/typenum-1.9.0/src/lib.rs b/crates/typenum-1.9.0/src/lib.rs
new file mode 100644
index 0000000..c2756e3
--- /dev/null
+++ b/crates/typenum-1.9.0/src/lib.rs
@@ -0,0 +1,143 @@
+//! This crate provides type-level numbers evaluated at compile time. It depends only on libcore.
+//!
+//! The traits defined or used in this crate are used in a typical manner. They can be divided into
+//! two categories: **marker traits** and **type operators**.
+//!
+//! Many of the marker traits have functions defined, but they all do essentially the same thing:
+//! convert a type into its runtime counterpart, and are really just there for debugging. For
+//! example,
+//!
+//! ```rust
+//! use typenum::{N4, Integer};
+//!
+//! assert_eq!(N4::to_i32(), -4);
+//! ```
+//!
+//! **Type operators** are traits that behave as functions at the type level. These are the meat of
+//! this library. Where possible, traits defined in libcore have been used, but their attached
+//! functions have not been implemented.
+//!
+//! For example, the `Add` trait is implemented for both unsigned and signed integers, but the
+//! `add` function is not. As there are never any objects of the types defined here, it wouldn't
+//! make sense to implement it. What is important is its associated type `Output`, which is where
+//! the addition happens.
+//!
+//! ```rust
+//! use std::ops::Add;
+//! use typenum::{Integer, P3, P4};
+//!
+//! type X = <P3 as Add<P4>>::Output;
+//! assert_eq!(<X as Integer>::to_i32(), 7);
+//! ```
+//!
+//! In addition, helper aliases are defined for type operators. For example, the above snippet
+//! could be replaced with
+//!
+//! ```rust
+//! use typenum::{Sum, Integer, P3, P4};
+//!
+//! type X = Sum<P3, P4>;
+//! assert_eq!(<X as Integer>::to_i32(), 7);
+//! ```
+//!
+//! Documented in each module is the full list of type operators implemented.
+//!
+
+#![no_std]
+#![warn(missing_docs)]
+
+#![cfg_attr(feature="i128", feature(i128_type))]
+
+// For clippy:
+#![cfg_attr(feature="clippy", feature(plugin))]
+#![cfg_attr(feature="clippy", plugin(clippy))]
+
+#![allow(unknown_lints)]
+#![deny(clippy)]
+#![allow(type_complexity, len_without_is_empty)]
+
+// For debugging macros:
+// #![feature(trace_macros)]
+// trace_macros!(true);
+
+use core::cmp::Ordering;
+
+include!(concat!(env!("OUT_DIR"), "/consts.rs"));
+include!(concat!(env!("OUT_DIR"), "/op.rs"));
+pub mod bit;
+pub mod uint;
+pub mod int;
+pub mod private;
+pub mod marker_traits;
+pub mod type_operators;
+pub mod operator_aliases;
+
+pub mod array;
+
+pub use consts::*;
+pub use marker_traits::*;
+pub use type_operators::*;
+pub use operator_aliases::*;
+
+pub use uint::{UInt, UTerm};
+pub use int::{NInt, PInt};
+pub use array::{TArr, ATerm};
+
+/// A potential output from `Cmp`, this is the type equivalent to the enum variant
+/// `core::cmp::Ordering::Greater`.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
+pub struct Greater;
+
+/// A potential output from `Cmp`, this is the type equivalent to the enum variant
+/// `core::cmp::Ordering::Less`.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
+pub struct Less;
+
+/// A potential output from `Cmp`, this is the type equivalent to the enum variant
+/// `core::cmp::Ordering::Equal`.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
+pub struct Equal;
+
+/// Returns `core::cmp::Ordering::Greater`
+impl Ord for Greater {
+    #[inline]
+    fn to_ordering() -> Ordering {
+        Ordering::Greater
+    }
+}
+
+/// Returns `core::cmp::Ordering::Less`
+impl Ord for Less {
+    #[inline]
+    fn to_ordering() -> Ordering {
+        Ordering::Less
+    }
+}
+
+/// Returns `core::cmp::Ordering::Equal`
+impl Ord for Equal {
+    #[inline]
+    fn to_ordering() -> Ordering {
+        Ordering::Equal
+    }
+}
+
+/**
+Asserts that two types are the same.
+*/
+#[macro_export]
+macro_rules! assert_type_eq {
+    ($a:ty, $b:ty) => (
+        let _: <$a as $crate::Same<$b>>::Output;
+    );
+}
+
+/**
+Asserts that a type is `True`, aka `B1`.
+*/
+#[macro_export]
+macro_rules! assert_type {
+    ($a:ty) => (
+        let _: <$a as $crate::Same<True>>::Output;
+    );
+}
diff --git a/crates/typenum-1.9.0/src/marker_traits.rs b/crates/typenum-1.9.0/src/marker_traits.rs
new file mode 100644
index 0000000..443e83c
--- /dev/null
+++ b/crates/typenum-1.9.0/src/marker_traits.rs
@@ -0,0 +1,112 @@
+//! All of the **marker traits** used in typenum.
+//!
+//! Note that the definition here for marker traits is slightly different than the conventional one
+//! -- we include traits with functions that convert a type to the corresponding value.
+//!
+//! For example, the `Integer` trait includes the function (among others) `fn to_i32() ->
+//! i32` so that one can do this:
+//!
+//! ```
+//! use typenum::{N42, Integer};
+//!
+//! assert_eq!(-42, N42::to_i32());
+//! ```
+//!
+//!
+
+/// A **marker trait** to designate that a type is not zero. All number types in this
+/// crate implement `NonZero` except `B0`, `U0`, and `Z0`.
+pub trait NonZero {}
+
+/// A **Marker trait** for the types `Greater`, `Equal`, and `Less`.
+///
+/// This trait should not be implemented for anything outside this crate.
+pub trait Ord {
+    #[allow(missing_docs)]
+    fn to_ordering() -> ::core::cmp::Ordering;
+}
+
+/// The **marker trait** for compile time bits.
+///
+/// This trait should not be implemented for anything outside this crate.
+pub trait Bit {
+    #[allow(missing_docs)]
+    fn to_u8() -> u8;
+    #[allow(missing_docs)]
+    fn to_bool() -> bool;
+}
+
+/// The **marker trait** for compile time unsigned integers.
+///
+/// This trait should not be implemented for anything outside this crate.
+///
+/// # Example
+/// ```rust
+/// use typenum::{U3, Unsigned};
+///
+/// assert_eq!(U3::to_u32(), 3);
+/// ```
+pub trait Unsigned {
+    #[allow(missing_docs)]
+    fn to_u8() -> u8;
+    #[allow(missing_docs)]
+    fn to_u16() -> u16;
+    #[allow(missing_docs)]
+    fn to_u32() -> u32;
+    #[allow(missing_docs)]
+    fn to_u64() -> u64;
+    #[cfg(feature="i128")]
+    #[allow(missing_docs)]
+    fn to_u128() -> u128;
+    #[allow(missing_docs)]
+    fn to_usize() -> usize;
+
+    #[allow(missing_docs)]
+    fn to_i8() -> i8;
+    #[allow(missing_docs)]
+    fn to_i16() -> i16;
+    #[allow(missing_docs)]
+    fn to_i32() -> i32;
+    #[allow(missing_docs)]
+    fn to_i64() -> i64;
+    #[cfg(feature="i128")]
+    #[allow(missing_docs)]
+    fn to_i128() -> i128;
+    #[allow(missing_docs)]
+    fn to_isize() -> isize;
+}
+
+/// The **marker trait** for compile time signed integers.
+///
+/// This trait should not be implemented for anything outside this crate.
+///
+/// # Example
+/// ```rust
+/// use typenum::{P3, Integer};
+///
+/// assert_eq!(P3::to_i32(), 3);
+/// ```
+pub trait Integer {
+    #[allow(missing_docs)]
+    fn to_i8() -> i8;
+    #[allow(missing_docs)]
+    fn to_i16() -> i16;
+    #[allow(missing_docs)]
+    fn to_i32() -> i32;
+    #[allow(missing_docs)]
+    fn to_i64() -> i64;
+    #[cfg(feature="i128")]
+    #[allow(missing_docs)]
+    fn to_i128() -> i128;
+    #[allow(missing_docs)]
+    fn to_isize() -> isize;
+}
+
+/// The **marker trait** for type-level arrays of type-level numbers.
+///
+/// This trait should not be implemented for anything outside this crate.
+///
+/// Someday, it will contain a function or associated constant to produce a runtime array, like the
+/// other marker traits here. However, that requires stabilization of associated consts or of
+/// const functions.
+pub trait TypeArray {}
diff --git a/crates/typenum-1.9.0/src/operator_aliases.rs b/crates/typenum-1.9.0/src/operator_aliases.rs
new file mode 100644
index 0000000..fe8fb9c
--- /dev/null
+++ b/crates/typenum-1.9.0/src/operator_aliases.rs
@@ -0,0 +1,102 @@
+//! Aliases for the type operators used in this crate.
+
+//! Their purpose is to increase the ergonomics of performing operations on the types defined
+//! here. For even more ergonomics, consider using the `op!` macro instead.
+//!
+//! For example, type `X` and type `Y` are the same here:
+//!
+//! ```rust
+//! # #[macro_use] extern crate typenum;
+//! # fn main() {
+//! use std::ops::Mul;
+//! use typenum::{Prod, P5, P7};
+//!
+//! type X = <P7 as Mul<P5>>::Output;
+//! type Y = Prod<P7, P5>;
+//!
+//! assert_type_eq!(X, Y);
+//! # }
+//! ```
+//!
+//!
+
+// Aliases!!!
+use core::ops::{BitAnd, BitOr, BitXor, Shl, Shr, Add, Sub, Mul, Div, Rem, Neg};
+use type_operators::{Abs, Pow, Cmp, Len, PartialDiv, Min, Max};
+
+/// Alias for the associated type of `BitAnd`: `And<A, B> = <A as BitAnd<B>>::Output`
+pub type And<A, B> = <A as BitAnd<B>>::Output;
+/// Alias for the associated type of `BitOr`: `Or<A, B> = <A as BitOr<B>>::Output`
+pub type Or<A, B> = <A as BitOr<B>>::Output;
+/// Alias for the associated type of `BitXor`: `Xor<A, B> = <A as BitXor<B>>::Output`
+pub type Xor<A, B> = <A as BitXor<B>>::Output;
+
+/// Alias for the associated type of `Shl`: `Shleft<A, B> = <A as Shl<B>>::Output`
+pub type Shleft<A, B> = <A as Shl<B>>::Output;
+/// Alias for the associated type of `Shr`: `Shright<A, B> = <A as Shr<B>>::Output`
+pub type Shright<A, B> = <A as Shr<B>>::Output;
+
+
+/// Alias for the associated type of `Add`: `Sum<A, B> = <A as Add<B>>::Output`
+pub type Sum<A, B> = <A as Add<B>>::Output;
+/// Alias for the associated type of `Sub`: `Diff<A, B> = <A as Sub<B>>::Output`
+pub type Diff<A, B> = <A as Sub<B>>::Output;
+/// Alias for the associated type of `Mul`: `Prod<A, B> = <A as Mul<B>>::Output`
+pub type Prod<A, B> = <A as Mul<B>>::Output;
+/// Alias for the associated type of `Div`: `Quot<A, B> = <A as Div<B>>::Output`
+pub type Quot<A, B> = <A as Div<B>>::Output;
+/// Alias for the associated type of `Rem`: `Mod<A, B> = <A as Rem<B>>::Output`
+pub type Mod<A, B> = <A as Rem<B>>::Output;
+
+/// Alias for the associated type of
+/// `PartialDiv`: `PartialQuot<A, B> = <A as PartialDiv<B>>::Output`
+pub type PartialQuot<A, B> = <A as PartialDiv<B>>::Output;
+
+/// Alias for the associated type of `Neg`: `Negate<A> = <A as Neg>::Output`
+pub type Negate<A> = <A as Neg>::Output;
+
+/// Alias for the associated type of `Abs`: `AbsVal<A> = <A as Abs>::Output`
+pub type AbsVal<A> = <A as Abs>::Output;
+
+/// Alias for the associated type of `Pow`: `Exp<A, B> = <A as Pow<B>>::Output`
+pub type Exp<A, B> = <A as Pow<B>>::Output;
+
+
+/// Alias to make it easy to add 1: `Add1<A> = <A as Add<B1>>::Output`
+pub type Add1<A> = <A as Add<::bit::B1>>::Output;
+/// Alias to make it easy to subtract 1: `Sub1<A> = <A as Sub<B1>>::Output`
+pub type Sub1<A> = <A as Sub<::bit::B1>>::Output;
+
+/// Alias to make it easy to square. `Square<A> = <A as Mul<A>>::Output`
+pub type Square<A> = <A as Mul>::Output;
+/// Alias to make it easy to square. `Cube<A> = <Square<A> as Mul<A>>::Output`
+pub type Cube<A> = <Square<A> as Mul<A>>::Output;
+
+/// Alias for the associated type of `Cmp`: `Compare<A, B> = <A as Cmp<B>>::Output`
+pub type Compare<A, B> = <A as Cmp<B>>::Output;
+
+/// Alias for the associated type of `Len`: `Length<A> = <A as Len>::Output`
+pub type Length<T> = <T as Len>::Output;
+
+
+/// Alias for the associated type of `Min`: `Minimum<A, B> = <A as Min<B>>::Output`
+pub type Minimum<A, B> = <A as Min<B>>::Output;
+
+/// Alias for the associated type of `Max`: `Maximum<A, B> = <A as Max<B>>::Output`
+pub type Maximum<A, B> = <A as Max<B>>::Output;
+
+
+use type_operators::{IsLess, IsEqual, IsGreater, IsGreaterOrEqual, IsLessOrEqual, IsNotEqual};
+/// Alias for the associated type of `IsLess`: `Le<A, B> = <A as IsLess<B>>::Output`
+pub type Le<A, B> = <A as IsLess<B>>::Output;
+/// Alias for the associated type of `IsEqual`: `Eq<A, B> = <A as IsEqual<B>>::Output`
+pub type Eq<A, B> = <A as IsEqual<B>>::Output;
+/// Alias for the associated type of `IsGreater`: `Gr<A, B> = <A as IsGreater<B>>::Output`
+pub type Gr<A, B> = <A as IsGreater<B>>::Output;
+/// Alias for the associated type of `IsGreaterOrEqual`:
+/// `GrEq<A, B> = <A as IsGreaterOrEqual<B>>::Output`
+pub type GrEq<A, B> = <A as IsGreaterOrEqual<B>>::Output;
+/// Alias for the associated type of `IsLessOrEqual`: `LeEq<A, B> = <A as IsLessOrEqual<B>>::Output`
+pub type LeEq<A, B> = <A as IsLessOrEqual<B>>::Output;
+/// Alias for the associated type of `IsNotEqual`: `NotEq<A, B> = <A as IsNotEqual<B>>::Output`
+pub type NotEq<A, B> = <A as IsNotEqual<B>>::Output;
diff --git a/crates/typenum-1.9.0/src/private.rs b/crates/typenum-1.9.0/src/private.rs
new file mode 100644
index 0000000..2eb61dc
--- /dev/null
+++ b/crates/typenum-1.9.0/src/private.rs
@@ -0,0 +1,371 @@
+//! **Ignore me!** This module is for things that are conceptually private but that must
+//! be made public for typenum to work correctly.
+//!
+//! Unless you are working on typenum itself, **there is no need to view anything here**.
+//!
+//! Certainly don't implement any of the traits here for anything.
+//!
+//!
+//! Just look away.
+//!
+//!
+//! Loooooooooooooooooooooooooooooooooook awaaaaaaaaaaaayyyyyyyyyyyyyyyyyyyyyyyyyyyyy...
+//!
+//!
+//! If you do manage to find something of use in here, please let me know. If you can make a
+//! compelling case, it may be moved out of __private.
+//!
+//! Note: Aliases for private type operators will all be named simply that operator followed
+//! by an abbreviated name of its associated type.
+//!
+
+#![doc(hidden)]
+
+// use ::{Sub};
+use bit::{Bit, B1, B0};
+use uint::{Unsigned, UInt, UTerm};
+
+/// Convenience trait. Calls `Invert` -> `TrimTrailingZeros` -> `Invert`
+pub trait Trim {
+    type Output;
+}
+pub type TrimOut<A> = <A as Trim>::Output;
+
+/// Gets rid of all zeros until it hits a one.
+
+// ONLY IMPLEMENT FOR INVERTED NUMBERS!
+pub trait TrimTrailingZeros {
+    type Output;
+}
+pub type TrimTrailingZerosOut<A> = <A as TrimTrailingZeros>::Output;
+
+/// Converts between standard numbers and inverted ones that have the most significant
+/// digit on the outside.
+pub trait Invert {
+    type Output;
+}
+pub type InvertOut<A> = <A as Invert>::Output;
+
+/// Doubly private! Called by invert to make the magic happen once its done the first step.
+/// The Rhs is what we've got so far.
+pub trait PrivateInvert<Rhs> {
+    type Output;
+}
+pub type PrivateInvertOut<A, Rhs> = <A as PrivateInvert<Rhs>>::Output;
+
+/// Terminating character for `InvertedUInt`s
+pub enum InvertedUTerm {}
+
+/// Inverted `UInt` (has most significant digit on the outside)
+pub struct InvertedUInt<IU: InvertedUnsigned, B: Bit> {
+    _marker: (IU, B),
+}
+
+/// Does the real anding for `UInt`s; `And` just calls this and then `Trim`.
+pub trait PrivateAnd<Rhs = Self> {
+    type Output;
+}
+pub type PrivateAndOut<A, Rhs> = <A as PrivateAnd<Rhs>>::Output;
+
+/// Does the real xoring for `UInt`s; `Xor` just calls this and then `Trim`.
+pub trait PrivateXor<Rhs = Self> {
+    type Output;
+}
+pub type PrivateXorOut<A, Rhs> = <A as PrivateXor<Rhs>>::Output;
+
+/// Does the real subtraction for `UInt`s; `Sub` just calls this and then `Trim`.
+pub trait PrivateSub<Rhs = Self> {
+    type Output;
+}
+pub type PrivateSubOut<A, Rhs> = <A as PrivateSub<Rhs>>::Output;
+
+/// Used for addition of signed integers; `C = P.cmp(N)`
+/// Assumes `P = Self` is positive and `N` is negative
+/// where `P` and `N` are both passed as unsigned integers
+pub trait PrivateIntegerAdd<C, N> {
+    type Output;
+}
+pub type PrivateIntegerAddOut<P, C, N> = <P as PrivateIntegerAdd<C, N>>::Output;
+
+pub trait PrivatePow<Y, N> {
+    type Output;
+}
+pub type PrivatePowOut<A, Y, N> = <A as PrivatePow<Y, N>>::Output;
+
+/// Performs `Shl` on `Lhs` so that `SizeOf(Lhs) = SizeOf(Rhs)`
+/// Fails if `SizeOf(Lhs) > SizeOf(Rhs)`
+pub trait ShiftDiff<Rhs> {
+    type Output;
+}
+pub type ShiftDiffOut<A, Rhs> = <A as ShiftDiff<Rhs>>::Output;
+
+/// Gives `SizeOf(Lhs) - SizeOf(Rhs)`
+pub trait BitDiff<Rhs> {
+    type Output;
+}
+pub type BitDiffOut<A, Rhs> = <A as BitDiff<Rhs>>::Output;
+
+/// Inverted unsigned numbers
+pub trait InvertedUnsigned {
+    fn to_u64() -> u64;
+}
+
+impl InvertedUnsigned for InvertedUTerm {
+    fn to_u64() -> u64 {
+        0
+    }
+}
+
+impl<IU: InvertedUnsigned, B: Bit> InvertedUnsigned for InvertedUInt<IU, B> {
+    fn to_u64() -> u64 {
+        B::to_u8() as u64 | IU::to_u64() << 1
+    }
+}
+
+impl Invert for UTerm {
+    type Output = InvertedUTerm;
+}
+
+impl<U: Unsigned, B: Bit> Invert for UInt<U, B>
+    where U: PrivateInvert<InvertedUInt<InvertedUTerm, B>>
+{
+    type Output = PrivateInvertOut<U, InvertedUInt<InvertedUTerm, B>>;
+}
+
+
+impl<IU: InvertedUnsigned> PrivateInvert<IU> for UTerm {
+    type Output = IU;
+}
+
+impl<IU: InvertedUnsigned, U: Unsigned, B: Bit> PrivateInvert<IU> for UInt<U, B>
+    where U: PrivateInvert<InvertedUInt<IU, B>>
+{
+    type Output = PrivateInvertOut<U, InvertedUInt<IU, B>>;
+}
+
+#[test]
+fn test_inversion() {
+    type Test4 = <::consts::U4 as Invert>::Output;
+    type Test5 = <::consts::U5 as Invert>::Output;
+    type Test12 = <::consts::U12 as Invert>::Output;
+    type Test16 = <::consts::U16 as Invert>::Output;
+
+    assert_eq!(1, <Test4 as InvertedUnsigned>::to_u64());
+    assert_eq!(5, <Test5 as InvertedUnsigned>::to_u64());
+    assert_eq!(3, <Test12 as InvertedUnsigned>::to_u64());
+    assert_eq!(1, <Test16 as InvertedUnsigned>::to_u64());
+}
+
+impl Invert for InvertedUTerm {
+    type Output = UTerm;
+}
+
+impl<IU: InvertedUnsigned, B: Bit> Invert for InvertedUInt<IU, B>
+    where IU: PrivateInvert<UInt<UTerm, B>>
+{
+    type Output = <IU as PrivateInvert<UInt<UTerm, B>>>::Output;
+}
+
+impl<U: Unsigned> PrivateInvert<U> for InvertedUTerm {
+    type Output = U;
+}
+
+impl<U: Unsigned, IU: InvertedUnsigned, B: Bit> PrivateInvert<U> for InvertedUInt<IU, B>
+    where IU: PrivateInvert<UInt<U, B>>
+{
+    type Output = <IU as PrivateInvert<UInt<U, B>>>::Output;
+}
+
+#[test]
+fn test_double_inversion() {
+    type Test4 =
+        <<::consts::U4 as Invert>::Output as Invert>::Output;
+    type Test5 =
+        <<::consts::U5 as Invert>::Output as Invert>::Output;
+    type Test12 =
+        <<::consts::U12 as Invert>::Output as Invert>::Output;
+    type Test16 =
+        <<::consts::U16 as Invert>::Output as Invert>::Output;
+
+    assert_eq!(4, <Test4 as Unsigned>::to_u64());
+    assert_eq!(5, <Test5 as Unsigned>::to_u64());
+    assert_eq!(12, <Test12 as Unsigned>::to_u64());
+    assert_eq!(16, <Test16 as Unsigned>::to_u64());
+}
+
+impl TrimTrailingZeros for InvertedUTerm {
+    type Output = InvertedUTerm;
+}
+
+impl<IU: InvertedUnsigned> TrimTrailingZeros for InvertedUInt<IU, B1> {
+    type Output = Self;
+}
+
+impl<IU: InvertedUnsigned> TrimTrailingZeros for InvertedUInt<IU, B0>
+    where IU: TrimTrailingZeros
+{
+    type Output = <IU as TrimTrailingZeros>::Output;
+}
+
+impl<U: Unsigned> Trim for U
+    where U: Invert,
+          <U as Invert>::Output: TrimTrailingZeros,
+          <<U as Invert>::Output as TrimTrailingZeros>::Output: Invert
+{
+    type Output = <<<U as Invert>::Output as TrimTrailingZeros>::Output as Invert>::Output;
+}
+
+// Note: Trimming is tested when we do subtraction.
+
+pub trait PrivateCmp<Rhs, SoFar> {
+    type Output;
+}
+pub type PrivateCmpOut<A, Rhs, SoFar> = <A as PrivateCmp<Rhs, SoFar>>::Output;
+
+
+// Set Bit
+pub trait PrivateSetBit<I, B> {
+    type Output;
+}
+pub type PrivateSetBitOut<N, I, B> = <N as PrivateSetBit<I, B>>::Output;
+
+// Div
+pub trait PrivateDiv<N, D, Q, R, I> {
+    type Quotient;
+    type Remainder;
+}
+
+pub type PrivateDivQuot<N, D, Q, R, I> = <() as PrivateDiv<N, D, Q, R, I>>::Quotient;
+pub type PrivateDivRem<N, D, Q, R, I> = <() as PrivateDiv<N, D, Q, R, I>>::Remainder;
+
+pub trait PrivateDivIf<N, D, Q, R, I, RcmpD> {
+    type Quotient;
+    type Remainder;
+}
+
+pub type PrivateDivIfQuot<N, D, Q, R, I, RcmpD> = <() as PrivateDivIf<N,
+                                                                             D,
+                                                                             Q,
+                                                                             R,
+                                                                             I,
+                                                                             RcmpD>>::Quotient;
+pub type PrivateDivIfRem<N, D, Q, R, I, RcmpD> = <() as PrivateDivIf<N,
+                                                                            D,
+                                                                            Q,
+                                                                            R,
+                                                                            I,
+                                                                            RcmpD>>::Remainder;
+
+// Div for signed ints
+pub trait PrivateDivInt<C, Divisor> {
+    type Output;
+}
+pub type PrivateDivIntOut<A, C, Divisor> = <A as PrivateDivInt<C, Divisor>>::Output;
+
+pub trait PrivateRem<URem, Divisor> {
+    type Output;
+}
+pub type PrivateRemOut<A, URem, Divisor> = <A as PrivateRem<URem, Divisor>>::Output;
+
+
+// min max
+pub trait PrivateMin<Rhs, CmpResult> {
+    type Output;
+    fn private_min(self, rhs: Rhs) -> Self::Output;
+}
+pub type PrivateMinOut<A, B, CmpResult> = <A as PrivateMin<B, CmpResult>>::Output;
+
+pub trait PrivateMax<Rhs, CmpResult> {
+    type Output;
+    fn private_max(self, rhs: Rhs) -> Self::Output;
+}
+pub type PrivateMaxOut<A, B, CmpResult> = <A as PrivateMax<B, CmpResult>>::Output;
+
+
+// Comparisons
+
+use {True, False, Greater, Less, Equal};
+
+pub trait IsLessPrivate<Rhs, Cmp> {
+    type Output: Bit;
+}
+
+impl<A, B> IsLessPrivate<B, Less> for A {
+    type Output = True;
+}
+impl<A, B> IsLessPrivate<B, Equal> for A {
+    type Output = False;
+}
+impl<A, B> IsLessPrivate<B, Greater> for A {
+    type Output = False;
+}
+
+pub trait IsEqualPrivate<Rhs, Cmp> {
+    type Output: Bit;
+}
+
+impl<A, B> IsEqualPrivate<B, Less> for A {
+    type Output = False;
+}
+impl<A, B> IsEqualPrivate<B, Equal> for A {
+    type Output = True;
+}
+impl<A, B> IsEqualPrivate<B, Greater> for A {
+    type Output = False;
+}
+
+pub trait IsGreaterPrivate<Rhs, Cmp> {
+    type Output: Bit;
+}
+
+impl<A, B> IsGreaterPrivate<B, Less> for A {
+    type Output = False;
+}
+impl<A, B> IsGreaterPrivate<B, Equal> for A {
+    type Output = False;
+}
+impl<A, B> IsGreaterPrivate<B, Greater> for A {
+    type Output = True;
+}
+
+pub trait IsLessOrEqualPrivate<Rhs, Cmp> {
+    type Output: Bit;
+}
+
+impl<A, B> IsLessOrEqualPrivate<B, Less> for A {
+    type Output = True;
+}
+impl<A, B> IsLessOrEqualPrivate<B, Equal> for A {
+    type Output = True;
+}
+impl<A, B> IsLessOrEqualPrivate<B, Greater> for A {
+    type Output = False;
+}
+
+pub trait IsNotEqualPrivate<Rhs, Cmp> {
+    type Output: Bit;
+}
+
+impl<A, B> IsNotEqualPrivate<B, Less> for A {
+    type Output = True;
+}
+impl<A, B> IsNotEqualPrivate<B, Equal> for A {
+    type Output = False;
+}
+impl<A, B> IsNotEqualPrivate<B, Greater> for A {
+    type Output = True;
+}
+
+pub trait IsGreaterOrEqualPrivate<Rhs, Cmp> {
+    type Output: Bit;
+}
+
+impl<A, B> IsGreaterOrEqualPrivate<B, Less> for A {
+    type Output = False;
+}
+impl<A, B> IsGreaterOrEqualPrivate<B, Equal> for A {
+    type Output = True;
+}
+impl<A, B> IsGreaterOrEqualPrivate<B, Greater> for A {
+    type Output = True;
+}
diff --git a/crates/typenum-1.9.0/src/type_operators.rs b/crates/typenum-1.9.0/src/type_operators.rs
new file mode 100644
index 0000000..24a528d
--- /dev/null
+++ b/crates/typenum-1.9.0/src/type_operators.rs
@@ -0,0 +1,499 @@
+//! Useful **type operators** that are not defined in `core::ops`.
+//!
+
+use {Unsigned, Bit, UInt, PInt, NInt, NonZero, UTerm, Z0};
+
+/// A **type operator** that ensures that `Rhs` is the same as `Self`, it is mainly useful
+/// for writing macros that can take arbitrary binary or unary operators.
+///
+/// `Same` is implemented generically for all types; it should never need to be implemented
+/// for anything else.
+///
+/// Note that Rust lazily evaluates types, so this will only fail for two different types if
+/// the `Output` is used.
+///
+/// # Example
+/// ```rust
+/// use typenum::{Same, U4, U5, Unsigned};
+///
+/// assert_eq!(<U5 as Same<U5>>::Output::to_u32(), 5);
+///
+/// // Only an error if we use it:
+/// # #[allow(dead_code)]
+/// type Undefined = <U5 as Same<U4>>::Output;
+/// // Compiler error:
+/// // Undefined::to_u32();
+/// ```
+pub trait Same<Rhs = Self> {
+    /// Should always be `Self`
+    type Output;
+}
+
+impl<T> Same<T> for T {
+    type Output = T;
+}
+
+/// A **type operator** that returns the absolute value.
+///
+/// # Example
+/// ```rust
+/// use typenum::{Abs, N5, Integer};
+///
+/// assert_eq!(<N5 as Abs>::Output::to_i32(), 5);
+/// ```
+pub trait Abs {
+    /// The absolute value.
+    type Output;
+}
+
+impl Abs for Z0 {
+    type Output = Z0;
+}
+
+impl<U: Unsigned + NonZero> Abs for PInt<U> {
+    type Output = Self;
+}
+
+impl<U: Unsigned + NonZero> Abs for NInt<U> {
+    type Output = PInt<U>;
+}
+
+/// A **type operator** that provides exponentiation by repeated squaring.
+///
+/// # Example
+/// ```rust
+/// use typenum::{Pow, N3, P3, Integer};
+///
+/// assert_eq!(<N3 as Pow<P3>>::Output::to_i32(), -27);
+/// ```
+pub trait Pow<Exp> {
+    /// The result of the exponentiation.
+    type Output;
+    /// This function isn't used in this crate, but may be useful for others.
+    /// It is implemented for primitives.
+    ///
+    /// # Example
+    /// ```rust
+    /// use typenum::{Pow, U3};
+    ///
+    /// let a = 7u32.powi(U3::new());
+    /// let b = 7u32.pow(3);
+    /// assert_eq!(a, b);
+    ///
+    /// let x = 3.0.powi(U3::new());
+    /// let y = 27.0;
+    /// assert_eq!(x, y);
+    /// ```
+    fn powi(self, exp: Exp) -> Self::Output;
+}
+
+macro_rules! impl_pow_f {
+    ($t: ty) => (
+        impl Pow<UTerm> for $t {
+            type Output = $t;
+            #[inline]
+            fn powi(self, _: UTerm) -> Self::Output {
+                1.0
+            }
+        }
+
+        impl<U: Unsigned, B: Bit> Pow<UInt<U, B>> for $t {
+            type Output = $t;
+            // powi is unstable in core, so we have to write this function ourselves.
+            // copied from num::pow::pow
+            #[inline]
+            fn powi(self, _: UInt<U, B>) -> Self::Output {
+                let mut exp = <UInt<U, B> as Unsigned>::to_u32();
+                let mut base = self;
+
+                if exp == 0 { return 1.0 }
+
+                while exp & 1 == 0 {
+                    base *= base;
+                    exp >>= 1;
+                }
+                if exp == 1 { return base }
+
+                let mut acc = base.clone();
+                while exp > 1 {
+                    exp >>= 1;
+                    base *= base;
+                    if exp & 1 == 1 {
+                        acc *= base.clone();
+                    }
+                }
+                acc
+            }
+        }
+
+        impl Pow<Z0> for $t {
+            type Output = $t;
+            #[inline]
+            fn powi(self, _: Z0) -> Self::Output {
+                1.0
+            }
+        }
+
+        impl<U: Unsigned + NonZero> Pow<PInt<U>> for $t {
+            type Output = $t;
+            // powi is unstable in core, so we have to write this function ourselves.
+            // copied from num::pow::pow
+            #[inline]
+            fn powi(self, _: PInt<U>) -> Self::Output {
+                let mut exp = U::to_u32();
+                let mut base = self;
+
+                if exp == 0 { return 1.0 }
+
+                while exp & 1 == 0 {
+                    base *= base;
+                    exp >>= 1;
+                }
+                if exp == 1 { return base }
+
+                let mut acc = base.clone();
+                while exp > 1 {
+                    exp >>= 1;
+                    base *= base;
+                    if exp & 1 == 1 {
+                        acc *= base.clone();
+                    }
+                }
+                acc
+            }
+        }
+    );
+}
+
+impl_pow_f!(f32);
+impl_pow_f!(f64);
+
+
+macro_rules! impl_pow_i {
+    () => ();
+    ($t: ty $(, $tail:tt)*) => (
+        impl Pow<UTerm> for $t {
+            type Output = $t;
+            #[inline]
+            fn powi(self, _: UTerm) -> Self::Output {
+                1
+            }
+        }
+
+        impl<U: Unsigned, B: Bit> Pow<UInt<U, B>> for $t {
+            type Output = $t;
+            #[inline]
+            fn powi(self, _: UInt<U, B>) -> Self::Output {
+                self.pow(<UInt<U, B> as Unsigned>::to_u32())
+            }
+        }
+
+        impl Pow<Z0> for $t {
+            type Output = $t;
+            #[inline]
+            fn powi(self, _: Z0) -> Self::Output {
+                1
+            }
+        }
+
+        impl<U: Unsigned + NonZero> Pow<PInt<U>> for $t {
+            type Output = $t;
+            #[inline]
+            fn powi(self, _: PInt<U>) -> Self::Output {
+                self.pow(U::to_u32())
+            }
+        }
+
+        impl_pow_i!($($tail),*);
+    );
+}
+
+impl_pow_i!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize);
+#[cfg(feature="i128")]
+impl_pow_i!(u128, i128);
+
+#[test]
+fn pow_test() {
+    use consts::*;
+    let z0 = Z0::new();
+    let p3 = P3::new();
+
+    let u0 = U0::new();
+    let u3 = U3::new();
+
+    macro_rules! check {
+        ($x:ident) => (
+            assert_eq!($x.powi(z0), 1);
+            assert_eq!($x.powi(u0), 1);
+
+            assert_eq!($x.powi(p3), $x*$x*$x);
+            assert_eq!($x.powi(u3), $x*$x*$x);
+        );
+        ($x:ident, $f:ident) => (
+            assert!((<$f as Pow<Z0>>::powi(*$x, z0) - 1.0).abs() < ::core::$f::EPSILON);
+            assert!((<$f as Pow<U0>>::powi(*$x, u0) - 1.0).abs() < ::core::$f::EPSILON);
+
+            assert!((<$f as Pow<P3>>::powi(*$x, p3) - $x*$x*$x).abs() < ::core::$f::EPSILON);
+            assert!((<$f as Pow<U3>>::powi(*$x, u3) - $x*$x*$x).abs() < ::core::$f::EPSILON);
+        );
+    }
+
+    for x in &[0i8, -3, 2] {
+        check!(x);
+    }
+    for x in &[0u8, 1, 5] {
+        check!(x);
+    }
+    for x in &[0usize, 1, 5, 40] {
+        check!(x);
+    }
+    for x in &[0isize, 1, 2, -30, -22, 48] {
+        check!(x);
+    }
+    for x in &[0.0f32, 2.2, -3.5, 378.223] {
+        check!(x, f32);
+    }
+    for x in &[0.0f64, 2.2, -3.5, -2387.2, 234.22] {
+        check!(x, f64);
+    }
+}
+
+
+/// A **type operator** for comparing `Self` and `Rhs`. It provides a similar functionality to
+/// the function
+/// [`core::cmp::Ord::cmp`](https://doc.rust-lang.org/nightly/core/cmp/trait.Ord.html#tymethod.cmp)
+/// but for types.
+///
+/// # Example
+/// ```rust
+/// use typenum::{Cmp, Ord, N3, P2, P5};
+/// use std::cmp::Ordering;
+///
+/// assert_eq!(<P2 as Cmp<N3>>::Output::to_ordering(), Ordering::Greater);
+/// assert_eq!(<P2 as Cmp<P2>>::Output::to_ordering(), Ordering::Equal);
+/// assert_eq!(<P2 as Cmp<P5>>::Output::to_ordering(), Ordering::Less);
+pub trait Cmp<Rhs = Self> {
+    /// The result of the comparison. It should only ever be one of `Greater`, `Less`, or `Equal`.
+    type Output;
+}
+
+/// A **type operator** that gives the length of an `Array` or the number of bits in a `UInt`.
+pub trait Len {
+    /// The length as a type-level unsigned integer.
+    type Output: ::Unsigned;
+    /// This function isn't used in this crate, but may be useful for others.
+    fn len(&self) -> Self::Output;
+}
+
+/// Division as a partial function. This **type operator** performs division just as `Div`, but is
+/// only defined when the result is an integer (i.e. there is no remainder).
+pub trait PartialDiv<Rhs = Self> {
+    /// The type of the result of the division
+    type Output;
+    /// Method for performing the division
+    fn partial_div(self, _: Rhs) -> Self::Output;
+}
+
+
+/// A **type operator** that returns the minimum of `Self` and `Rhs`.
+pub trait Min<Rhs = Self> {
+    /// The type of the minimum of `Self` and `Rhs`
+    type Output;
+    /// Method returning the minimum
+    fn min(self, rhs: Rhs) -> Self::Output;
+}
+
+/// A **type operator** that returns the maximum of `Self` and `Rhs`.
+pub trait Max<Rhs = Self> {
+    /// The type of the maximum of `Self` and `Rhs`
+    type Output;
+    /// Method returning the maximum
+    fn max(self, rhs: Rhs) -> Self::Output;
+}
+
+use Compare;
+
+/// A **type operator** that returns `True` if `Self < Rhs`, otherwise returns `False`.
+pub trait IsLess<Rhs = Self> {
+    /// The type representing either `True` or `False`
+    type Output: Bit;
+    /// Method returning `True` or `False`.
+    fn is_less(self, rhs: Rhs) -> Self::Output;
+}
+
+use private::IsLessPrivate;
+impl<A, B> IsLess<B> for A
+    where A: Cmp<B> + IsLessPrivate<B, Compare<A, B>>
+{
+    type Output = <A as IsLessPrivate<B, Compare<A, B>>>::Output;
+
+    fn is_less(self, _: B) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+/// A **type operator** that returns `True` if `Self == Rhs`, otherwise returns `False`.
+pub trait IsEqual<Rhs = Self> {
+    /// The type representing either `True` or `False`
+    type Output: Bit;
+    /// Method returning `True` or `False`.
+    fn is_equal(self, rhs: Rhs) -> Self::Output;
+}
+
+use private::IsEqualPrivate;
+impl<A, B> IsEqual<B> for A
+    where A: Cmp<B> + IsEqualPrivate<B, Compare<A, B>>
+{
+    type Output = <A as IsEqualPrivate<B, Compare<A, B>>>::Output;
+
+    fn is_equal(self, _: B) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+
+/// A **type operator** that returns `True` if `Self > Rhs`, otherwise returns `False`.
+pub trait IsGreater<Rhs = Self> {
+    /// The type representing either `True` or `False`
+    type Output: Bit;
+    /// Method returning `True` or `False`.
+    fn is_greater(self, rhs: Rhs) -> Self::Output;
+}
+
+use private::IsGreaterPrivate;
+impl<A, B> IsGreater<B> for A
+    where A: Cmp<B> + IsGreaterPrivate<B, Compare<A, B>>
+{
+    type Output = <A as IsGreaterPrivate<B, Compare<A, B>>>::Output;
+
+    fn is_greater(self, _: B) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+/// A **type operator** that returns `True` if `Self <= Rhs`, otherwise returns `False`.
+pub trait IsLessOrEqual<Rhs = Self> {
+    /// The type representing either `True` or `False`
+    type Output: Bit;
+    /// Method returning `True` or `False`.
+    fn is_less_or_equal(self, rhs: Rhs) -> Self::Output;
+}
+
+use private::IsLessOrEqualPrivate;
+impl<A, B> IsLessOrEqual<B> for A
+    where A: Cmp<B> + IsLessOrEqualPrivate<B, Compare<A, B>>
+{
+    type Output = <A as IsLessOrEqualPrivate<B, Compare<A, B>>>::Output;
+
+    fn is_less_or_equal(self, _: B) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+/// A **type operator** that returns `True` if `Self != Rhs`, otherwise returns `False`.
+pub trait IsNotEqual<Rhs = Self> {
+    /// The type representing either `True` or `False`
+    type Output: Bit;
+    /// Method returning `True` or `False`.
+    fn is_not_equal(self, rhs: Rhs) -> Self::Output;
+}
+
+use private::IsNotEqualPrivate;
+impl<A, B> IsNotEqual<B> for A
+    where A: Cmp<B> + IsNotEqualPrivate<B, Compare<A, B>>
+{
+    type Output = <A as IsNotEqualPrivate<B, Compare<A, B>>>::Output;
+
+    fn is_not_equal(self, _: B) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+/// A **type operator** that returns `True` if `Self >= Rhs`, otherwise returns `False`.
+pub trait IsGreaterOrEqual<Rhs = Self> {
+    /// The type representing either `True` or `False`
+    type Output: Bit;
+    /// Method returning `True` or `False`.
+    fn is_greater_or_equal(self, rhs: Rhs) -> Self::Output;
+}
+
+use private::IsGreaterOrEqualPrivate;
+impl<A, B> IsGreaterOrEqual<B> for A
+    where A: Cmp<B> + IsGreaterOrEqualPrivate<B, Compare<A, B>>
+{
+    type Output = <A as IsGreaterOrEqualPrivate<B, Compare<A, B>>>::Output;
+
+    fn is_greater_or_equal(self, _: B) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+
+/**
+A convenience macro for comparing type numbers. Use `op!` instead.
+
+Due to the intricacies of the macro system, if the left-hand operand is more complex than a simple
+`ident`, you must place a comma between it and the comparison sign.
+
+For example, you can do `cmp!(P5 > P3)` or `cmp!(typenum::P5, > typenum::P3)` but not
+`cmp!(typenum::P5 > typenum::P3)`.
+
+The result of this comparison will always be one of `True` (aka `B1`) or `False` (aka `B0`).
+
+# Example
+```rust
+#[macro_use] extern crate typenum;
+use typenum::consts::*;
+use typenum::Bit;
+
+fn main() {
+type Result = cmp!(P9 == op!(P1 + P2 * (P2 - N2)));
+assert_eq!(Result::to_bool(), true);
+}
+```
+ */
+#[deprecated(since="1.9.0", note="use the `op!` macro instead")]
+#[macro_export]
+macro_rules! cmp {
+    ($a:ident < $b:ty) => (
+        <$a as $crate::IsLess<$b>>::Output
+    );
+    ($a:ty, < $b:ty) => (
+        <$a as $crate::IsLess<$b>>::Output
+    );
+
+    ($a:ident == $b:ty) => (
+        <$a as $crate::IsEqual<$b>>::Output
+    );
+    ($a:ty, == $b:ty) => (
+        <$a as $crate::IsEqual<$b>>::Output
+    );
+
+    ($a:ident > $b:ty) => (
+        <$a as $crate::IsGreater<$b>>::Output
+    );
+    ($a:ty, > $b:ty) => (
+        <$a as $crate::IsGreater<$b>>::Output
+    );
+
+    ($a:ident <= $b:ty) => (
+        <$a as $crate::IsLessOrEqual<$b>>::Output
+    );
+    ($a:ty, <= $b:ty) => (
+        <$a as $crate::IsLessOrEqual<$b>>::Output
+    );
+
+    ($a:ident != $b:ty) => (
+        <$a as $crate::IsNotEqual<$b>>::Output
+    );
+    ($a:ty, != $b:ty) => (
+        <$a as $crate::IsNotEqual<$b>>::Output
+    );
+
+    ($a:ident >= $b:ty) => (
+        <$a as $crate::IsGreaterOrEqual<$b>>::Output
+    );
+    ($a:ty, >= $b:ty) => (
+        <$a as $crate::IsGreaterOrEqual<$b>>::Output
+    );
+}
diff --git a/crates/typenum-1.9.0/src/uint.rs b/crates/typenum-1.9.0/src/uint.rs
new file mode 100644
index 0000000..973c92d
--- /dev/null
+++ b/crates/typenum-1.9.0/src/uint.rs
@@ -0,0 +1,1499 @@
+//! Type-level unsigned integers.
+//!
+//!
+//! **Type operators** implemented:
+//!
+//! From `core::ops`: `BitAnd`, `BitOr`, `BitXor`, `Shl`, `Shr`, `Add`, `Sub`,
+//!                 `Mul`, `Div`, and `Rem`.
+//! From `typenum`: `Same`, `Cmp`, and `Pow`.
+//!
+//! Rather than directly using the structs defined in this module, it is recommended that
+//! you import and use the relevant aliases from the [consts](../consts/index.html) module.
+//!
+//! # Example
+//! ```rust
+//! use std::ops::{BitAnd, BitOr, BitXor, Shl, Shr, Add, Sub, Mul, Div, Rem};
+//! use typenum::{Unsigned, U1, U2, U3, U4};
+//!
+//! assert_eq!(<U3 as BitAnd<U2>>::Output::to_u32(), 2);
+//! assert_eq!(<U3 as BitOr<U4>>::Output::to_u32(), 7);
+//! assert_eq!(<U3 as BitXor<U2>>::Output::to_u32(), 1);
+//! assert_eq!(<U3 as Shl<U1>>::Output::to_u32(), 6);
+//! assert_eq!(<U3 as Shr<U1>>::Output::to_u32(), 1);
+//! assert_eq!(<U3 as Add<U2>>::Output::to_u32(), 5);
+//! assert_eq!(<U3 as Sub<U2>>::Output::to_u32(), 1);
+//! assert_eq!(<U3 as Mul<U2>>::Output::to_u32(), 6);
+//! assert_eq!(<U3 as Div<U2>>::Output::to_u32(), 1);
+//! assert_eq!(<U3 as Rem<U2>>::Output::to_u32(), 1);
+//! ```
+//!
+
+use core::ops::{BitAnd, BitOr, BitXor, Shl, Shr, Add, Sub, Mul};
+use core::marker::PhantomData;
+use {NonZero, Ord, Greater, Equal, Less, Pow, Cmp, Len};
+
+use bit::{Bit, B0, B1};
+
+use private::{Trim, PrivateAnd, PrivateXor, PrivateSub, PrivateCmp, PrivatePow, BitDiff};
+
+use private::{TrimOut, PrivateAndOut, PrivateXorOut, PrivateSubOut, PrivateCmpOut, PrivatePowOut,
+              BitDiffOut};
+
+use consts::{U0, U1};
+use {Or, Shleft, Shright, Sum, Prod, Add1, Sub1, Square, Length};
+
+pub use marker_traits::Unsigned;
+
+/// The terminating type for `UInt`; it always comes after the most significant
+/// bit. `UTerm` by itself represents zero, which is aliased to `U0`.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
+pub struct UTerm;
+
+impl UTerm {
+    /// Instantiates a singleton representing this unsigned integer.
+    #[inline]
+    pub fn new() -> UTerm {
+        UTerm
+    }
+}
+
+impl Unsigned for UTerm {
+    #[inline]
+    fn to_u8() -> u8 {
+        0
+    }
+    #[inline]
+    fn to_u16() -> u16 {
+        0
+    }
+    #[inline]
+    fn to_u32() -> u32 {
+        0
+    }
+    #[inline]
+    fn to_u64() -> u64 {
+        0
+    }
+    #[cfg(feature="i128")]
+    #[inline]
+    fn to_u128() -> u128 {
+        0
+    }
+    #[inline]
+    fn to_usize() -> usize {
+        0
+    }
+
+    #[inline]
+    fn to_i8() -> i8 {
+        0
+    }
+    #[inline]
+    fn to_i16() -> i16 {
+        0
+    }
+    #[inline]
+    fn to_i32() -> i32 {
+        0
+    }
+    #[inline]
+    fn to_i64() -> i64 {
+        0
+    }
+    #[cfg(feature="i128")]
+    #[inline]
+    fn to_i128() -> i128 {
+        0
+    }
+    #[inline]
+    fn to_isize() -> isize {
+        0
+    }
+}
+
+/// `UInt` is defined recursively, where `B` is the least significant bit and `U` is the rest
+/// of the number. Conceptually, `U` should be bound by the trait `Unsigned` and `B` should
+/// be bound by the trait `Bit`, but enforcing these bounds causes linear instead of
+/// logrithmic scaling in some places, so they are left off for now. They may be enforced in
+/// future.
+///
+/// In order to keep numbers unique, leading zeros are not allowed, so `UInt<UTerm, B0>` is
+/// forbidden.
+///
+/// # Example
+/// ```rust
+/// use typenum::{B0, B1, UInt, UTerm};
+///
+/// # #[allow(dead_code)]
+/// type U6 = UInt<UInt<UInt<UTerm, B1>, B1>, B0>;
+/// ```
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
+pub struct UInt<U, B> {
+    _marker: PhantomData<(U, B)>,
+}
+
+impl<U: Unsigned, B: Bit> UInt<U, B> {
+    /// Instantiates a singleton representing this unsigned integer.
+    #[inline]
+    pub fn new() -> UInt<U, B> {
+        UInt { _marker: PhantomData }
+    }
+}
+
+
+impl<U: Unsigned, B: Bit> Unsigned for UInt<U, B> {
+    #[inline]
+    fn to_u8() -> u8 {
+        B::to_u8() | U::to_u8() << 1
+    }
+    #[inline]
+    fn to_u16() -> u16 {
+        B::to_u8() as u16 | U::to_u16() << 1
+    }
+    #[inline]
+    fn to_u32() -> u32 {
+        B::to_u8() as u32 | U::to_u32() << 1
+    }
+    #[inline]
+    fn to_u64() -> u64 {
+        B::to_u8() as u64 | U::to_u64() << 1
+    }
+    #[cfg(feature="i128")]
+    #[inline]
+    fn to_u128() -> u128 {
+        B::to_u8() as u128 | U::to_u128() << 1
+    }
+    #[inline]
+    fn to_usize() -> usize {
+        B::to_u8() as usize | U::to_usize() << 1
+    }
+
+    #[inline]
+    fn to_i8() -> i8 {
+        B::to_u8() as i8 | U::to_i8() << 1
+    }
+    #[inline]
+    fn to_i16() -> i16 {
+        B::to_u8() as i16 | U::to_i16() << 1
+    }
+    #[inline]
+    fn to_i32() -> i32 {
+        B::to_u8() as i32 | U::to_i32() << 1
+    }
+    #[inline]
+    fn to_i64() -> i64 {
+        B::to_u8() as i64 | U::to_i64() << 1
+    }
+    #[cfg(feature="i128")]
+    #[inline]
+    fn to_i128() -> i128 {
+        B::to_u8() as i128 | U::to_i128() << 1
+    }
+    #[inline]
+    fn to_isize() -> isize {
+        B::to_u8() as isize | U::to_isize() << 1
+    }
+}
+
+impl<U: Unsigned, B: Bit> NonZero for UInt<U, B> {}
+
+// macro for testing operation results. Uses `Same` to ensure the types are equal and
+// not just the values they evaluate to.
+macro_rules! test_uint_op {
+    ($op:ident $Lhs:ident = $Answer:ident) => (
+        {
+            type Test = <<$Lhs as $op>::Output as ::Same<$Answer>>::Output;
+            assert_eq!(<$Answer as Unsigned>::to_u64(), <Test as Unsigned>::to_u64());
+        }
+        );
+    ($Lhs:ident $op:ident $Rhs:ident = $Answer:ident) => (
+        {
+            type Test = <<$Lhs as $op<$Rhs>>::Output as ::Same<$Answer>>::Output;
+            assert_eq!(<$Answer as Unsigned>::to_u64(), <Test as Unsigned>::to_u64());
+        }
+        );
+}
+
+// ---------------------------------------------------------------------------------------
+// Getting length of unsigned integers, which is defined as the number of bits before `UTerm`
+
+/// Length of `UTerm` by itself is 0
+impl Len for UTerm {
+    type Output = U0;
+    fn len(&self) -> Self::Output {
+        UTerm
+    }
+}
+
+/// Length of a bit is 1
+impl<U: Unsigned, B: Bit> Len for UInt<U, B>
+    where U: Len,
+          Length<U>: Add<B1>,
+          Add1<Length<U>>: Unsigned
+{
+    type Output = Add1<Length<U>>;
+    fn len(&self) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+// ---------------------------------------------------------------------------------------
+// Adding bits to unsigned integers
+
+/// `UTerm + B0 = UTerm`
+impl Add<B0> for UTerm {
+    type Output = UTerm;
+    fn add(self, _: B0) -> Self::Output {
+        UTerm
+    }
+}
+
+/// `U + B0 = U`
+impl<U: Unsigned, B: Bit> Add<B0> for UInt<U, B> {
+    type Output = UInt<U, B>;
+    fn add(self, _: B0) -> Self::Output {
+        UInt::new()
+    }
+}
+
+/// `UTerm + B1 = UInt<UTerm, B1>`
+impl Add<B1> for UTerm {
+    type Output = UInt<UTerm, B1>;
+    fn add(self, _: B1) -> Self::Output {
+        UInt::new()
+    }
+}
+
+/// `UInt<U, B0> + B1 = UInt<U + B1>`
+impl<U: Unsigned> Add<B1> for UInt<U, B0> {
+    type Output = UInt<U, B1>;
+    fn add(self, _: B1) -> Self::Output {
+        UInt::new()
+    }
+}
+
+/// `UInt<U, B1> + B1 = UInt<U + B1, B0>`
+impl<U: Unsigned> Add<B1> for UInt<U, B1>
+    where U: Add<B1>,
+          Add1<U>: Unsigned
+{
+    type Output = UInt<Add1<U>, B0>;
+    fn add(self, _: B1) -> Self::Output {
+        UInt::new()
+    }
+}
+
+// ---------------------------------------------------------------------------------------
+// Adding unsigned integers
+
+/// `UTerm + U = U`
+impl<U: Unsigned> Add<U> for UTerm {
+    type Output = U;
+    fn add(self, _: U) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+/// `UInt<U, B> + UTerm = UInt<U, B>`
+impl<U: Unsigned, B: Bit> Add<UTerm> for UInt<U, B> {
+    type Output = UInt<U, B>;
+    fn add(self, _: UTerm) -> Self::Output {
+        UInt::new()
+    }
+}
+
+/// `UInt<Ul, B0> + UInt<Ur, B0> = UInt<Ul + Ur, B0>`
+impl<Ul: Unsigned, Ur: Unsigned> Add<UInt<Ur, B0>> for UInt<Ul, B0>
+    where Ul: Add<Ur>
+{
+    type Output = UInt<Sum<Ul, Ur>, B0>;
+    fn add(self, _: UInt<Ur, B0>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+/// `UInt<Ul, B0> + UInt<Ur, B1> = UInt<Ul + Ur, B1>`
+impl<Ul: Unsigned, Ur: Unsigned> Add<UInt<Ur, B1>> for UInt<Ul, B0>
+    where Ul: Add<Ur>
+{
+    type Output = UInt<Sum<Ul, Ur>, B1>;
+    fn add(self, _: UInt<Ur, B1>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+/// `UInt<Ul, B1> + UInt<Ur, B0> = UInt<Ul + Ur, B1>`
+impl<Ul: Unsigned, Ur: Unsigned> Add<UInt<Ur, B0>> for UInt<Ul, B1>
+    where Ul: Add<Ur>
+{
+    type Output = UInt<Sum<Ul, Ur>, B1>;
+    fn add(self, _: UInt<Ur, B0>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+/// `UInt<Ul, B1> + UInt<Ur, B1> = UInt<(Ul + Ur) + B1, B0>`
+impl<Ul: Unsigned, Ur: Unsigned> Add<UInt<Ur, B1>> for UInt<Ul, B1>
+    where Ul: Add<Ur>,
+          Sum<Ul, Ur>: Add<B1>
+{
+    type Output = UInt<Add1<Sum<Ul, Ur>>, B0>;
+    fn add(self, _: UInt<Ur, B1>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+// ---------------------------------------------------------------------------------------
+// Subtracting bits from unsigned integers
+
+/// `UTerm - B0 = Term`
+impl Sub<B0> for UTerm {
+    type Output = UTerm;
+    fn sub(self, _: B0) -> Self::Output {
+        UTerm
+    }
+}
+
+/// `UInt - B0 = UInt`
+impl<U: Unsigned, B: Bit> Sub<B0> for UInt<U, B> {
+    type Output = UInt<U, B>;
+    fn sub(self, _: B0) -> Self::Output {
+        UInt::new()
+    }
+}
+
+/// `UInt<U, B1> - B1 = UInt<U, B0>`
+impl<U: Unsigned, B: Bit> Sub<B1> for UInt<UInt<U, B>, B1> {
+    type Output = UInt<UInt<U, B>, B0>;
+    fn sub(self, _: B1) -> Self::Output {
+        UInt::new()
+    }
+}
+
+/// `UInt<UTerm, B1> - B1 = UTerm`
+impl Sub<B1> for UInt<UTerm, B1> {
+    type Output = UTerm;
+    fn sub(self, _: B1) -> Self::Output {
+        UTerm
+    }
+}
+
+/// `UInt<U, B0> - B1 = UInt<U - B1, B1>`
+impl<U: Unsigned> Sub<B1> for UInt<U, B0>
+    where U: Sub<B1>,
+          Sub1<U>: Unsigned
+{
+    type Output = UInt<Sub1<U>, B1>;
+    fn sub(self, _: B1) -> Self::Output {
+        UInt::new()
+    }
+}
+
+// ---------------------------------------------------------------------------------------
+// Subtracting unsigned integers
+
+/// `UTerm - UTerm = UTerm`
+impl Sub<UTerm> for UTerm {
+    type Output = UTerm;
+    fn sub(self, _: UTerm) -> Self::Output {
+        UTerm
+    }
+}
+
+/// Subtracting unsigned integers. We just do our `PrivateSub` and then `Trim` the output.
+impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned> Sub<Ur> for UInt<Ul, Bl>
+    where UInt<Ul, Bl>: PrivateSub<Ur>,
+          PrivateSubOut<UInt<Ul, Bl>, Ur>: Trim
+{
+    type Output = TrimOut<PrivateSubOut<UInt<Ul, Bl>, Ur>>;
+    fn sub(self, _: Ur) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+/// `U - UTerm = U`
+impl<U: Unsigned> PrivateSub<UTerm> for U {
+    type Output = U;
+}
+
+/// `UInt<Ul, B0> - UInt<Ur, B0> = UInt<Ul - Ur, B0>`
+impl<Ul: Unsigned, Ur: Unsigned> PrivateSub<UInt<Ur, B0>> for UInt<Ul, B0>
+    where Ul: PrivateSub<Ur>
+{
+    type Output = UInt<PrivateSubOut<Ul, Ur>, B0>;
+}
+
+/// `UInt<Ul, B0> - UInt<Ur, B1> = UInt<(Ul - Ur) - B1, B1>`
+impl<Ul: Unsigned, Ur: Unsigned> PrivateSub<UInt<Ur, B1>> for UInt<Ul, B0>
+    where Ul: PrivateSub<Ur>,
+          PrivateSubOut<Ul, Ur>: Sub<B1>
+{
+    type Output = UInt<Sub1<PrivateSubOut<Ul, Ur>>, B1>;
+}
+
+/// `UInt<Ul, B1> - UInt<Ur, B0> = UInt<Ul - Ur, B1>`
+impl<Ul: Unsigned, Ur: Unsigned> PrivateSub<UInt<Ur, B0>> for UInt<Ul, B1>
+    where Ul: PrivateSub<Ur>
+{
+    type Output = UInt<PrivateSubOut<Ul, Ur>, B1>;
+}
+
+/// `UInt<Ul, B1> - UInt<Ur, B1> = UInt<Ul - Ur, B0>`
+impl<Ul: Unsigned, Ur: Unsigned> PrivateSub<UInt<Ur, B1>> for UInt<Ul, B1>
+    where Ul: PrivateSub<Ur>
+{
+    type Output = UInt<PrivateSubOut<Ul, Ur>, B0>;
+}
+
+// ---------------------------------------------------------------------------------------
+// And unsigned integers
+
+/// 0 & X = 0
+impl<Ur: Unsigned> BitAnd<Ur> for UTerm {
+    type Output = UTerm;
+    fn bitand(self, _: Ur) -> Self::Output {
+        UTerm
+    }
+}
+
+/// Anding unsigned integers.
+/// We use our `PrivateAnd` operator and then `Trim` the output.
+impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned> BitAnd<Ur> for UInt<Ul, Bl>
+    where UInt<Ul, Bl>: PrivateAnd<Ur>,
+          PrivateAndOut<UInt<Ul, Bl>, Ur>: Trim
+{
+    type Output = TrimOut<PrivateAndOut<UInt<Ul, Bl>, Ur>>;
+    fn bitand(self, _: Ur) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+/// `UTerm & X = UTerm`
+impl<U: Unsigned> PrivateAnd<U> for UTerm {
+    type Output = UTerm;
+}
+
+/// `X & UTerm = UTerm`
+impl<B: Bit, U: Unsigned> PrivateAnd<UTerm> for UInt<U, B> {
+    type Output = UTerm;
+}
+
+/// `UInt<Ul, B0> & UInt<Ur, B0> = UInt<Ul & Ur, B0>`
+impl<Ul: Unsigned, Ur: Unsigned> PrivateAnd<UInt<Ur, B0>> for UInt<Ul, B0>
+    where Ul: PrivateAnd<Ur>
+{
+    type Output = UInt<PrivateAndOut<Ul, Ur>, B0>;
+}
+
+/// `UInt<Ul, B0> & UInt<Ur, B1> = UInt<Ul & Ur, B0>`
+impl<Ul: Unsigned, Ur: Unsigned> PrivateAnd<UInt<Ur, B1>> for UInt<Ul, B0>
+    where Ul: PrivateAnd<Ur>
+{
+    type Output = UInt<PrivateAndOut<Ul, Ur>, B0>;
+}
+
+/// `UInt<Ul, B1> & UInt<Ur, B0> = UInt<Ul & Ur, B0>`
+impl<Ul: Unsigned, Ur: Unsigned> PrivateAnd<UInt<Ur, B0>> for UInt<Ul, B1>
+    where Ul: PrivateAnd<Ur>
+{
+    type Output = UInt<PrivateAndOut<Ul, Ur>, B0>;
+}
+
+/// `UInt<Ul, B1> & UInt<Ur, B1> = UInt<Ul & Ur, B1>`
+impl<Ul: Unsigned, Ur: Unsigned> PrivateAnd<UInt<Ur, B1>> for UInt<Ul, B1>
+    where Ul: PrivateAnd<Ur>
+{
+    type Output = UInt<PrivateAndOut<Ul, Ur>, B1>;
+}
+
+// ---------------------------------------------------------------------------------------
+// Or unsigned integers
+
+/// `UTerm | X = X`
+impl<U: Unsigned> BitOr<U> for UTerm {
+    type Output = U;
+    fn bitor(self, _: U) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+///  `X | UTerm = X`
+impl<B: Bit, U: Unsigned> BitOr<UTerm> for UInt<U, B> {
+    type Output = Self;
+    fn bitor(self, _: UTerm) -> Self::Output {
+        UInt::new()
+    }
+}
+
+/// `UInt<Ul, B0> | UInt<Ur, B0> = UInt<Ul | Ur, B0>`
+impl<Ul: Unsigned, Ur: Unsigned> BitOr<UInt<Ur, B0>> for UInt<Ul, B0>
+    where Ul: BitOr<Ur>
+{
+    type Output = UInt<<Ul as BitOr<Ur>>::Output, B0>;
+    fn bitor(self, _: UInt<Ur, B0>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+/// `UInt<Ul, B0> | UInt<Ur, B1> = UInt<Ul | Ur, B1>`
+impl<Ul: Unsigned, Ur: Unsigned> BitOr<UInt<Ur, B1>> for UInt<Ul, B0>
+    where Ul: BitOr<Ur>
+{
+    type Output = UInt<Or<Ul, Ur>, B1>;
+    fn bitor(self, _: UInt<Ur, B1>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+/// `UInt<Ul, B1> | UInt<Ur, B0> = UInt<Ul | Ur, B1>`
+impl<Ul: Unsigned, Ur: Unsigned> BitOr<UInt<Ur, B0>> for UInt<Ul, B1>
+    where Ul: BitOr<Ur>
+{
+    type Output = UInt<Or<Ul, Ur>, B1>;
+    fn bitor(self, _: UInt<Ur, B0>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+/// `UInt<Ul, B1> | UInt<Ur, B1> = UInt<Ul | Ur, B1>`
+impl<Ul: Unsigned, Ur: Unsigned> BitOr<UInt<Ur, B1>> for UInt<Ul, B1>
+    where Ul: BitOr<Ur>
+{
+    type Output = UInt<Or<Ul, Ur>, B1>;
+    fn bitor(self, _: UInt<Ur, B1>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+// ---------------------------------------------------------------------------------------
+// Xor unsigned integers
+
+/// 0 ^ X = X
+impl<Ur: Unsigned> BitXor<Ur> for UTerm {
+    type Output = Ur;
+    fn bitxor(self, _: Ur) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+/// Xoring unsigned integers.
+/// We use our `PrivateXor` operator and then `Trim` the output.
+impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned> BitXor<Ur> for UInt<Ul, Bl>
+    where UInt<Ul, Bl>: PrivateXor<Ur>,
+          PrivateXorOut<UInt<Ul, Bl>, Ur>: Trim
+{
+    type Output = TrimOut<PrivateXorOut<UInt<Ul, Bl>, Ur>>;
+    fn bitxor(self, _: Ur) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+/// `UTerm ^ X = X`
+impl<U: Unsigned> PrivateXor<U> for UTerm {
+    type Output = U;
+}
+
+/// `X ^ UTerm = X`
+impl<B: Bit, U: Unsigned> PrivateXor<UTerm> for UInt<U, B> {
+    type Output = Self;
+}
+
+/// `UInt<Ul, B0> ^ UInt<Ur, B0> = UInt<Ul ^ Ur, B0>`
+impl<Ul: Unsigned, Ur: Unsigned> PrivateXor<UInt<Ur, B0>> for UInt<Ul, B0>
+    where Ul: PrivateXor<Ur>
+{
+    type Output = UInt<PrivateXorOut<Ul, Ur>, B0>;
+}
+
+/// `UInt<Ul, B0> ^ UInt<Ur, B1> = UInt<Ul ^ Ur, B1>`
+impl<Ul: Unsigned, Ur: Unsigned> PrivateXor<UInt<Ur, B1>> for UInt<Ul, B0>
+    where Ul: PrivateXor<Ur>
+{
+    type Output = UInt<PrivateXorOut<Ul, Ur>, B1>;
+}
+
+/// `UInt<Ul, B1> ^ UInt<Ur, B0> = UInt<Ul ^ Ur, B1>`
+impl<Ul: Unsigned, Ur: Unsigned> PrivateXor<UInt<Ur, B0>> for UInt<Ul, B1>
+    where Ul: PrivateXor<Ur>
+{
+    type Output = UInt<PrivateXorOut<Ul, Ur>, B1>;
+}
+
+/// `UInt<Ul, B1> ^ UInt<Ur, B1> = UInt<Ul ^ Ur, B0>`
+impl<Ul: Unsigned, Ur: Unsigned> PrivateXor<UInt<Ur, B1>> for UInt<Ul, B1>
+    where Ul: PrivateXor<Ur>
+{
+    type Output = UInt<PrivateXorOut<Ul, Ur>, B0>;
+}
+
+// ---------------------------------------------------------------------------------------
+// Shl unsigned integers
+
+/// Shifting `UTerm` by a 0 bit: `UTerm << B0 = UTerm`
+impl Shl<B0> for UTerm {
+    type Output = UTerm;
+    fn shl(self, _: B0) -> Self::Output {
+        UTerm
+    }
+}
+
+/// Shifting `UTerm` by a 1 bit: `UTerm << B1 = UTerm`
+impl Shl<B1> for UTerm {
+    type Output = UTerm;
+    fn shl(self, _: B1) -> Self::Output {
+        UTerm
+    }
+}
+
+/// Shifting left any unsigned by a zero bit: `U << B0 = U`
+impl<U: Unsigned, B: Bit> Shl<B0> for UInt<U, B> {
+    type Output = UInt<U, B>;
+    fn shl(self, _: B0) -> Self::Output {
+        UInt::new()
+    }
+}
+
+/// Shifting left a `UInt` by a one bit: `UInt<U, B> << B1 = UInt<UInt<U, B>, B0>`
+impl<U: Unsigned, B: Bit> Shl<B1> for UInt<U, B> {
+    type Output = UInt<UInt<U, B>, B0>;
+    fn shl(self, _: B1) -> Self::Output {
+        UInt::new()
+    }
+}
+
+/// Shifting left `UInt` by `UTerm`: `UInt<U, B> << UTerm = UInt<U, B>`
+impl<U: Unsigned, B: Bit> Shl<UTerm> for UInt<U, B> {
+    type Output = UInt<U, B>;
+    fn shl(self, _: UTerm) -> Self::Output {
+        UInt::new()
+    }
+}
+
+/// Shifting left `UTerm` by an unsigned integer: `UTerm << U = UTerm`
+impl<U: Unsigned> Shl<U> for UTerm {
+    type Output = UTerm;
+    fn shl(self, _: U) -> Self::Output {
+        UTerm
+    }
+}
+
+/// Shifting left `UInt` by `UInt`: `X << Y` = `UInt(X, B0) << (Y - 1)`
+impl<U: Unsigned, B: Bit, Ur: Unsigned, Br: Bit> Shl<UInt<Ur, Br>> for UInt<U, B>
+    where UInt<Ur, Br>: Sub<B1>,
+          UInt<UInt<U, B>, B0>: Shl<Sub1<UInt<Ur, Br>>>
+{
+    type Output = Shleft<UInt<UInt<U, B>, B0>, Sub1<UInt<Ur, Br>>>;
+    fn shl(self, _: UInt<Ur, Br>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+// ---------------------------------------------------------------------------------------
+// Shr unsigned integers
+
+/// Shifting right a `UTerm` by an unsigned integer: `UTerm >> U = UTerm`
+impl<U: Unsigned> Shr<U> for UTerm {
+    type Output = UTerm;
+    fn shr(self, _: U) -> Self::Output {
+        UTerm
+    }
+}
+
+/// Shifting right `UInt` by `UTerm`: `UInt<U, B> >> UTerm = UInt<U, B>`
+impl<U: Unsigned, B: Bit> Shr<UTerm> for UInt<U, B> {
+    type Output = UInt<U, B>;
+    fn shr(self, _: UTerm) -> Self::Output {
+        UInt::new()
+    }
+}
+
+/// Shifting right `UTerm` by a 0 bit: `UTerm >> B0 = UTerm`
+impl Shr<B0> for UTerm {
+    type Output = UTerm;
+    fn shr(self, _: B0) -> Self::Output {
+        UTerm
+    }
+}
+
+/// Shifting right `UTerm` by a 1 bit: `UTerm >> B1 = UTerm`
+impl Shr<B1> for UTerm {
+    type Output = UTerm;
+    fn shr(self, _: B1) -> Self::Output {
+        UTerm
+    }
+}
+
+/// Shifting right any unsigned by a zero bit: `U >> B0 = U`
+impl<U: Unsigned, B: Bit> Shr<B0> for UInt<U, B> {
+    type Output = UInt<U, B>;
+    fn shr(self, _: B0) -> Self::Output {
+        UInt::new()
+    }
+}
+
+/// Shifting right a `UInt` by a 1 bit: `UInt<U, B> >> B1 = U`
+impl<U: Unsigned, B: Bit> Shr<B1> for UInt<U, B> {
+    type Output = U;
+    fn shr(self, _: B1) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+/// Shifting right `UInt` by `UInt`: `UInt(U, B) >> Y` = `U >> (Y - 1)`
+impl<U: Unsigned, B: Bit, Ur: Unsigned, Br: Bit> Shr<UInt<Ur, Br>> for UInt<U, B>
+    where UInt<Ur, Br>: Sub<B1>,
+          U: Shr<Sub1<UInt<Ur, Br>>>
+{
+    type Output = Shright<U, Sub1<UInt<Ur, Br>>>;
+    fn shr(self, _: UInt<Ur, Br>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+// ---------------------------------------------------------------------------------------
+// Multiply unsigned integers
+
+/// `UInt * B0 = UTerm`
+impl<U: Unsigned, B: Bit> Mul<B0> for UInt<U, B> {
+    type Output = UTerm;
+    fn mul(self, _: B0) -> Self::Output {
+        UTerm
+    }
+}
+
+/// `UTerm * B0 = UTerm`
+impl Mul<B0> for UTerm {
+    type Output = UTerm;
+    fn mul(self, _: B0) -> Self::Output {
+        UTerm
+    }
+}
+
+/// `UTerm * B1 = UTerm`
+impl Mul<B1> for UTerm {
+    type Output = UTerm;
+    fn mul(self, _: B1) -> Self::Output {
+        UTerm
+    }
+}
+
+/// `UInt * B1 = UInt`
+impl<U: Unsigned, B: Bit> Mul<B1> for UInt<U, B> {
+    type Output = UInt<U, B>;
+    fn mul(self, _: B1) -> Self::Output {
+        UInt::new()
+    }
+}
+
+/// `UInt<U, B> * UTerm = UTerm`
+impl<U: Unsigned, B: Bit> Mul<UTerm> for UInt<U, B> {
+    type Output = UTerm;
+    fn mul(self, _: UTerm) -> Self::Output {
+        UTerm
+    }
+}
+
+/// `UTerm * U = UTerm`
+impl<U: Unsigned> Mul<U> for UTerm {
+    type Output = UTerm;
+    fn mul(self, _: U) -> Self::Output {
+        UTerm
+    }
+}
+
+/// `UInt<Ul, B0> * UInt<Ur, B> = UInt<(Ul * UInt<Ur, B>), B0>`
+impl<Ul: Unsigned, B: Bit, Ur: Unsigned> Mul<UInt<Ur, B>> for UInt<Ul, B0>
+    where Ul: Mul<UInt<Ur, B>>
+{
+    type Output = UInt<Prod<Ul, UInt<Ur, B>>, B0>;
+    fn mul(self, _: UInt<Ur, B>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+/// `UInt<Ul, B1> * UInt<Ur, B> = UInt<(Ul * UInt<Ur, B>), B0> + UInt<Ur, B>`
+impl<Ul: Unsigned, B: Bit, Ur: Unsigned> Mul<UInt<Ur, B>> for UInt<Ul, B1>
+    where Ul: Mul<UInt<Ur, B>>,
+          UInt<Prod<Ul, UInt<Ur, B>>, B0>: Add<UInt<Ur, B>>
+{
+    type Output = Sum<UInt<Prod<Ul, UInt<Ur, B>>, B0>, UInt<Ur, B>>;
+    fn mul(self, _: UInt<Ur, B>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+// ---------------------------------------------------------------------------------------
+// Compare unsigned integers
+
+/// Zero == Zero
+impl Cmp<UTerm> for UTerm {
+    type Output = Equal;
+}
+
+/// Nonzero > Zero
+impl<U: Unsigned, B: Bit> Cmp<UTerm> for UInt<U, B> {
+    type Output = Greater;
+}
+
+/// Zero < Nonzero
+impl<U: Unsigned, B: Bit> Cmp<UInt<U, B>> for UTerm {
+    type Output = Less;
+}
+
+/// `UInt<Ul, B0>` cmp with `UInt<Ur, B0>`: `SoFar` is `Equal`
+impl<Ul: Unsigned, Ur: Unsigned> Cmp<UInt<Ur, B0>> for UInt<Ul, B0>
+    where Ul: PrivateCmp<Ur, Equal>
+{
+    type Output = PrivateCmpOut<Ul, Ur, Equal>;
+}
+
+/// `UInt<Ul, B1>` cmp with `UInt<Ur, B1>`: `SoFar` is `Equal`
+impl<Ul: Unsigned, Ur: Unsigned> Cmp<UInt<Ur, B1>> for UInt<Ul, B1>
+    where Ul: PrivateCmp<Ur, Equal>
+{
+    type Output = PrivateCmpOut<Ul, Ur, Equal>;
+}
+
+/// `UInt<Ul, B0>` cmp with `UInt<Ur, B1>`: `SoFar` is `Less`
+impl<Ul: Unsigned, Ur: Unsigned> Cmp<UInt<Ur, B1>> for UInt<Ul, B0>
+    where Ul: PrivateCmp<Ur, Less>
+{
+    type Output = PrivateCmpOut<Ul, Ur, Less>;
+}
+
+/// `UInt<Ul, B1>` cmp with `UInt<Ur, B0>`: `SoFar` is `Greater`
+impl<Ul: Unsigned, Ur: Unsigned> Cmp<UInt<Ur, B0>> for UInt<Ul, B1>
+    where Ul: PrivateCmp<Ur, Greater>
+{
+    type Output = PrivateCmpOut<Ul, Ur, Greater>;
+}
+
+/// Comparing non-terimal bits, with both having bit `B0`.
+/// These are `Equal`, so we propogate `SoFar`.
+impl<Ul, Ur, SoFar> PrivateCmp<UInt<Ur, B0>, SoFar> for UInt<Ul, B0>
+    where Ul: Unsigned,
+          Ur: Unsigned,
+          SoFar: Ord,
+          Ul: PrivateCmp<Ur, SoFar>
+{
+    type Output = PrivateCmpOut<Ul, Ur, SoFar>;
+}
+
+/// Comparing non-terimal bits, with both having bit `B1`.
+/// These are `Equal`, so we propogate `SoFar`.
+impl<Ul, Ur, SoFar> PrivateCmp<UInt<Ur, B1>, SoFar> for UInt<Ul, B1>
+    where Ul: Unsigned,
+          Ur: Unsigned,
+          SoFar: Ord,
+          Ul: PrivateCmp<Ur, SoFar>
+{
+    type Output = PrivateCmpOut<Ul, Ur, SoFar>;
+}
+
+/// Comparing non-terimal bits, with `Lhs` having bit `B0` and `Rhs` having bit `B1`.
+/// `SoFar`, Lhs is `Less`.
+impl<Ul, Ur, SoFar> PrivateCmp<UInt<Ur, B1>, SoFar> for UInt<Ul, B0>
+    where Ul: Unsigned,
+          Ur: Unsigned,
+          SoFar: Ord,
+          Ul: PrivateCmp<Ur, Less>
+{
+    type Output = PrivateCmpOut<Ul, Ur, Less>;
+}
+
+/// Comparing non-terimal bits, with `Lhs` having bit `B1` and `Rhs` having bit `B0`.
+/// `SoFar`, Lhs is `Greater`.
+impl<Ul, Ur, SoFar> PrivateCmp<UInt<Ur, B0>, SoFar> for UInt<Ul, B1>
+    where Ul: Unsigned,
+          Ur: Unsigned,
+          SoFar: Ord,
+          Ul: PrivateCmp<Ur, Greater>
+{
+    type Output = PrivateCmpOut<Ul, Ur, Greater>;
+}
+
+/// Got to the end of just the `Lhs`. It's `Less`.
+impl<U: Unsigned, B: Bit, SoFar: Ord> PrivateCmp<UInt<U, B>, SoFar> for UTerm {
+    type Output = Less;
+}
+
+/// Got to the end of just the `Rhs`. `Lhs` is `Greater`.
+impl<U: Unsigned, B: Bit, SoFar: Ord> PrivateCmp<UTerm, SoFar> for UInt<U, B> {
+    type Output = Greater;
+}
+
+/// Got to the end of both! Return `SoFar`
+impl<SoFar: Ord> PrivateCmp<UTerm, SoFar> for UTerm {
+    type Output = SoFar;
+}
+
+macro_rules! test_ord {
+    ($Lhs:ident > $Rhs:ident) => (
+        {
+            type Test = <$Lhs as Cmp<$Rhs>>::Output;
+            assert_eq!(::core::cmp::Ordering::Greater, <Test as Ord>::to_ordering());
+        }
+        );
+    ($Lhs:ident == $Rhs:ident) => (
+        {
+            type Test = <$Lhs as Cmp<$Rhs>>::Output;
+            assert_eq!(::core::cmp::Ordering::Equal, <Test as Ord>::to_ordering());
+        }
+        );
+    ($Lhs:ident < $Rhs:ident) => (
+        {
+            type Test = <$Lhs as Cmp<$Rhs>>::Output;
+            assert_eq!(::core::cmp::Ordering::Less, <Test as Ord>::to_ordering());
+        }
+    );
+}
+
+// ---------------------------------------------------------------------------------------
+// Getting difference in number of bits
+
+impl<Ul, Bl, Ur, Br> BitDiff<UInt<Ur, Br>> for UInt<Ul, Bl>
+    where Ul: Unsigned,
+          Bl: Bit,
+          Ur: Unsigned,
+          Br: Bit,
+          Ul: BitDiff<Ur>
+{
+    type Output = BitDiffOut<Ul, Ur>;
+}
+
+impl<Ul> BitDiff<UTerm> for Ul
+    where Ul: Unsigned + Len
+{
+    type Output = Length<Ul>;
+}
+
+// ---------------------------------------------------------------------------------------
+// Shifting one number until it's the size of another
+use private::ShiftDiff;
+impl<Ul: Unsigned, Ur: Unsigned> ShiftDiff<Ur> for Ul
+    where Ur: BitDiff<Ul>,
+          Ul: Shl<BitDiffOut<Ur, Ul>>
+{
+    type Output = Shleft<Ul, BitDiffOut<Ur, Ul>>;
+}
+
+// ---------------------------------------------------------------------------------------
+// Powers of unsigned integers
+
+/// X^N
+impl<X: Unsigned, N: Unsigned> Pow<N> for X
+    where X: PrivatePow<U1, N>
+{
+    type Output = PrivatePowOut<X, U1, N>;
+    fn powi(self, _: N) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+impl<Y: Unsigned, X: Unsigned> PrivatePow<Y, U0> for X {
+    type Output = Y;
+}
+
+impl<Y: Unsigned, X: Unsigned> PrivatePow<Y, U1> for X
+    where X: Mul<Y>
+{
+    type Output = Prod<X, Y>;
+}
+
+/// N is even
+impl<Y: Unsigned, U: Unsigned, B: Bit, X: Unsigned> PrivatePow<Y, UInt<UInt<U, B>, B0>> for X
+    where X: Mul,
+          Square<X>: PrivatePow<Y, UInt<U, B>>
+{
+    type Output = PrivatePowOut<Square<X>, Y, UInt<U, B>>;
+}
+
+/// N is odd
+impl<Y: Unsigned, U: Unsigned, B: Bit, X: Unsigned> PrivatePow<Y, UInt<UInt<U, B>, B1>> for X
+    where X: Mul + Mul<Y>,
+          Square<X>: PrivatePow<Prod<X, Y>, UInt<U, B>>
+{
+    type Output = PrivatePowOut<Square<X>, Prod<X, Y>, UInt<U, B>>;
+}
+
+// -----------------------------------------
+// GetBit
+
+#[allow(missing_docs)]
+pub trait GetBit<I> {
+    #[allow(missing_docs)]
+    type Output;
+}
+
+#[allow(missing_docs)]
+pub type GetBitOut<N, I> = <N as GetBit<I>>::Output;
+
+// Base case
+impl<Un, Bn> GetBit<U0> for UInt<Un, Bn> {
+    type Output = Bn;
+}
+
+// Recursion case
+impl<Un, Bn, Ui, Bi> GetBit<UInt<Ui, Bi>> for UInt<Un, Bn>
+    where UInt<Ui, Bi>: Sub<B1>,
+          Un: GetBit<Sub1<UInt<Ui, Bi>>>
+{
+    type Output = GetBitOut<Un, Sub1<UInt<Ui, Bi>>>;
+}
+
+// Ran out of bits
+impl<I> GetBit<I> for UTerm {
+    type Output = B0;
+}
+
+#[test]
+fn test_get_bit() {
+    use consts::*;
+    use Same;
+    type T1 = <GetBitOut<U2, U0> as Same<B0>>::Output;
+    type T2 = <GetBitOut<U2, U1> as Same<B1>>::Output;
+    type T3 = <GetBitOut<U2, U2> as Same<B0>>::Output;
+
+    <T1 as Bit>::to_bool();
+    <T2 as Bit>::to_bool();
+    <T3 as Bit>::to_bool();
+}
+
+
+// -----------------------------------------
+// SetBit
+
+/// A **type operator** that, when implemented for unsigned integer `N`, sets the bit at position
+/// `I` to `B`.
+pub trait SetBit<I, B> {
+    #[allow(missing_docs)]
+    type Output;
+}
+/// Alias for the result of calling `SetBit`: `SetBitOut<N, I, B> = <N as SetBit<I, B>>::Output`.
+pub type SetBitOut<N, I, B> = <N as SetBit<I, B>>::Output;
+
+use private::{PrivateSetBit, PrivateSetBitOut};
+
+// Call private one then trim it
+impl<N, I, B> SetBit<I, B> for N
+    where N: PrivateSetBit<I, B>,
+          PrivateSetBitOut<N, I, B>: Trim
+{
+    type Output = TrimOut<PrivateSetBitOut<N, I, B>>;
+}
+
+// Base case
+impl<Un, Bn, B> PrivateSetBit<U0, B> for UInt<Un, Bn> {
+    type Output = UInt<Un, B>;
+}
+
+// Recursion case
+impl<Un, Bn, Ui, Bi, B> PrivateSetBit<UInt<Ui, Bi>, B> for UInt<Un, Bn>
+    where UInt<Ui, Bi>: Sub<B1>,
+          Un: PrivateSetBit<Sub1<UInt<Ui, Bi>>, B>
+{
+    type Output = UInt<PrivateSetBitOut<Un, Sub1<UInt<Ui, Bi>>, B>, Bn>;
+}
+
+// Ran out of bits, setting B0
+impl<I> PrivateSetBit<I, B0> for UTerm {
+    type Output = UTerm;
+}
+
+// Ran out of bits, setting B1
+impl<I> PrivateSetBit<I, B1> for UTerm
+    where U1: Shl<I>
+{
+    type Output = Shleft<U1, I>;
+}
+
+#[test]
+fn test_set_bit() {
+    use consts::*;
+    use Same;
+    type T1 = <SetBitOut<U2, U0, B0> as Same<U2>>::Output;
+    type T2 = <SetBitOut<U2, U0, B1> as Same<U3>>::Output;
+    type T3 = <SetBitOut<U2, U1, B0> as Same<U0>>::Output;
+    type T4 = <SetBitOut<U2, U1, B1> as Same<U2>>::Output;
+    type T5 = <SetBitOut<U2, U2, B0> as Same<U2>>::Output;
+    type T6 = <SetBitOut<U2, U2, B1> as Same<U6>>::Output;
+    type T7 = <SetBitOut<U2, U3, B0> as Same<U2>>::Output;
+    type T8 = <SetBitOut<U2, U3, B1> as Same<U10>>::Output;
+    type T9 = <SetBitOut<U2, U4, B0> as Same<U2>>::Output;
+    type T10 = <SetBitOut<U2, U4, B1> as Same<U18>>::Output;
+
+    type T11 = <SetBitOut<U3, U0, B0> as Same<U2>>::Output;
+
+    <T1 as Unsigned>::to_u32();
+    <T2 as Unsigned>::to_u32();
+    <T3 as Unsigned>::to_u32();
+    <T4 as Unsigned>::to_u32();
+    <T5 as Unsigned>::to_u32();
+    <T6 as Unsigned>::to_u32();
+    <T7 as Unsigned>::to_u32();
+    <T8 as Unsigned>::to_u32();
+    <T9 as Unsigned>::to_u32();
+    <T10 as Unsigned>::to_u32();
+    <T11 as Unsigned>::to_u32();
+}
+
+// -----------------------------------------
+
+// Division algorithm:
+// We have N / D:
+// let Q = 0, R = 0
+// NBits = len(N)
+// for I in NBits-1..0:
+//   R <<=1
+//   R[0] = N[i]
+//   let C = R.cmp(D)
+//   if C == Equal or Greater:
+//     R -= D
+//     Q[i] = 1
+
+macro_rules! test_div {
+    ($a:ident / $b:ident = $c:ident) => (
+        {
+            type R = Quot<$a, $b>;
+            assert_eq!(<R as Unsigned>::to_usize(), $c::to_usize());
+        }
+    );
+}
+#[test]
+fn test_div() {
+    use consts::*;
+    use {Quot, Same};
+
+    test_div!(U0 / U1 = U0);
+    test_div!(U1 / U1 = U1);
+    test_div!(U2 / U1 = U2);
+    test_div!(U3 / U1 = U3);
+    test_div!(U4 / U1 = U4);
+
+    test_div!(U0 / U2 = U0);
+    test_div!(U1 / U2 = U0);
+    test_div!(U2 / U2 = U1);
+    test_div!(U3 / U2 = U1);
+    test_div!(U4 / U2 = U2);
+    test_div!(U6 / U2 = U3);
+    test_div!(U7 / U2 = U3);
+
+    type T = <SetBitOut<U0, U1, B1> as Same<U2>>::Output;
+    <T as Unsigned>::to_u32();
+}
+
+// -----------------------------------------
+// Div
+use core::ops::Div;
+
+// 0 // N
+impl<Ur: Unsigned, Br: Bit> Div<UInt<Ur, Br>> for UTerm {
+    type Output = UTerm;
+    fn div(self, _: UInt<Ur, Br>) -> Self::Output {
+        UTerm
+    }
+}
+
+// M // N
+impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned, Br: Bit> Div<UInt<Ur, Br>> for UInt<Ul, Bl>
+    where UInt<Ul, Bl>: Len,
+          Length<UInt<Ul, Bl>>: Sub<B1>,
+          (): PrivateDiv<UInt<Ul, Bl>, UInt<Ur, Br>, U0, U0, Sub1<Length<UInt<Ul, Bl>>>>
+{
+    type Output = PrivateDivQuot<UInt<Ul, Bl>, UInt<Ur, Br>, U0, U0, Sub1<Length<UInt<Ul, Bl>>>>;
+    fn div(self, _: UInt<Ur, Br>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+// -----------------------------------------
+// Rem
+use core::ops::Rem;
+
+// 0 % N
+impl<Ur: Unsigned, Br: Bit> Rem<UInt<Ur, Br>> for UTerm {
+    type Output = UTerm;
+    fn rem(self, _: UInt<Ur, Br>) -> Self::Output {
+        UTerm
+    }
+}
+
+// M % N
+impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned, Br: Bit> Rem<UInt<Ur, Br>> for UInt<Ul, Bl>
+    where UInt<Ul, Bl>: Len,
+          Length<UInt<Ul, Bl>>: Sub<B1>,
+          (): PrivateDiv<UInt<Ul, Bl>, UInt<Ur, Br>, U0, U0, Sub1<Length<UInt<Ul, Bl>>>>
+{
+    type Output = PrivateDivRem<UInt<Ul, Bl>, UInt<Ur, Br>, U0, U0, Sub1<Length<UInt<Ul, Bl>>>>;
+    fn rem(self, _: UInt<Ur, Br>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+
+// -----------------------------------------
+// PrivateDiv
+use private::{PrivateDiv, PrivateDivQuot, PrivateDivRem};
+
+use Compare;
+// R == 0: We set R = UInt<UTerm, N[i]>, then call out to PrivateDivIf for the if statement
+impl<N, D, Q, I> PrivateDiv<N, D, Q, U0, I> for ()
+    where N: GetBit<I>,
+          UInt<UTerm, GetBitOut<N, I>>: Trim,
+          TrimOut<UInt<UTerm, GetBitOut<N, I>>>: Cmp<D>,
+          (): PrivateDivIf<N,
+                           D,
+                           Q,
+                           TrimOut<UInt<UTerm, GetBitOut<N, I>>>,
+                           I,
+                           Compare<TrimOut<UInt<UTerm, GetBitOut<N, I>>>, D>>
+{
+    type Quotient = PrivateDivIfQuot<N,
+                     D,
+                     Q,
+                     TrimOut<UInt<UTerm, GetBitOut<N, I>>>,
+                     I,
+                     Compare<TrimOut<UInt<UTerm, GetBitOut<N, I>>>, D>>;
+    type Remainder = PrivateDivIfRem<N,
+                    D,
+                    Q,
+                    TrimOut<UInt<UTerm, GetBitOut<N, I>>>,
+                    I,
+                    Compare<TrimOut<UInt<UTerm, GetBitOut<N, I>>>, D>>;
+}
+
+// R > 0: We perform R <<= 1 and R[0] = N[i], then call out to PrivateDivIf for the if statement
+impl<N, D, Q, Ur, Br, I> PrivateDiv<N, D, Q, UInt<Ur, Br>, I> for ()
+    where N: GetBit<I>,
+          UInt<UInt<Ur, Br>, GetBitOut<N, I>>: Cmp<D>,
+          (): PrivateDivIf<N,
+                           D,
+                           Q,
+                           UInt<UInt<Ur, Br>, GetBitOut<N, I>>,
+                           I,
+                           Compare<UInt<UInt<Ur, Br>, GetBitOut<N, I>>, D>>
+{
+    type Quotient = PrivateDivIfQuot<N,
+                     D,
+                     Q,
+                     UInt<UInt<Ur, Br>, GetBitOut<N, I>>,
+                     I,
+                     Compare<UInt<UInt<Ur, Br>, GetBitOut<N, I>>, D>>;
+    type Remainder = PrivateDivIfRem<N,
+                    D,
+                    Q,
+                    UInt<UInt<Ur, Br>, GetBitOut<N, I>>,
+                    I,
+                    Compare<UInt<UInt<Ur, Br>, GetBitOut<N, I>>, D>>;
+}
+
+// -----------------------------------------
+// PrivateDivIf
+
+use private::{PrivateDivIf, PrivateDivIfQuot, PrivateDivIfRem};
+
+// R < D, I > 0, we do nothing and recurse
+impl<N, D, Q, R, Ui, Bi> PrivateDivIf<N, D, Q, R, UInt<Ui, Bi>, Less> for ()
+    where UInt<Ui, Bi>: Sub<B1>,
+          (): PrivateDiv<N, D, Q, R, Sub1<UInt<Ui, Bi>>>
+{
+    type Quotient = PrivateDivQuot<N, D, Q, R, Sub1<UInt<Ui, Bi>>>;
+    type Remainder = PrivateDivRem<N, D, Q, R, Sub1<UInt<Ui, Bi>>>;
+}
+
+// R == D, I > 0, we set R = 0, Q[I] = 1 and recurse
+impl<N, D, Q, R, Ui, Bi> PrivateDivIf<N, D, Q, R, UInt<Ui, Bi>, Equal> for ()
+    where UInt<Ui, Bi>: Sub<B1>,
+          Q: SetBit<UInt<Ui, Bi>, B1>,
+          (): PrivateDiv<N, D, SetBitOut<Q, UInt<Ui, Bi>, B1>, U0, Sub1<UInt<Ui, Bi>>>
+{
+    type Quotient = PrivateDivQuot<N, D, SetBitOut<Q, UInt<Ui, Bi>, B1>, U0, Sub1<UInt<Ui, Bi>>>;
+    type Remainder = PrivateDivRem<N, D, SetBitOut<Q, UInt<Ui, Bi>, B1>, U0, Sub1<UInt<Ui, Bi>>>;
+}
+
+use Diff;
+// R > D, I > 0, we set R -= D, Q[I] = 1 and recurse
+impl<N, D, Q, R, Ui, Bi> PrivateDivIf<N, D, Q, R, UInt<Ui, Bi>, Greater> for ()
+    where UInt<Ui, Bi>: Sub<B1>,
+          R: Sub<D>,
+          Q: SetBit<UInt<Ui, Bi>, B1>,
+          (): PrivateDiv<N, D, SetBitOut<Q, UInt<Ui, Bi>, B1>, Diff<R, D>, Sub1<UInt<Ui, Bi>>>
+{
+    type Quotient = PrivateDivQuot<N,
+                   D,
+                   SetBitOut<Q, UInt<Ui, Bi>, B1>,
+                   Diff<R, D>,
+                   Sub1<UInt<Ui, Bi>>>;
+    type Remainder = PrivateDivRem<N,
+                  D,
+                  SetBitOut<Q, UInt<Ui, Bi>, B1>,
+                  Diff<R, D>,
+                  Sub1<UInt<Ui, Bi>>>;
+}
+
+// R < D, I == 0: we do nothing, and return
+impl<N, D, Q, R> PrivateDivIf<N, D, Q, R, U0, Less> for () {
+    type Quotient = Q;
+    type Remainder = R;
+}
+
+// R == D, I == 0: we set R = 0, Q[I] = 1, and return
+impl<N, D, Q, R> PrivateDivIf<N, D, Q, R, U0, Equal> for ()
+    where Q: SetBit<U0, B1>
+{
+    type Quotient = SetBitOut<Q, U0, B1>;
+    type Remainder = U0;
+}
+
+// R > D, I == 0: We set R -= D, Q[I] = 1, and return
+impl<N, D, Q, R> PrivateDivIf<N, D, Q, R, U0, Greater> for ()
+    where R: Sub<D>,
+          Q: SetBit<U0, B1>
+{
+    type Quotient = SetBitOut<Q, U0, B1>;
+    type Remainder = Diff<R, D>;
+}
+
+// -----------------------------------------
+// PartialDiv
+use {PartialDiv, Quot};
+impl<Ur: Unsigned, Br: Bit> PartialDiv<UInt<Ur, Br>> for UTerm {
+    type Output = UTerm;
+    fn partial_div(self, _: UInt<Ur, Br>) -> Self::Output {
+        UTerm
+    }
+}
+
+// M / N
+impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned, Br: Bit> PartialDiv<UInt<Ur, Br>> for UInt<Ul, Bl>
+    where UInt<Ul, Bl>: Div<UInt<Ur, Br>> + Rem<UInt<Ur, Br>, Output = U0>
+{
+    type Output = Quot<UInt<Ul, Bl>, UInt<Ur, Br>>;
+    fn partial_div(self, _: UInt<Ur, Br>) -> Self::Output {
+        unsafe { ::core::mem::uninitialized() }
+    }
+}
+
+// -----------------------------------------
+// PrivateMin
+use private::{PrivateMin, PrivateMinOut};
+
+impl<U, B, Ur> PrivateMin<Ur, Equal> for UInt<U, B>
+    where Ur: Unsigned,
+          U: Unsigned,
+          B: Bit
+{
+    type Output = UInt<U, B>;
+    fn private_min(self, _: Ur) -> Self::Output {
+        self
+    }
+}
+
+impl<U, B, Ur> PrivateMin<Ur, Less> for UInt<U, B>
+    where Ur: Unsigned,
+          U: Unsigned,
+          B: Bit
+{
+    type Output = UInt<U, B>;
+    fn private_min(self, _: Ur) -> Self::Output {
+        self
+    }
+}
+
+impl<U, B, Ur> PrivateMin<Ur, Greater> for UInt<U, B>
+    where Ur: Unsigned,
+          U: Unsigned,
+          B: Bit
+{
+    type Output = Ur;
+    fn private_min(self, rhs: Ur) -> Self::Output {
+        rhs
+    }
+}
+
+// -----------------------------------------
+// Min
+use Min;
+
+impl<U> Min<U> for UTerm
+    where U: Unsigned
+{
+    type Output = UTerm;
+    fn min(self, _: U) -> Self::Output {
+        self
+    }
+}
+
+impl<U, B, Ur> Min<Ur> for UInt<U, B>
+    where U: Unsigned,
+          B: Bit,
+          Ur: Unsigned,
+          UInt<U, B>: Cmp<Ur> + PrivateMin<Ur, Compare<UInt<U, B>, Ur>>
+{
+    type Output = PrivateMinOut<UInt<U, B>, Ur, Compare<UInt<U, B>, Ur>>;
+    fn min(self, rhs: Ur) -> Self::Output {
+        self.private_min(rhs)
+    }
+}
+
+// -----------------------------------------
+// PrivateMax
+use private::{PrivateMax, PrivateMaxOut};
+
+impl<U, B, Ur> PrivateMax<Ur, Equal> for UInt<U, B>
+    where Ur: Unsigned,
+          U: Unsigned,
+          B: Bit
+{
+    type Output = UInt<U, B>;
+    fn private_max(self, _: Ur) -> Self::Output {
+        self
+    }
+}
+
+impl<U, B, Ur> PrivateMax<Ur, Less> for UInt<U, B>
+    where Ur: Unsigned,
+          U: Unsigned,
+          B: Bit
+{
+    type Output = Ur;
+    fn private_max(self, rhs: Ur) -> Self::Output {
+        rhs
+    }
+}
+
+impl<U, B, Ur> PrivateMax<Ur, Greater> for UInt<U, B>
+    where Ur: Unsigned,
+          U: Unsigned,
+          B: Bit
+{
+    type Output = UInt<U, B>;
+    fn private_max(self, _: Ur) -> Self::Output {
+        self
+    }
+}
+
+// -----------------------------------------
+// Max
+use Max;
+
+impl<U> Max<U> for UTerm
+    where U: Unsigned
+{
+    type Output = U;
+    fn max(self, rhs: U) -> Self::Output {
+        rhs
+    }
+}
+
+impl<U, B, Ur> Max<Ur> for UInt<U, B>
+    where U: Unsigned,
+          B: Bit,
+          Ur: Unsigned,
+          UInt<U, B>: Cmp<Ur> + PrivateMax<Ur, Compare<UInt<U, B>, Ur>>
+{
+    type Output = PrivateMaxOut<UInt<U, B>, Ur, Compare<UInt<U, B>, Ur>>;
+    fn max(self, rhs: Ur) -> Self::Output {
+        self.private_max(rhs)
+    }
+}
diff --git a/crates/typenum-1.9.0/tests/test.rs b/crates/typenum-1.9.0/tests/test.rs
new file mode 100644
index 0000000..0471b27
--- /dev/null
+++ b/crates/typenum-1.9.0/tests/test.rs
@@ -0,0 +1 @@
+include!(concat!(env!("OUT_DIR"), "/tests.rs"));



More information about the tor-commits mailing list