Bug 1455902: Revendor rust dependencies. r=me
authorEmilio Cobos Álvarez <emilio@crisal.io>
Sat, 21 Apr 2018 21:44:37 +0200
changeset 468487 e57d78a2b830dc163f5dbcb070d45dd5552be786
parent 468486 dbc1cffb4a11cabf48862d5206f139dd190c94ce
child 468488 f297b23906c2a9e87b34a6cf3aa9aa8dcd73db55
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersme
bugs1455902
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1455902: Revendor rust dependencies. r=me MozReview-Commit-ID: FiGpKeFA6Ob
Cargo.lock
third_party/rust/smallbitvec/.cargo-checksum.json
third_party/rust/smallbitvec/.travis.yml
third_party/rust/smallbitvec/Cargo.toml
third_party/rust/smallbitvec/README.md
third_party/rust/smallbitvec/benches/bench.rs
third_party/rust/smallbitvec/src/lib.rs
third_party/rust/smallbitvec/src/tests.rs
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1120,17 +1120,17 @@ name = "malloc_size_of"
 version = "0.0.1"
 dependencies = [
  "app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cssparser 0.23.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "hashglobe 0.1.0",
  "selectors 0.19.0",
  "servo_arc 0.1.1",
- "smallbitvec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallbitvec 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "malloc_size_of_derive"
 version = "0.0.1"
 dependencies = [
@@ -1812,17 +1812,17 @@ version = "0.0.1"
 
 [[package]]
 name = "slab"
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "smallbitvec"
-version = "1.0.6"
+version = "2.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "smallvec"
 version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1897,17 +1897,17 @@ dependencies = [
  "ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.19.0",
  "servo_arc 0.1.1",
- "smallbitvec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallbitvec 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "style_derive 0.0.1",
  "style_traits 0.0.1",
  "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "uluru 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2627,17 +2627,17 @@ dependencies = [
 "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
 "checksum serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "d3bcee660dcde8f52c3765dd9ca5ee36b4bf35470a738eb0bd5a8752b0389645"
 "checksum serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)" = "adb6e51a6b3696b301bc221d785f898b4457c619b51d7ce195a6d20baecb37b3"
 "checksum serde_derive 1.0.37 (git+https://github.com/servo/serde?branch=deserialize_from_enums6)" = "<none>"
 "checksum serde_derive_internals 0.23.0 (git+https://github.com/servo/serde?branch=deserialize_from_enums6)" = "<none>"
 "checksum simd 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3dd0805c7363ab51a829a1511ad24b6ed0349feaa756c4bc2f977f9f496e6673"
 "checksum siphasher 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ffc669b726f2bc9a3bcff66e5e23b56ba6bf70e22a34c3d7b6d0b3450b65b84"
 "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
-"checksum smallbitvec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "79b776f00dfe01df905fa3b2eaa1659522e99e3fc4a7b1334171622205c4bdcf"
+"checksum smallbitvec 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "665fbc8384f961eb55c548daa2a4b1efff1f9d03b7a10f162ac6ad6a781ca966"
 "checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9"
 "checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
 "checksum string_cache 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39cb4173bcbd1319da31faa5468a7e3870683d7a237150b0b0aaafd546f6ad12"
 "checksum string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "479cde50c3539481f33906a387f2bd17c8e87cb848c35b6021d41fb81ff9b4d7"
 "checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
 "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
 "checksum syn 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9e1c669ed757c0ebd04337f6a5bb972d05e0c08fe2540dd3ee3dd9e4daf1604c"
 "checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59"
--- a/third_party/rust/smallbitvec/.cargo-checksum.json
+++ b/third_party/rust/smallbitvec/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"d5d98ff79b139424aafbc16c69b0b163d5555c8f2587eb0545d3ca23129009be","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"daa94322de7eab889e055932396160395bd8e3af82f56ae8c419d3049111da72","README.md":"c7b7102e5b19a19c3a0e1cefeddb228fb57c7fac6ce91f15dada4d81d8dc2dac","benches/bench.rs":"6d6bc6afac8af5cfb37a672f7a1e8f9abb29b00993b85e94cd701dcd8955aabd","src/lib.rs":"e52f4408a673ce873e231d61d0059c49cb7d735335b24a797f5d071f2954b53c"},"package":"79b776f00dfe01df905fa3b2eaa1659522e99e3fc4a7b1334171622205c4bdcf"}
\ No newline at end of file
+{"files":{".travis.yml":"91edce5ea2a1956399db4b17f580c8b7995af3aa9801c4314865f560c55d6d09","Cargo.toml":"b916f68b32a3896fd51b5e792b6fbefb22c45e4061f646ef38c0bd5d9f3ccc4d","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"daa94322de7eab889e055932396160395bd8e3af82f56ae8c419d3049111da72","README.md":"4ac9c9b88726f6bcc3b454d61ce75a8224bd430584b765e304be9aa21815c327","benches/bench.rs":"9691c531845f2741bcb6485641ee3fd3e39980925ec6e5f716464e94fd5adfd0","src/lib.rs":"49c8ea8ce266cbbe5fe4e32e063067f334764bf55ec957f0c56c04ffa9360b51","src/tests.rs":"1d92b1cf9660293664bcee3be22c40859603dece4502cedcf53e0b0301683d7e"},"package":"665fbc8384f961eb55c548daa2a4b1efff1f9d03b7a10f162ac6ad6a781ca966"}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/third_party/rust/smallbitvec/.travis.yml
@@ -0,0 +1,14 @@
+language: rust
+rust:
+  - nightly
+  - beta
+  - stable
+script: |
+  cargo build --verbose &&
+  cargo build --all-features --verbose &&
+  cargo test --verbose &&
+  cargo test --all-features --verbose &&
+  ([ $TRAVIS_RUST_VERSION != nightly ] || cargo test --verbose --no-default-features) &&
+  ([ $TRAVIS_RUST_VERSION != nightly ] || cargo bench --verbose bench)
+notifications:
+  webhooks: http://build.servo.org:54856/travis
--- a/third_party/rust/smallbitvec/Cargo.toml
+++ b/third_party/rust/smallbitvec/Cargo.toml
@@ -7,21 +7,22 @@
 #
 # 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 = "smallbitvec"
-version = "1.0.6"
+version = "2.1.0"
 authors = ["Matt Brubeck <mbrubeck@limpet.net>"]
 description = "A bit vector optimized for size and inline storage"
 documentation = "https://docs.rs/smallbitvec"
 readme = "README.md"
 keywords = ["bitvec", "bitmap", "vec", "data-structures"]
+categories = ["data-structures"]
 license = "MIT / Apache-2.0"
 repository = "https://github.com/servo/smallbitvec"
 [dev-dependencies.bit-vec]
 version = "0.4.4"
 
 [dev-dependencies.rand]
-version = "0.3.15"
+version = "0.4.2"
--- a/third_party/rust/smallbitvec/README.md
+++ b/third_party/rust/smallbitvec/README.md
@@ -1,7 +1,9 @@
 # smallbitvec
 
 A bit vector that is only one word wide, and can store data either inline or
-on the heap.
+on the heap.  Like the `bit-vec` crate but optimized for small inline size and
+reduced allocations.
 
 * [Documentation](https://docs.rs/smallbitvec)
 * [crates.io](https://crates.io/crates/smallbitvec)
+* [Release notes](https://github.com/servo/smallbitvec/releases)
--- a/third_party/rust/smallbitvec/benches/bench.rs
+++ b/third_party/rust/smallbitvec/benches/bench.rs
@@ -12,152 +12,144 @@
 #![feature(test)]
 
 extern crate bit_vec;
 extern crate rand;
 extern crate smallbitvec;
 extern crate test;
 
 use bit_vec::BitVec;
-use rand::{Rng, weak_rng, XorShiftRng};
+use rand::{weak_rng, Rng, XorShiftRng};
 use smallbitvec::SmallBitVec;
-use test::{Bencher, black_box};
+use test::{black_box, Bencher};
 
-const BENCH_BITS : usize = 1 << 14;
-const U32_BITS: usize = 32;
+const BENCH_BITS: usize = 1 << 14;
+const USIZE_BITS: usize = ::std::mem::size_of::<usize>() * 8;
 
 fn rng() -> XorShiftRng {
     weak_rng()
 }
 
 #[bench]
 fn bench_bit_set_big_fixed_bv(b: &mut Bencher) {
     let mut r = rng();
     let mut bit_vec = BitVec::from_elem(BENCH_BITS, false);
     b.iter(|| {
         for _ in 0..100 {
-            bit_vec.set((r.next_u32() as usize) % BENCH_BITS, true);
+            bit_vec.set((r.next_u64() as usize) % BENCH_BITS, true);
         }
         black_box(&bit_vec);
     });
 }
 
 #[bench]
 fn bench_bit_set_big_fixed_sbv(b: &mut Bencher) {
     let mut r = rng();
-    let mut bit_vec = SmallBitVec::from_elem(BENCH_BITS as u32, false);
+    let mut bit_vec = SmallBitVec::from_elem(BENCH_BITS, false);
     b.iter(|| {
         for _ in 0..100 {
-            bit_vec.set(r.next_u32() % BENCH_BITS as u32, true);
+            bit_vec.set(r.next_u64() as usize % BENCH_BITS, true);
         }
         black_box(&bit_vec);
     });
 }
 
 #[bench]
 fn bench_big_set_big_variable_bv(b: &mut Bencher) {
     let mut r = rng();
     let mut bit_vec = BitVec::from_elem(BENCH_BITS, false);
     b.iter(|| {
         for _ in 0..100 {
-            bit_vec.set((r.next_u32() as usize) % BENCH_BITS, r.gen());
+            bit_vec.set((r.next_u64() as usize) % BENCH_BITS, r.gen());
         }
         black_box(&bit_vec);
     });
 }
 
 #[bench]
 fn bench_bit_set_big_variable_sbv(b: &mut Bencher) {
     let mut r = rng();
-    let mut bit_vec = SmallBitVec::from_elem(BENCH_BITS as u32, false);
+    let mut bit_vec = SmallBitVec::from_elem(BENCH_BITS, false);
     b.iter(|| {
         for _ in 0..100 {
-            bit_vec.set(r.next_u32() % BENCH_BITS as u32, r.gen());
+            bit_vec.set(r.next_u64() as usize % BENCH_BITS, r.gen());
         }
         black_box(&bit_vec);
     });
 }
 
 #[bench]
 fn bench_bit_set_small_bv(b: &mut Bencher) {
     let mut r = rng();
-    let mut bit_vec = BitVec::from_elem(U32_BITS, false);
+    let mut bit_vec = BitVec::from_elem(USIZE_BITS, false);
     b.iter(|| {
         for _ in 0..100 {
-            bit_vec.set((r.next_u32() as usize) % U32_BITS, true);
+            bit_vec.set((r.next_u64() as usize) % USIZE_BITS, true);
         }
         black_box(&bit_vec);
     });
 }
 
 #[bench]
 fn bench_bit_set_small_sbv(b: &mut Bencher) {
     let mut r = rng();
-    let mut bit_vec = SmallBitVec::from_elem(U32_BITS as u32, false);
+    let mut bit_vec = SmallBitVec::from_elem(USIZE_BITS, false);
     b.iter(|| {
         for _ in 0..100 {
-            bit_vec.set(r.next_u32() % U32_BITS as u32, true);
+            bit_vec.set(r.next_u64() as usize % USIZE_BITS, true);
         }
         black_box(&bit_vec);
     });
 }
 
 #[bench]
 fn bench_bit_vec_small_eq_bv(b: &mut Bencher) {
-    let x = BitVec::from_elem(U32_BITS, false);
-    let y = BitVec::from_elem(U32_BITS, false);
-    b.iter(|| {
-        x == y
-    });
+    let x = BitVec::from_elem(USIZE_BITS, false);
+    let y = BitVec::from_elem(USIZE_BITS, false);
+    b.iter(|| x == y);
 }
 
 #[bench]
 fn bench_bit_vec_small_eq_sbv(b: &mut Bencher) {
-    let x = SmallBitVec::from_elem(U32_BITS as u32, false);
-    let y = SmallBitVec::from_elem(U32_BITS as u32, false);
-    b.iter(|| {
-        x == y
-    });
+    let x = SmallBitVec::from_elem(USIZE_BITS, false);
+    let y = SmallBitVec::from_elem(USIZE_BITS, false);
+    b.iter(|| x == y);
 }
 
 #[bench]
 fn bench_bit_vec_big_eq_bv(b: &mut Bencher) {
     let x = BitVec::from_elem(BENCH_BITS, false);
     let y = BitVec::from_elem(BENCH_BITS, false);
-    b.iter(|| {
-        x == y
-    });
+    b.iter(|| x == y);
 }
 
 #[bench]
 fn bench_bit_vec_big_eq_sbv(b: &mut Bencher) {
-    let x = SmallBitVec::from_elem(BENCH_BITS as u32, false);
-    let y = SmallBitVec::from_elem(BENCH_BITS as u32, false);
-    b.iter(|| {
-        x == y
-    });
+    let x = SmallBitVec::from_elem(BENCH_BITS, false);
+    let y = SmallBitVec::from_elem(BENCH_BITS, false);
+    b.iter(|| x == y);
 }
 
 #[bench]
 fn bench_bit_vec_small_iter_bv(b: &mut Bencher) {
-    let bit_vec = BitVec::from_elem(U32_BITS, false);
+    let bit_vec = BitVec::from_elem(USIZE_BITS, false);
     b.iter(|| {
         let mut sum = 0;
         for _ in 0..10 {
             for pres in &bit_vec {
                 sum += pres as usize;
             }
         }
         sum
     })
 }
 
 #[bench]
 fn bench_bit_vec_small_iter_sbv(b: &mut Bencher) {
-    let bit_vec = SmallBitVec::from_elem(U32_BITS as u32, false);
+    let bit_vec = SmallBitVec::from_elem(USIZE_BITS, false);
     b.iter(|| {
         let mut sum = 0;
         for _ in 0..10 {
             for pres in &bit_vec {
                 sum += pres as usize;
             }
         }
         sum
@@ -173,57 +165,53 @@ fn bench_bit_vec_big_iter_bv(b: &mut Ben
             sum += pres as usize;
         }
         sum
     })
 }
 
 #[bench]
 fn bench_bit_vec_big_iter_sbv(b: &mut Bencher) {
-    let bit_vec = SmallBitVec::from_elem(BENCH_BITS as u32, false);
+    let bit_vec = SmallBitVec::from_elem(BENCH_BITS, false);
     b.iter(|| {
         let mut sum = 0;
         for pres in &bit_vec {
             sum += pres as usize;
         }
         sum
     })
 }
 
 #[bench]
 fn bench_from_elem_bv(b: &mut Bencher) {
     let cap = black_box(BENCH_BITS);
     let bit = black_box(true);
-    b.iter(|| {
-        BitVec::from_elem(cap, bit)
-    });
+    b.iter(|| BitVec::from_elem(cap, bit));
     b.bytes = cap as u64 / 8;
 }
 
 #[bench]
 fn bench_from_elem_sbv(b: &mut Bencher) {
-    let cap = black_box(BENCH_BITS) as u32;
+    let cap = black_box(BENCH_BITS);
     let bit = black_box(true);
-    b.iter(|| {
-        SmallBitVec::from_elem(cap, bit)
-    });
+    b.iter(|| SmallBitVec::from_elem(cap, bit));
     b.bytes = cap as u64 / 8;
 }
 
 #[bench]
 fn bench_remove_small(b: &mut Bencher) {
     b.iter(|| {
-        let mut v = SmallBitVec::from_elem(U32_BITS as u32, false);
-        for _ in 0..U32_BITS {
+        let mut v = SmallBitVec::from_elem(USIZE_BITS, false);
+        for _ in 0..USIZE_BITS {
             v.remove(0);
         }
     });
 }
 
 #[bench]
 fn bench_remove_big(b: &mut Bencher) {
     b.iter(|| {
-        let mut v = SmallBitVec::from_elem(BENCH_BITS as u32, false);
+        let mut v = SmallBitVec::from_elem(BENCH_BITS, false);
         for _ in 0..200 {
             v.remove(0);
         }
     });
 }
--- a/third_party/rust/smallbitvec/src/lib.rs
+++ b/third_party/rust/smallbitvec/src/lib.rs
@@ -15,222 +15,272 @@
 //!
 //! [`SmallBitVec`]: struct.SmallBitVec.html
 
 use std::cmp::max;
 use std::fmt;
 use std::hash;
 use std::iter::{DoubleEndedIterator, ExactSizeIterator, FromIterator};
 use std::mem::{forget, replace, size_of};
-use std::ops::Range;
+use std::ops::{Index, Range};
 use std::slice;
 
+/// Creates a [`SmallBitVec`] containing the arguments.
+///
+/// `sbvec!` allows `SmallBitVec`s to be defined with the same syntax as array expressions.
+/// There are two forms of this macro:
+///
+/// - Create a [`SmallBitVec`] containing a given list of elements:
+///
+/// ```
+/// # #[macro_use] extern crate smallbitvec;
+/// # use smallbitvec::SmallBitVec;
+/// # fn main() {
+/// let v = sbvec![true, false, true];
+/// assert_eq!(v[0], true);
+/// assert_eq!(v[1], false);
+/// assert_eq!(v[2], true);
+/// # }
+/// ```
+///
+/// - Create a [`SmallBitVec`] from a given element and size:
+///
+/// ```
+/// # #[macro_use] extern crate smallbitvec;
+/// # use smallbitvec::SmallBitVec;
+/// # fn main() {
+/// let v = sbvec![true; 3];
+/// assert!(v.into_iter().eq(vec![true, true, true].into_iter()));
+/// # }
+/// ```
+
+#[macro_export]
+macro_rules! sbvec {
+    ($elem:expr; $n:expr) => (
+        $crate::SmallBitVec::from_elem($n, $elem)
+    );
+    ($($x:expr),*) => (
+        [$($x),*].iter().cloned().collect::<$crate::SmallBitVec>()
+    );
+    ($($x:expr,)*) => (
+        sbvec![$($x),*]
+    );
+}
+
+#[cfg(test)]
+mod tests;
+
 /// A resizable bit vector, optimized for size and inline storage.
 ///
 /// `SmallBitVec` is exactly one word wide. Depending on the required capacity, this word
 /// either stores the bits inline, or it stores a pointer to a separate buffer on the heap.
 pub struct SmallBitVec {
     data: usize,
 }
 
 /// Total number of bits per word.
-fn inline_bits() -> u32 {
-    size_of::<usize>() as u32 * 8
+fn inline_bits() -> usize {
+    size_of::<usize>() * 8
 }
 
 /// For an inline vector, all bits except two can be used as storage capacity:
 ///
 /// - The rightmost bit is set to zero to signal an inline vector.
 /// - The position of the rightmost nonzero bit encodes the length.
-fn inline_capacity() -> u32 {
+fn inline_capacity() -> usize {
     inline_bits() - 2
 }
 
 /// Left shift amount to access the nth bit
-fn inline_shift(n: u32) -> u32 {
+fn inline_shift(n: usize) -> usize {
     debug_assert!(n <= inline_capacity());
     // The storage starts at the leftmost bit.
     inline_bits() - 1 - n
 }
 
 /// An inline vector with the nth bit set.
-fn inline_index(n: u32) -> usize {
+fn inline_index(n: usize) -> usize {
     1 << inline_shift(n)
 }
 
 /// An inline vector with the leftmost `n` bits set.
-fn inline_ones(n: u32) -> usize {
+fn inline_ones(n: usize) -> usize {
     if n == 0 {
         0
     } else {
         !0 << (inline_bits() - n)
     }
 }
 
 /// If the rightmost bit of `data` is set, then the remaining bits of `data`
 /// are a pointer to a heap allocation.
 const HEAP_FLAG: usize = 1;
 
 /// The allocation will contain a `Header` followed by a [Storage] buffer.
-type Storage = u32;
+type Storage = usize;
 
 /// The number of bits in one `Storage`.
 #[inline(always)]
-fn bits_per_storage() -> u32 {
-    size_of::<Storage>() as u32 * 8
+fn bits_per_storage() -> usize {
+    size_of::<Storage>() * 8
 }
 
 /// Data stored at the start of the heap allocation.
 ///
 /// `Header` must have the same alignment as `Storage`.
 struct Header {
     /// The number of bits in this bit vector.
     len: Storage,
 
-    /// The number of elements in the [u32] buffer that follows this header.
+    /// The number of elements in the [usize] buffer that follows this header.
     buffer_len: Storage,
 }
 
 impl Header {
     /// Create a heap allocation with enough space for a header,
     /// plus a buffer of at least `cap` bits, each initialized to `val`.
-    fn new(cap: u32, len: u32, val: bool) -> *mut Header {
+    fn new(cap: usize, len: usize, val: bool) -> *mut Header {
         let alloc_len = header_len() + buffer_len(cap);
         let init = if val { !0 } else { 0 };
 
         let v: Vec<Storage> = vec![init; alloc_len];
 
         let buffer_len = v.capacity() - header_len();
         let header_ptr = v.as_ptr() as *mut Header;
 
         forget(v);
 
         unsafe {
             (*header_ptr).len = len;
-            (*header_ptr).buffer_len = buffer_len as u32;
+            (*header_ptr).buffer_len = buffer_len;
         }
         header_ptr
     }
 }
 
 /// The number of `Storage` elements to allocate to hold a header.
 fn header_len() -> usize {
     size_of::<Header>() / size_of::<Storage>()
 }
 
 /// The minimum number of `Storage` elements to hold at least `cap` bits.
-fn buffer_len(cap: u32) -> usize {
-    ((cap + bits_per_storage() - 1) / bits_per_storage()) as usize
+fn buffer_len(cap: usize) -> usize {
+    (cap + bits_per_storage() - 1) / bits_per_storage()
 }
 
 impl SmallBitVec {
     /// Create an empty vector.
     #[inline]
     pub fn new() -> SmallBitVec {
         SmallBitVec {
-            data: inline_index(0)
+            data: inline_index(0),
         }
     }
 
     /// Create a vector containing `len` bits, each set to `val`.
-    pub fn from_elem(len: u32, val: bool) -> SmallBitVec {
+    pub fn from_elem(len: usize, val: bool) -> SmallBitVec {
         if len <= inline_capacity() {
             return SmallBitVec {
                 data: if val {
                     inline_ones(len + 1)
                 } else {
                     inline_index(len)
-                }
-            }
+                },
+            };
         }
         let header_ptr = Header::new(len, len, val);
         SmallBitVec {
-            data: (header_ptr as usize) | HEAP_FLAG
+            data: (header_ptr as usize) | HEAP_FLAG,
         }
     }
 
-    /// Create an empty vector enough storage pre-allocated to store at least `cap` bits without
-    /// resizing.
-    pub fn with_capacity(cap: u32) -> SmallBitVec {
+    /// Create an empty vector with enough storage pre-allocated to store at least `cap` bits
+    /// without resizing.
+    pub fn with_capacity(cap: usize) -> SmallBitVec {
         // Use inline storage if possible.
         if cap <= inline_capacity() {
-            return SmallBitVec::new()
+            return SmallBitVec::new();
         }
 
         // Otherwise, allocate on the heap.
         let header_ptr = Header::new(cap, 0, false);
         SmallBitVec {
-            data: (header_ptr as usize) | HEAP_FLAG
+            data: (header_ptr as usize) | HEAP_FLAG,
         }
     }
 
     /// The number of bits stored in this bit vector.
     #[inline]
-    pub fn len(&self) -> u32 {
+    pub fn len(&self) -> usize {
         if self.is_inline() {
             // The rightmost nonzero bit is a sentinel.  All bits to the left of
             // the sentinel bit are the elements of the bit vector.
-            inline_bits() - self.data.trailing_zeros() - 1
+            inline_bits() - self.data.trailing_zeros() as usize - 1
         } else {
             self.header().len
         }
     }
 
     /// Returns `true` if this vector contains no bits.
     #[inline]
     pub fn is_empty(&self) -> bool {
         self.len() == 0
     }
 
     /// The number of bits that can be stored in this bit vector without re-allocating.
     #[inline]
-    pub fn capacity(&self) -> u32 {
+    pub fn capacity(&self) -> usize {
         if self.is_inline() {
             inline_capacity()
         } else {
             self.header().buffer_len * bits_per_storage()
         }
     }
 
-    /// Get the nth bit in this bit vector.  Panics if the index is out of bounds.
+    /// Get the nth bit in this bit vector.
     #[inline]
-    pub fn get(&self, n: u32) -> bool {
-        assert!(n < self.len(), "Index {} out of bounds", n);
-        unsafe { self.get_unchecked(n) }
+    pub fn get(&self, n: usize) -> Option<bool> {
+        if n < self.len() {
+            Some(unsafe { self.get_unchecked(n) })
+        } else {
+            None
+        }
     }
 
     /// Get the nth bit in this bit vector, without bounds checks.
-    pub unsafe fn get_unchecked(&self, n: u32) -> bool {
+    pub unsafe fn get_unchecked(&self, n: usize) -> bool {
         if self.is_inline() {
             self.data & inline_index(n) != 0
         } else {
             let buffer = self.buffer();
-            let i = (n / bits_per_storage()) as usize;
+            let i = n / bits_per_storage();
             let offset = n % bits_per_storage();
             *buffer.get_unchecked(i) & (1 << offset) != 0
         }
     }
 
     /// Set the nth bit in this bit vector to `val`.  Panics if the index is out of bounds.
-    pub fn set(&mut self, n: u32, val: bool) {
+    pub fn set(&mut self, n: usize, val: bool) {
         assert!(n < self.len(), "Index {} out of bounds", n);
-        unsafe { self.set_unchecked(n, val); }
+        unsafe {
+            self.set_unchecked(n, val);
+        }
     }
 
     /// Set the nth bit in this bit vector to `val`, without bounds checks.
-    pub unsafe fn set_unchecked(&mut self, n: u32, val: bool) {
+    pub unsafe fn set_unchecked(&mut self, n: usize, val: bool) {
         if self.is_inline() {
             if val {
                 self.data |= inline_index(n);
             } else {
                 self.data &= !inline_index(n);
             }
         } else {
             let buffer = self.buffer_mut();
-            let i = (n / bits_per_storage()) as usize;
+            let i = n / bits_per_storage();
             let offset = n % bits_per_storage();
             if val {
                 *buffer.get_unchecked_mut(i) |= 1 << offset;
             } else {
                 *buffer.get_unchecked_mut(i) &= !(1 << offset);
             }
         }
     }
@@ -238,17 +288,17 @@ impl SmallBitVec {
     /// Append a bit to the end of the vector.
     ///
     /// ```
     /// use smallbitvec::SmallBitVec;
     /// let mut v = SmallBitVec::new();
     /// v.push(true);
     ///
     /// assert_eq!(v.len(), 1);
-    /// assert_eq!(v.get(0), true);
+    /// assert_eq!(v.get(0), Some(true));
     /// ```
     #[inline]
     pub fn push(&mut self, val: bool) {
         let idx = self.len();
         if idx == self.capacity() {
             self.reserve(1);
         }
         unsafe {
@@ -266,215 +316,232 @@ impl SmallBitVec {
     ///
     /// assert_eq!(v.pop(), Some(false));
     /// assert_eq!(v.len(), 0);
     /// assert_eq!(v.pop(), None);
     /// ```
     pub fn pop(&mut self) -> Option<bool> {
         let old_len = self.len();
         if old_len == 0 {
-            return None
+            return None;
         }
         unsafe {
             let val = self.get_unchecked(old_len - 1);
             self.set_len(old_len - 1);
             Some(val)
         }
     }
 
-    /// Remove the bit at index `idx`, shifting all later bits toward the front.
+    /// Remove and return the bit at index `idx`, shifting all later bits toward the front.
     ///
     /// Panics if the index is out of bounds.
-    pub fn remove(&mut self, idx: u32) {
+    pub fn remove(&mut self, idx: usize) -> bool {
         let len = self.len();
-        assert!(idx < len, "Index {} out of bounds", idx);
+        let val = self[idx];
 
         if self.is_inline() {
             // Shift later bits, including the length bit, toward the front.
             let mask = !inline_ones(idx);
             let new_vals = (self.data & mask) << 1;
             self.data = (self.data & !mask) | (new_vals & mask);
         } else {
-            let first = (idx / bits_per_storage()) as usize;
+            let first = idx / bits_per_storage();
             let offset = idx % bits_per_storage();
             let count = buffer_len(len);
             {
                 // Shift bits within the first storage block.
                 let buf = self.buffer_mut();
                 let mask = !0 << offset;
                 let new_vals = (buf[first] & mask) >> 1;
                 buf[first] = (buf[first] & !mask) | (new_vals & mask);
             }
             // Shift bits in subsequent storage blocks.
             for i in (first + 1)..count {
                 // Move the first bit into the previous block.
-                let bit_idx = i as u32 * bits_per_storage();
+                let bit_idx = i * bits_per_storage();
                 unsafe {
                     let first_bit = self.get_unchecked(bit_idx);
                     self.set_unchecked(bit_idx - 1, first_bit);
                 }
                 // Shift the remaining bits.
                 self.buffer_mut()[i] >>= 1;
             }
             // Decrement the length.
             unsafe {
                 self.set_len(len - 1);
             }
         }
+        val
     }
 
     /// Remove all elements from the vector, without deallocating its buffer.
     pub fn clear(&mut self) {
         unsafe {
             self.set_len(0);
         }
     }
 
     /// Reserve capacity for at least `additional` more elements to be inserted.
     ///
     /// May reserve more space than requested, to avoid frequent reallocations.
     ///
-    /// Panics if the new capacity overflows `u32`.
+    /// Panics if the new capacity overflows `usize`.
     ///
     /// Re-allocates only if `self.capacity() < self.len() + additional`.
-    pub fn reserve(&mut self, additional: u32) {
+    pub fn reserve(&mut self, additional: usize) {
         let old_cap = self.capacity();
-        let new_cap = self.len().checked_add(additional).expect("capacity overflow");
+        let new_cap = self.len()
+            .checked_add(additional)
+            .expect("capacity overflow");
         if new_cap <= old_cap {
-            return
+            return;
         }
         // Ensure the new capacity is at least double, to guarantee exponential growth.
         let double_cap = old_cap.saturating_mul(2);
         self.reallocate(max(new_cap, double_cap));
     }
 
     /// Set the length of the vector. The length must not exceed the capacity.
     ///
     /// If this makes the vector longer, then the values of its new elements
     /// are not specified.
-    unsafe fn set_len(&mut self, len: u32) {
+    unsafe fn set_len(&mut self, len: usize) {
         debug_assert!(len <= self.capacity());
         if self.is_inline() {
             let sentinel = inline_index(len);
             let mask = !(sentinel - 1);
             self.data |= sentinel;
             self.data &= mask;
         } else {
             self.header_mut().len = len;
         }
     }
 
     /// Returns an iterator that yields the bits of the vector in order, as `bool` values.
     pub fn iter(&self) -> Iter {
-        Iter { vec: self, range: 0..self.len() }
+        Iter {
+            vec: self,
+            range: 0..self.len(),
+        }
+    }
+
+    /// Returns an immutable view of a range of bits from this vec.
+    /// ```
+    /// #[macro_use] extern crate smallbitvec;
+    /// let v = sbvec![true, false, true];
+    /// let r = v.range(1..3);
+    /// assert_eq!(r[1], true);
+    /// ```
+    pub fn range(&self, range: Range<usize>) -> VecRange {
+        assert!(range.end <= self.len(), "range out of bounds");
+        VecRange { vec: &self, range }
     }
 
     /// Returns true if all the bits in the vec are set to zero/false.
     pub fn all_false(&self) -> bool {
         let mut len = self.len();
         if len == 0 {
-            return true
+            return true;
         }
 
         if self.is_inline() {
             let mask = inline_ones(len);
             self.data & mask == 0
         } else {
             for &storage in self.buffer() {
                 if len >= bits_per_storage() {
                     if storage != 0 {
-                        return false
+                        return false;
                     }
                     len -= bits_per_storage();
                 } else {
                     let mask = (1 << len) - 1;
                     if storage & mask != 0 {
-                        return false
+                        return false;
                     }
-                    break
+                    break;
                 }
             }
             true
         }
     }
 
     /// Returns true if all the bits in the vec are set to one/true.
     pub fn all_true(&self) -> bool {
         let mut len = self.len();
         if len == 0 {
-            return true
+            return true;
         }
 
         if self.is_inline() {
             let mask = inline_ones(len);
             self.data & mask == mask
         } else {
             for &storage in self.buffer() {
                 if len >= bits_per_storage() {
                     if storage != !0 {
-                        return false
+                        return false;
                     }
                     len -= bits_per_storage();
                 } else {
                     let mask = (1 << len) - 1;
                     if storage & mask != mask {
-                        return false
+                        return false;
                     }
-                    break
+                    break;
                 }
             }
             true
         }
     }
 
     /// Resize the vector to have capacity for at least `cap` bits.
     ///
     /// `cap` must be at least as large as the length of the vector.
-    fn reallocate(&mut self, cap: u32) {
+    fn reallocate(&mut self, cap: usize) {
         let old_cap = self.capacity();
         if cap <= old_cap {
-            return
+            return;
         }
         assert!(self.len() <= cap);
 
         if self.is_heap() {
-            let old_buffer_len = self.header().buffer_len as usize;
+            let old_buffer_len = self.header().buffer_len;
             let new_buffer_len = buffer_len(cap);
 
             let old_alloc_len = header_len() + old_buffer_len;
             let new_alloc_len = header_len() + new_buffer_len;
 
             let old_ptr = self.header_raw() as *mut Storage;
-            let mut v = unsafe {
-                Vec::from_raw_parts(old_ptr, old_alloc_len, old_alloc_len)
-            };
+            let mut v = unsafe { Vec::from_raw_parts(old_ptr, old_alloc_len, old_alloc_len) };
             v.resize(new_alloc_len, 0);
             v.shrink_to_fit();
             self.data = v.as_ptr() as usize | HEAP_FLAG;
             forget(v);
 
-            self.header_mut().buffer_len = new_buffer_len as u32;
+            self.header_mut().buffer_len = new_buffer_len;
         } else {
             let old_self = replace(self, SmallBitVec::with_capacity(cap));
             unsafe {
                 self.set_len(old_self.len());
                 for i in 0..old_self.len() {
                     self.set_unchecked(i, old_self.get_unchecked(i));
                 }
             }
         }
     }
 
     /// If the vector owns a heap allocation, returns a pointer to the start of the allocation.
     ///
     /// The layout of the data at this allocation is a private implementation detail.
-    pub fn heap_ptr(&self) -> Option<*const u32> {
-        match self.is_heap() {
-            true => Some((self.data & !HEAP_FLAG) as *const Storage),
-            false => None
+    pub fn heap_ptr(&self) -> Option<*const usize> {
+        if self.is_heap() {
+            Some((self.data & !HEAP_FLAG) as *const Storage)
+        } else {
+            None
         }
     }
 
     /// If the rightmost bit is set, then we treat it as inline storage.
     fn is_inline(&self) -> bool {
         self.data & HEAP_FLAG == 0
     }
 
@@ -496,17 +563,17 @@ impl SmallBitVec {
     fn header(&self) -> &Header {
         unsafe { &*self.header_raw() }
     }
 
     /// Get the buffer of a heap-allocated vector.
     fn buffer_raw(&self) -> *mut [Storage] {
         unsafe {
             let header_ptr = self.header_raw();
-            let buffer_len = (*header_ptr).buffer_len as usize;
+            let buffer_len = (*header_ptr).buffer_len;
             let buffer_ptr = (header_ptr as *mut Storage)
                 .offset((size_of::<Header>() / size_of::<Storage>()) as isize);
             slice::from_raw_parts_mut(buffer_ptr, buffer_len)
         }
     }
 
     fn buffer_mut(&mut self) -> &mut [Storage] {
         unsafe { &mut *self.buffer_raw() }
@@ -517,136 +584,159 @@ impl SmallBitVec {
     }
 }
 
 // Trait implementations:
 
 impl fmt::Debug for SmallBitVec {
     #[inline]
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        fmt.debug_list().entries(self.iter().map(|b| b as u8)).finish()
+        fmt.debug_list()
+            .entries(self.iter().map(|b| b as u8))
+            .finish()
+    }
+}
+
+impl Default for SmallBitVec {
+    fn default() -> Self {
+        Self::new()
     }
 }
 
 impl PartialEq for SmallBitVec {
     fn eq(&self, other: &Self) -> bool {
         // Compare by inline representation
         if self.is_inline() && other.is_inline() {
-            return self.data == other.data
+            return self.data == other.data;
         }
 
         let len = self.len();
         if len != other.len() {
-            return false
+            return false;
         }
 
         // Compare by heap representation
         if self.is_heap() && other.is_heap() {
             let buf0 = self.buffer();
             let buf1 = other.buffer();
 
-            let full_blocks = (len / bits_per_storage()) as usize;
+            let full_blocks = len / bits_per_storage();
             let remainder = len % bits_per_storage();
 
             if buf0[..full_blocks] != buf1[..full_blocks] {
-                return false
+                return false;
             }
 
             if remainder != 0 {
                 let mask = (1 << remainder) - 1;
                 if buf0[full_blocks] & mask != buf1[full_blocks] & mask {
-                    return false
+                    return false;
                 }
             }
-            return true
+            return true;
         }
 
         // Representations differ; fall back to bit-by-bit comparison
         Iterator::eq(self.iter(), other.iter())
     }
 }
 
 impl Eq for SmallBitVec {}
 
 impl Drop for SmallBitVec {
     fn drop(&mut self) {
         if self.is_heap() {
             unsafe {
                 let header_ptr = self.header_raw();
                 let alloc_ptr = header_ptr as *mut Storage;
-                let alloc_len = header_len() + (*header_ptr).buffer_len as usize;
+                let alloc_len = header_len() + (*header_ptr).buffer_len;
                 Vec::from_raw_parts(alloc_ptr, alloc_len, alloc_len);
             }
         }
     }
 }
 
 impl Clone for SmallBitVec {
     fn clone(&self) -> Self {
         if self.is_inline() {
-            return SmallBitVec { data: self.data }
+            return SmallBitVec { data: self.data };
         }
 
-        let buffer_len = self.header().buffer_len as usize;
+        let buffer_len = self.header().buffer_len;
         let alloc_len = header_len() + buffer_len;
         let ptr = self.header_raw() as *mut Storage;
-        let raw_allocation = unsafe {
-            slice::from_raw_parts(ptr, alloc_len)
-        };
+        let raw_allocation = unsafe { slice::from_raw_parts(ptr, alloc_len) };
 
         let v = raw_allocation.to_vec();
         let header_ptr = v.as_ptr() as *mut Header;
         forget(v);
         SmallBitVec {
-            data: (header_ptr as usize) | HEAP_FLAG
+            data: (header_ptr as usize) | HEAP_FLAG,
+        }
+    }
+}
+
+impl Index<usize> for SmallBitVec {
+    type Output = bool;
+
+    #[inline]
+    fn index(&self, i: usize) -> &bool {
+        assert!(i < self.len(), "index out of range");
+        if self.get(i).unwrap() {
+            &true
+        } else {
+            &false
         }
     }
 }
 
 impl hash::Hash for SmallBitVec {
     #[inline]
     fn hash<H: hash::Hasher>(&self, state: &mut H) {
         self.len().hash(state);
         for b in self.iter() {
             b.hash(state);
         }
     }
 }
 
 impl Extend<bool> for SmallBitVec {
     #[inline]
-    fn extend<I: IntoIterator<Item=bool>>(&mut self, iter: I) {
+    fn extend<I: IntoIterator<Item = bool>>(&mut self, iter: I) {
         let iter = iter.into_iter();
 
         let (min, _) = iter.size_hint();
-        assert!(min <= u32::max_value() as usize, "capacity overflow");
-        self.reserve(min as u32);
+        assert!(min <= usize::max_value(), "capacity overflow");
+        self.reserve(min);
 
         for element in iter {
             self.push(element)
         }
     }
 }
 
 impl FromIterator<bool> for SmallBitVec {
     #[inline]
-    fn from_iter<I: IntoIterator<Item=bool>>(iter: I) -> Self {
+    fn from_iter<I: IntoIterator<Item = bool>>(iter: I) -> Self {
         let mut v = SmallBitVec::new();
         v.extend(iter);
         v
     }
 }
 
 impl IntoIterator for SmallBitVec {
     type Item = bool;
     type IntoIter = IntoIter;
 
     #[inline]
     fn into_iter(self) -> IntoIter {
-        IntoIter { range: 0..self.len(), vec: self }
+        IntoIter {
+            range: 0..self.len(),
+            vec: self,
+        }
     }
 }
 
 impl<'a> IntoIterator for &'a SmallBitVec {
     type Item = bool;
     type IntoIter = Iter<'a>;
 
     #[inline]
@@ -657,326 +747,105 @@ impl<'a> IntoIterator for &'a SmallBitVe
 
 /// An iterator that owns a SmallBitVec and yields its bits as `bool` values.
 ///
 /// Returned from [`SmallBitVec::into_iter`][1].
 ///
 /// [1]: struct.SmallBitVec.html#method.into_iter
 pub struct IntoIter {
     vec: SmallBitVec,
-    range: Range<u32>,
+    range: Range<usize>,
 }
 
 impl Iterator for IntoIter {
     type Item = bool;
 
     #[inline]
     fn next(&mut self) -> Option<bool> {
-        self.range.next().map(|i| unsafe { self.vec.get_unchecked(i) })
+        self.range
+            .next()
+            .map(|i| unsafe { self.vec.get_unchecked(i) })
     }
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.range.size_hint()
     }
 }
 
 impl DoubleEndedIterator for IntoIter {
     #[inline]
     fn next_back(&mut self) -> Option<bool> {
-        self.range.next_back().map(|i| unsafe { self.vec.get_unchecked(i) })
+        self.range
+            .next_back()
+            .map(|i| unsafe { self.vec.get_unchecked(i) })
     }
 }
 
 impl ExactSizeIterator for IntoIter {}
 
 /// An iterator that borrows a SmallBitVec and yields its bits as `bool` values.
 ///
 /// Returned from [`SmallBitVec::iter`][1].
 ///
 /// [1]: struct.SmallBitVec.html#method.iter
 pub struct Iter<'a> {
     vec: &'a SmallBitVec,
-    range: Range<u32>,
+    range: Range<usize>,
 }
 
 impl<'a> Iterator for Iter<'a> {
     type Item = bool;
 
     #[inline]
     fn next(&mut self) -> Option<bool> {
-        self.range.next().map(|i| unsafe { self.vec.get_unchecked(i) })
+        self.range
+            .next()
+            .map(|i| unsafe { self.vec.get_unchecked(i) })
     }
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.range.size_hint()
     }
 }
 
 impl<'a> DoubleEndedIterator for Iter<'a> {
     #[inline]
     fn next_back(&mut self) -> Option<bool> {
-        self.range.next_back().map(|i| unsafe { self.vec.get_unchecked(i) })
+        self.range
+            .next_back()
+            .map(|i| unsafe { self.vec.get_unchecked(i) })
     }
 }
 
 impl<'a> ExactSizeIterator for Iter<'a> {}
 
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    macro_rules! v {
-        ($elem:expr; $n:expr) => ({
-            SmallBitVec::from_elem($n, $elem)
-        });
-        ($($x:expr),*) => ({
-            [$($x),*].iter().cloned().collect::<SmallBitVec>()
-        });
-    }
-
-
-    #[cfg(target_pointer_width = "32")]
-    #[test]
-    fn test_inline_capacity() {
-        assert_eq!(inline_capacity(), 30);
-    }
-
-    #[cfg(target_pointer_width = "64")]
-    #[test]
-    fn test_inline_capacity() {
-        assert_eq!(inline_capacity(), 62);
-    }
-
-    #[test]
-    fn new() {
-        let v = SmallBitVec::new();
-        assert_eq!(v.len(), 0);
-        assert_eq!(v.capacity(), inline_capacity());
-        assert!(v.is_empty());
-        assert!(v.is_inline());
-    }
-
-    #[test]
-    fn with_capacity_inline() {
-        for cap in 0..(inline_capacity() + 1) {
-            let v = SmallBitVec::with_capacity(cap);
-            assert_eq!(v.len(), 0);
-            assert_eq!(v.capacity(), inline_capacity());
-            assert!(v.is_inline());
-        }
-    }
-
-    #[test]
-    fn with_capacity_heap() {
-        let cap = inline_capacity() + 1;
-        let v = SmallBitVec::with_capacity(cap);
-        assert_eq!(v.len(), 0);
-        assert!(v.capacity() > inline_capacity());
-        assert!(v.is_heap());
-    }
+/// An immutable view of a range of bits from a borrowed SmallBitVec.
+///
+/// Returned from [`SmallBitVec::range`][1].
+///
+/// [1]: struct.SmallBitVec.html#method.range
+#[derive(Debug, Clone)]
+pub struct VecRange<'a> {
+    vec: &'a SmallBitVec,
+    range: Range<usize>,
+}
 
-    #[test]
-    fn set_len_inline() {
-        let mut v = SmallBitVec::new();
-        for i in 0..(inline_capacity() + 1) {
-            unsafe { v.set_len(i); }
-            assert_eq!(v.len(), i);
-        }
-        for i in (0..(inline_capacity() + 1)).rev() {
-            unsafe { v.set_len(i); }
-            assert_eq!(v.len(), i);
-        }
-    }
-
-    #[test]
-    fn set_len_heap() {
-        let mut v = SmallBitVec::with_capacity(500);
-        unsafe { v.set_len(30); }
-        assert_eq!(v.len(), 30);
-    }
-
-    #[test]
-    fn push_many() {
-        let mut v = SmallBitVec::new();
-        for i in 0..500 {
-            v.push(i % 3 == 0);
-        }
-        assert_eq!(v.len(), 500);
-
-        for i in 0..500 {
-            assert_eq!(v.get(i), (i % 3 == 0), "{}", i);
-        }
-    }
-
-    #[test]
-    #[should_panic]
-    fn get_out_of_bounds() {
-        let v = SmallBitVec::new();
-        v.get(0);
-    }
-
-    #[test]
-    #[should_panic]
-    fn set_out_of_bounds() {
-        let mut v = SmallBitVec::new();
-        v.set(2, false);
-    }
-
-    #[test]
-    fn all_false() {
-        let mut v = SmallBitVec::new();
-        assert!(v.all_false());
-        for _ in 0..100 {
-            v.push(false);
-            assert!(v.all_false());
-
-            let mut v2 = v.clone();
-            v2.push(true);
-            assert!(!v2.all_false());
-        }
-    }
-
-    #[test]
-    fn all_true() {
-        let mut v = SmallBitVec::new();
-        assert!(v.all_true());
-        for _ in 0..100 {
-            v.push(true);
-            assert!(v.all_true());
-
-            let mut v2 = v.clone();
-            v2.push(false);
-            assert!(!v2.all_true());
+impl<'a> VecRange<'a> {
+    pub fn iter(&self) -> Iter<'a> {
+        Iter {
+            vec: self.vec,
+            range: self.range.clone(),
         }
     }
-
-    #[test]
-    fn iter() {
-        let mut v = SmallBitVec::new();
-        v.push(true);
-        v.push(false);
-        v.push(false);
-
-        let mut i = v.iter();
-        assert_eq!(i.next(), Some(true));
-        assert_eq!(i.next(), Some(false));
-        assert_eq!(i.next(), Some(false));
-        assert_eq!(i.next(), None);
-    }
-
-    #[test]
-    fn into_iter() {
-        let mut v = SmallBitVec::new();
-        v.push(true);
-        v.push(false);
-        v.push(false);
-
-        let mut i = v.into_iter();
-        assert_eq!(i.next(), Some(true));
-        assert_eq!(i.next(), Some(false));
-        assert_eq!(i.next(), Some(false));
-        assert_eq!(i.next(), None);
-    }
+}
 
-    #[test]
-    fn iter_back() {
-        let mut v = SmallBitVec::new();
-        v.push(true);
-        v.push(false);
-        v.push(false);
-
-        let mut i = v.iter();
-        assert_eq!(i.next_back(), Some(false));
-        assert_eq!(i.next_back(), Some(false));
-        assert_eq!(i.next_back(), Some(true));
-        assert_eq!(i.next(), None);
-    }
-
-    #[test]
-    fn debug() {
-        let mut v = SmallBitVec::new();
-        v.push(true);
-        v.push(false);
-        v.push(false);
-
-        assert_eq!(format!("{:?}", v), "[1, 0, 0]")
-    }
-
-    #[test]
-    fn from_elem() {
-        for len in 0..100 {
-            let ones = SmallBitVec::from_elem(len, true);
-            assert_eq!(ones.len(), len);
-            assert!(ones.all_true());
+impl<'a> Index<usize> for VecRange<'a> {
+    type Output = bool;
 
-            let zeros = SmallBitVec::from_elem(len, false);
-            assert_eq!(zeros.len(), len);
-            assert!(zeros.all_false());
-        }
-    }
-
-    #[test]
-    fn remove() {
-        let mut v = SmallBitVec::new();
-        v.push(false);
-        v.push(true);
-        v.push(false);
-        v.push(false);
-        v.push(true);
-
-        v.remove(1);
-        assert_eq!(format!("{:?}", v), "[0, 0, 0, 1]");
-        v.remove(0);
-        assert_eq!(format!("{:?}", v), "[0, 0, 1]");
-        v.remove(2);
-        assert_eq!(format!("{:?}", v), "[0, 0]");
-        v.remove(1);
-        assert_eq!(format!("{:?}", v), "[0]");
-        v.remove(0);
-        assert_eq!(format!("{:?}", v), "[]");
-    }
-
-    #[test]
-    fn remove_big() {
-        let mut v = SmallBitVec::from_elem(256, false);
-        v.set(100, true);
-        v.set(255, true);
-        v.remove(0);
-        assert_eq!(v.len(), 255);
-        assert_eq!(v.get(0), false);
-        assert_eq!(v.get(99), true);
-        assert_eq!(v.get(100), false);
-        assert_eq!(v.get(253), false);
-        assert_eq!(v.get(254), true);
-
-        v.remove(254);
-        assert_eq!(v.len(), 254);
-        assert_eq!(v.get(0), false);
-        assert_eq!(v.get(99), true);
-        assert_eq!(v.get(100), false);
-        assert_eq!(v.get(253), false);
-
-        v.remove(99);
-        assert_eq!(v, SmallBitVec::from_elem(253, false));
-    }
-
-    #[test]
-    fn eq() {
-        assert_eq!(v![], v![]);
-        assert_eq!(v![true], v![true]);
-        assert_eq!(v![false], v![false]);
-
-        assert_ne!(v![], v![false]);
-        assert_ne!(v![true], v![]);
-        assert_ne!(v![true], v![false]);
-        assert_ne!(v![false], v![true]);
-
-        assert_eq!(v![true, false], v![true, false]);
-        assert_eq!(v![true; 400], v![true; 400]);
-        assert_eq!(v![false; 400], v![false; 400]);
-
-        assert_ne!(v![true, false], v![true, true]);
-        assert_ne!(v![true; 400], v![true; 401]);
-        assert_ne!(v![false; 401], v![false; 400]);
+    #[inline]
+    fn index(&self, i: usize) -> &bool {
+        let vec_i = i + self.range.start;
+        assert!(vec_i < self.range.end, "index out of range");
+        &self.vec[vec_i]
     }
 }
new file mode 100644
--- /dev/null
+++ b/third_party/rust/smallbitvec/src/tests.rs
@@ -0,0 +1,313 @@
+// Copyright 2017 Matt Brubeck. See the COPYRIGHT file at the top-level
+// directory of this distribution and at http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use super::*;
+
+#[cfg(target_pointer_width = "32")]
+#[test]
+fn test_inline_capacity() {
+    assert_eq!(inline_capacity(), 30);
+}
+
+#[cfg(target_pointer_width = "64")]
+#[test]
+fn test_inline_capacity() {
+    assert_eq!(inline_capacity(), 62);
+}
+
+#[test]
+fn new() {
+    let v = SmallBitVec::new();
+    assert_eq!(v.len(), 0);
+    assert_eq!(v.capacity(), inline_capacity());
+    assert!(v.is_empty());
+    assert!(v.is_inline());
+}
+
+#[test]
+fn with_capacity_inline() {
+    for cap in 0..(inline_capacity() + 1) {
+        let v = SmallBitVec::with_capacity(cap);
+        assert_eq!(v.len(), 0);
+        assert_eq!(v.capacity(), inline_capacity());
+        assert!(v.is_inline());
+    }
+}
+
+#[test]
+fn with_capacity_heap() {
+    let cap = inline_capacity() + 1;
+    let v = SmallBitVec::with_capacity(cap);
+    assert_eq!(v.len(), 0);
+    assert!(v.capacity() > inline_capacity());
+    assert!(v.is_heap());
+}
+
+#[test]
+fn set_len_inline() {
+    let mut v = SmallBitVec::new();
+    for i in 0..(inline_capacity() + 1) {
+        unsafe {
+            v.set_len(i);
+        }
+        assert_eq!(v.len(), i);
+    }
+    for i in (0..(inline_capacity() + 1)).rev() {
+        unsafe {
+            v.set_len(i);
+        }
+        assert_eq!(v.len(), i);
+    }
+}
+
+#[test]
+fn set_len_heap() {
+    let mut v = SmallBitVec::with_capacity(500);
+    unsafe {
+        v.set_len(30);
+    }
+    assert_eq!(v.len(), 30);
+}
+
+#[test]
+fn push_many() {
+    let mut v = SmallBitVec::new();
+    for i in 0..500 {
+        v.push(i % 3 == 0);
+    }
+    assert_eq!(v.len(), 500);
+
+    for i in 0..500 {
+        assert_eq!(v.get(i).unwrap(), (i % 3 == 0), "{}", i);
+        assert_eq!(v[i], v.get(i).unwrap());
+    }
+}
+
+#[test]
+#[should_panic(expected = "index out of range")]
+fn index_out_of_bounds() {
+    let v = SmallBitVec::new();
+    v[0];
+}
+
+#[test]
+#[should_panic(expected = "index out of range")]
+fn index_out_of_bounds_nonempty() {
+    let mut v = SmallBitVec::new();
+    v.push(true);
+    v[1 << 32];
+}
+
+#[test]
+fn get_out_of_bounds() {
+    let v = SmallBitVec::new();
+    assert!(v.get(0).is_none());
+}
+
+#[test]
+#[should_panic]
+fn set_out_of_bounds() {
+    let mut v = SmallBitVec::new();
+    v.set(2, false);
+}
+
+#[test]
+fn all_false() {
+    let mut v = SmallBitVec::new();
+    assert!(v.all_false());
+    for _ in 0..100 {
+        v.push(false);
+        assert!(v.all_false());
+
+        let mut v2 = v.clone();
+        v2.push(true);
+        assert!(!v2.all_false());
+    }
+}
+
+#[test]
+fn all_true() {
+    let mut v = SmallBitVec::new();
+    assert!(v.all_true());
+    for _ in 0..100 {
+        v.push(true);
+        assert!(v.all_true());
+
+        let mut v2 = v.clone();
+        v2.push(false);
+        assert!(!v2.all_true());
+    }
+}
+
+#[test]
+fn iter() {
+    let mut v = SmallBitVec::new();
+    v.push(true);
+    v.push(false);
+    v.push(false);
+
+    let mut i = v.iter();
+    assert_eq!(i.next(), Some(true));
+    assert_eq!(i.next(), Some(false));
+    assert_eq!(i.next(), Some(false));
+    assert_eq!(i.next(), None);
+}
+
+#[test]
+fn into_iter() {
+    let mut v = SmallBitVec::new();
+    v.push(true);
+    v.push(false);
+    v.push(false);
+
+    let mut i = v.into_iter();
+    assert_eq!(i.next(), Some(true));
+    assert_eq!(i.next(), Some(false));
+    assert_eq!(i.next(), Some(false));
+    assert_eq!(i.next(), None);
+}
+
+#[test]
+fn iter_back() {
+    let mut v = SmallBitVec::new();
+    v.push(true);
+    v.push(false);
+    v.push(false);
+
+    let mut i = v.iter();
+    assert_eq!(i.next_back(), Some(false));
+    assert_eq!(i.next_back(), Some(false));
+    assert_eq!(i.next_back(), Some(true));
+    assert_eq!(i.next(), None);
+}
+
+#[test]
+fn range() {
+    let mut v = SmallBitVec::new();
+    v.push(true);
+    v.push(false);
+    v.push(false);
+    v.push(true);
+
+    let r = v.range(0..2);
+    let mut ri = r.iter();
+    assert_eq!(ri.next(), Some(true));
+    assert_eq!(ri.next(), Some(false));
+    assert_eq!(ri.next(), None);
+    assert_eq!(r[0], true);
+}
+
+#[test]
+#[should_panic(expected = "range out of bounds")]
+fn range_oob() {
+    let mut v = SmallBitVec::new();
+    v.push(true);
+
+    v.range(0..2);
+}
+
+#[test]
+#[should_panic(expected = "index out of range")]
+fn range_index_oob() {
+    let mut v = SmallBitVec::new();
+    v.push(true);
+    v.push(false);
+    v.push(true);
+
+    let r = v.range(1..2);
+    r[1];
+}
+
+#[test]
+fn debug() {
+    let mut v = SmallBitVec::new();
+    v.push(true);
+    v.push(false);
+    v.push(false);
+
+    assert_eq!(format!("{:?}", v), "[1, 0, 0]")
+}
+
+#[test]
+fn from_elem() {
+    for len in 0..100 {
+        let ones = SmallBitVec::from_elem(len, true);
+        assert_eq!(ones.len(), len);
+        assert!(ones.all_true());
+
+        let zeros = SmallBitVec::from_elem(len, false);
+        assert_eq!(zeros.len(), len);
+        assert!(zeros.all_false());
+    }
+}
+
+#[test]
+fn remove() {
+    let mut v = SmallBitVec::new();
+    v.push(false);
+    v.push(true);
+    v.push(false);
+    v.push(false);
+    v.push(true);
+
+    assert_eq!(v.remove(1), true);
+    assert_eq!(format!("{:?}", v), "[0, 0, 0, 1]");
+    assert_eq!(v.remove(0), false);
+    assert_eq!(format!("{:?}", v), "[0, 0, 1]");
+    v.remove(2);
+    assert_eq!(format!("{:?}", v), "[0, 0]");
+    v.remove(1);
+    assert_eq!(format!("{:?}", v), "[0]");
+    v.remove(0);
+    assert_eq!(format!("{:?}", v), "[]");
+}
+
+#[test]
+fn remove_big() {
+    let mut v = SmallBitVec::from_elem(256, false);
+    v.set(100, true);
+    v.set(255, true);
+    v.remove(0);
+    assert_eq!(v.len(), 255);
+    assert_eq!(v.get(0).unwrap(), false);
+    assert_eq!(v.get(99).unwrap(), true);
+    assert_eq!(v.get(100).unwrap(), false);
+    assert_eq!(v.get(253).unwrap(), false);
+    assert_eq!(v.get(254).unwrap(), true);
+
+    v.remove(254);
+    assert_eq!(v.len(), 254);
+    assert_eq!(v.get(0).unwrap(), false);
+    assert_eq!(v.get(99).unwrap(), true);
+    assert_eq!(v.get(100).unwrap(), false);
+    assert_eq!(v.get(253).unwrap(), false);
+
+    v.remove(99);
+    assert_eq!(v, SmallBitVec::from_elem(253, false));
+}
+
+#[test]
+fn eq() {
+    assert_eq!(sbvec![], sbvec![]);
+    assert_eq!(sbvec![true], sbvec![true]);
+    assert_eq!(sbvec![false], sbvec![false]);
+
+    assert_ne!(sbvec![], sbvec![false]);
+    assert_ne!(sbvec![true], sbvec![]);
+    assert_ne!(sbvec![true], sbvec![false]);
+    assert_ne!(sbvec![false], sbvec![true]);
+
+    assert_eq!(sbvec![true, false], sbvec![true, false]);
+    assert_eq!(sbvec![true; 400], sbvec![true; 400]);
+    assert_eq!(sbvec![false; 400], sbvec![false; 400]);
+
+    assert_ne!(sbvec![true, false], sbvec![true, true]);
+    assert_ne!(sbvec![true; 400], sbvec![true; 401]);
+    assert_ne!(sbvec![false; 401], sbvec![false; 400]);
+}