Bug 1393967 - Update cssparser to verison 0.19.5 (and some other dependencies) r?emilio draft
authorSimon Sapin <simon.sapin@exyr.org>
Fri, 25 Aug 2017 22:28:33 +0200
changeset 653389 685749ca204169a1ed36f5bc9b9ad26adc8075ea
parent 653388 bb813dab9832c1b780293edbc5477f920bf0c88e
child 728334 8015d97cd932e065444f8980aacfd8102ba991de
push id76322
push userbmo:simon.sapin@exyr.org
push dateFri, 25 Aug 2017 23:12:22 +0000
reviewersemilio
bugs1393967
milestone57.0a1
Bug 1393967 - Update cssparser to verison 0.19.5 (and some other dependencies) r?emilio MozReview-Commit-ID: GOxKFvP3Y9x
third_party/rust/cssparser/.cargo-checksum.json
third_party/rust/cssparser/Cargo.toml
third_party/rust/cssparser/src/lib.rs
third_party/rust/cssparser/src/parser.rs
third_party/rust/cssparser/src/rules_and_declarations.rs
third_party/rust/cssparser/src/tests.rs
third_party/rust/cssparser/src/tokenizer.rs
third_party/rust/parking_lot_core/.cargo-checksum.json
third_party/rust/parking_lot_core/Cargo.toml
third_party/rust/parking_lot_core/src/lib.rs
third_party/rust/parking_lot_core/src/parking_lot.rs
third_party/rust/parking_lot_core/src/thread_parker/generic.rs
third_party/rust/parking_lot_core/src/thread_parker/unix.rs
third_party/rust/parking_lot_core/src/word_lock.rs
third_party/rust/smallvec-0.3.3/.cargo-checksum.json
third_party/rust/smallvec-0.3.3/.cargo-ok
third_party/rust/smallvec-0.3.3/.travis.yml
third_party/rust/smallvec-0.3.3/Cargo.toml
third_party/rust/smallvec-0.3.3/README.md
third_party/rust/smallvec-0.3.3/benches/bench.rs
third_party/rust/smallvec-0.3.3/lib.rs
third_party/rust/smallvec/.cargo-checksum.json
third_party/rust/smallvec/.travis.yml
third_party/rust/smallvec/Cargo.toml
third_party/rust/smallvec/README.md
third_party/rust/smallvec/lib.rs
toolkit/library/gtest/rust/Cargo.lock
toolkit/library/rust/Cargo.lock
--- a/third_party/rust/cssparser/.cargo-checksum.json
+++ b/third_party/rust/cssparser/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".travis.yml":"f1fb4b65964c81bc1240544267ea334f554ca38ae7a74d57066f4d47d2b5d568","Cargo.toml":"c4f2dc684880666eaf58ade1209dc52e94a19b85b3b7ceeb1908642400c633f4","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"c5781e673335f37ed3d7acb119f8ed33efdf6eb75a7094b7da2abe0c3230adb8","build.rs":"950bcc47a196f07f99f59637c28cc65e02a885130011f90a2b2608248b4724a2","build/match_byte.rs":"89e8b941af74df2c204abf808672d3ff278bdec75abc918c41a843260b924677","docs/.nojekyll":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","docs/404.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","docs/index.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","src/color.rs":"b847b80097015cb7d0f4be67c0d8b2f6b82006be865917ff14a96b484760d460","src/cow_rc_str.rs":"541216f8ef74ee3cc5cbbc1347e5f32ed66588c401851c9a7d68b867aede1de0","src/from_bytes.rs":"331fe63af2123ae3675b61928a69461b5ac77799fff3ce9978c55cf2c558f4ff","src/lib.rs":"56d7bb15699a938c827ec57464525f0a58f0529920433db6c652142e97fd67e4","src/macros.rs":"adb9773c157890381556ea83d7942dcc676f99eea71abbb6afeffee1e3f28960","src/nth.rs":"246fa83a3ab97a7bb617c97a976af77136652ce77ba8ccca22e144b213b61310","src/parser.rs":"7a35d02bf0158a4725527e32295ce734d317e226569234d346952e27048f6ee2","src/rules_and_declarations.rs":"f2cde5c4518a2349d24049f6195e31783a8af2815d84394d21f90c763fc257a1","src/serializer.rs":"843c9d01de00523851a4c40f791c64e3b00325426cb38f897e4a2ddb4cfa6de8","src/size_of_tests.rs":"a28664d44797519119d659eaf7e84e1789ef97e9e2c2d36630eb9f226c0cc0a6","src/tests.rs":"120298ba20126c90ec6c8b1eb837b3c3a567fc6f9701552486191cc61d8459a6","src/tokenizer.rs":"914326e19bf2d97122b41e9930e16a70825aa5c4096bdb39c66d18388f4cdbda","src/unicode_range.rs":"fbbd0f4b393944699730a6b0f945b2b2376fcea61fce2ea37190fb287793021a"},"package":"1f9442c00898020a56c9485d64c9c8f14ae30ba45be89d15846046593383467f"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".travis.yml":"f1fb4b65964c81bc1240544267ea334f554ca38ae7a74d57066f4d47d2b5d568","Cargo.toml":"a52213c38e6ff8fcbf4c2f632c6d78521a9a8b9cfcfdfa34339544649d486076","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"c5781e673335f37ed3d7acb119f8ed33efdf6eb75a7094b7da2abe0c3230adb8","build.rs":"950bcc47a196f07f99f59637c28cc65e02a885130011f90a2b2608248b4724a2","build/match_byte.rs":"89e8b941af74df2c204abf808672d3ff278bdec75abc918c41a843260b924677","docs/.nojekyll":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","docs/404.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","docs/index.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","src/color.rs":"b847b80097015cb7d0f4be67c0d8b2f6b82006be865917ff14a96b484760d460","src/cow_rc_str.rs":"541216f8ef74ee3cc5cbbc1347e5f32ed66588c401851c9a7d68b867aede1de0","src/from_bytes.rs":"331fe63af2123ae3675b61928a69461b5ac77799fff3ce9978c55cf2c558f4ff","src/lib.rs":"77c0852be9ba7682f4e325a09ebac03ce25aafec30142eb10937b77651a29d67","src/macros.rs":"adb9773c157890381556ea83d7942dcc676f99eea71abbb6afeffee1e3f28960","src/nth.rs":"246fa83a3ab97a7bb617c97a976af77136652ce77ba8ccca22e144b213b61310","src/parser.rs":"3a315b7600e80b577c5d04f215038c55ae1c9e5a2c70c6587850cd7fc1be6ae4","src/rules_and_declarations.rs":"44e47663aaa8a5ff167393b91337e377e5a4fcbef64b227028780b6d22879f69","src/serializer.rs":"843c9d01de00523851a4c40f791c64e3b00325426cb38f897e4a2ddb4cfa6de8","src/size_of_tests.rs":"a28664d44797519119d659eaf7e84e1789ef97e9e2c2d36630eb9f226c0cc0a6","src/tests.rs":"c07f5d8464217b1650f7ee8911b90ef67947876305be215d1e666a20a793dbfb","src/tokenizer.rs":"63640e6a2d875e8afda9dea6034b8c57db9b5877c3c491a97fee1c6ec223b75d","src/unicode_range.rs":"fbbd0f4b393944699730a6b0f945b2b2376fcea61fce2ea37190fb287793021a"},"package":"dc476dc0960774aa1cabfd0044de7d4585a8f2f8a3ef72e6d9d1e16c1e2492b1"}
\ No newline at end of file
--- a/third_party/rust/cssparser/Cargo.toml
+++ b/third_party/rust/cssparser/Cargo.toml
@@ -7,56 +7,59 @@
 #
 # 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 = "cssparser"
-version = "0.19.2"
+version = "0.19.5"
 authors = ["Simon Sapin <simon.sapin@exyr.org>"]
 build = "build.rs"
 exclude = ["src/css-parsing-tests/**", "src/big-data-url.css"]
 description = "Rust implementation of CSS Syntax Level 3"
 documentation = "https://docs.rs/cssparser/"
 readme = "README.md"
 keywords = ["css", "syntax", "parser"]
 license = "MPL-2.0"
 repository = "https://github.com/servo/rust-cssparser"
-[dependencies.serde]
-version = "1.0"
-optional = true
+[dependencies.cssparser-macros]
+version = "0.3"
 
 [dependencies.procedural-masquerade]
 version = "0.1"
 
+[dependencies.matches]
+version = "0.1"
+
 [dependencies.dtoa-short]
 version = "0.3"
 
-[dependencies.heapsize]
-version = ">= 0.3, < 0.5"
-optional = true
-
-[dependencies.cssparser-macros]
-version = "0.3"
+[dependencies.smallvec]
+version = "0.4.3"
 
 [dependencies.phf]
 version = "0.7"
 
-[dependencies.matches]
-version = "0.1"
+[dependencies.serde]
+version = "1.0"
+optional = true
+
+[dependencies.heapsize]
+version = ">= 0.3, < 0.5"
+optional = true
 [dev-dependencies.difference]
 version = "1.0"
 
+[dev-dependencies.encoding_rs]
+version = "0.5"
+
 [dev-dependencies.rustc-serialize]
 version = "0.3"
-
-[dev-dependencies.encoding_rs]
-version = "0.5"
 [build-dependencies.syn]
 version = "0.11"
 
 [build-dependencies.quote]
 version = "0.3"
 
 [features]
 dummy_match_byte = []
--- a/third_party/rust/cssparser/src/lib.rs
+++ b/third_party/rust/cssparser/src/lib.rs
@@ -73,16 +73,17 @@ extern crate dtoa_short;
 #[macro_use] extern crate matches;
 #[macro_use] extern crate procedural_masquerade;
 #[doc(hidden)] pub extern crate phf as _internal__phf;
 #[cfg(test)] extern crate encoding_rs;
 #[cfg(test)] extern crate difference;
 #[cfg(test)] extern crate rustc_serialize;
 #[cfg(feature = "serde")] extern crate serde;
 #[cfg(feature = "heapsize")] #[macro_use] extern crate heapsize;
+extern crate smallvec;
 
 pub use cssparser_macros::*;
 
 pub use tokenizer::{Token, SourcePosition, SourceLocation};
 pub use rules_and_declarations::{parse_important};
 pub use rules_and_declarations::{DeclarationParser, DeclarationListParser, parse_one_declaration};
 pub use rules_and_declarations::{RuleListParser, parse_one_rule, PreciseParseError};
 pub use rules_and_declarations::{AtRuleType, QualifiedRuleParser, AtRuleParser};
--- a/third_party/rust/cssparser/src/parser.rs
+++ b/third_party/rust/cssparser/src/parser.rs
@@ -1,13 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use cow_rc_str::CowRcStr;
+use smallvec::SmallVec;
 use std::ops::Range;
 use std::ascii::AsciiExt;
 use std::ops::BitOr;
 use tokenizer::{Token, Tokenizer, SourcePosition, SourceLocation};
 
 
 /// A capture of the internal state of a `Parser` (including the position within the input),
 /// obtained from the `Parser::position` method.
@@ -96,16 +97,25 @@ impl<'i> ParserInput<'i> {
     /// Create a new input for a parser.
     pub fn new(input: &'i str) -> ParserInput<'i> {
         ParserInput {
             tokenizer: Tokenizer::new(input),
             cached_token: None,
         }
     }
 
+    /// Create a new input for a parser.  Line numbers in locations
+    /// are offset by the given value.
+    pub fn new_with_line_number_offset(input: &'i str, first_line_number: u32) -> ParserInput<'i> {
+        ParserInput {
+            tokenizer: Tokenizer::with_first_line_number(input, first_line_number),
+            cached_token: None,
+        }
+    }
+
     #[inline]
     fn cached_token_ref(&self) -> &Token<'i> {
         &self.cached_token.as_ref().unwrap().token
     }
 }
 
 /// A CSS parser that borrows its `&str` input,
 /// yields `Token`s,
@@ -283,16 +293,44 @@ impl<'i: 't, 't> Parser<'i, 't> {
     #[inline]
     pub fn state(&self) -> ParserState {
         ParserState {
             at_start_of: self.at_start_of,
             .. self.input.tokenizer.state()
         }
     }
 
+    /// Advance the input until the next token that’s not whitespace or a comment.
+    #[inline]
+    pub fn skip_whitespace(&mut self) {
+        if let Some(block_type) = self.at_start_of.take() {
+            consume_until_end_of_block(block_type, &mut self.input.tokenizer);
+        }
+
+        self.input.tokenizer.skip_whitespace()
+    }
+
+    #[inline]
+    pub(crate) fn skip_cdc_and_cdo(&mut self) {
+        if let Some(block_type) = self.at_start_of.take() {
+            consume_until_end_of_block(block_type, &mut self.input.tokenizer);
+        }
+
+        self.input.tokenizer.skip_cdc_and_cdo()
+    }
+
+    #[inline]
+    pub(crate) fn next_byte(&self) -> Option<u8> {
+        let byte = self.input.tokenizer.next_byte();
+        if self.stop_before.contains(Delimiters::from_byte(byte)) {
+            return None
+        }
+        byte
+    }
+
     /// Restore the internal state of the parser (including position within the input)
     /// to what was previously saved by the `Parser::position` method.
     ///
     /// Should only be used with `SourcePosition` values from the same `Parser` instance.
     #[inline]
     pub fn reset(&mut self, state: &ParserState) {
         self.input.tokenizer.reset(state);
         self.at_start_of = state.at_start_of;
@@ -359,24 +397,18 @@ impl<'i: 't, 't> Parser<'i, 't> {
     /// `CurlyBracketBlock`, or `SquareBracketBlock` token,
     /// the next call will skip until after the matching `CloseParenthesis`,
     /// `CloseCurlyBracket`, or `CloseSquareBracket` token.
     ///
     /// See the `Parser::parse_nested_block` method to parse the content of functions or blocks.
     ///
     /// This only returns a closing token when it is unmatched (and therefore an error).
     pub fn next(&mut self) -> Result<&Token<'i>, BasicParseError<'i>> {
-        loop {
-            match self.next_including_whitespace_and_comments() {
-                Err(e) => return Err(e),
-                Ok(&Token::WhiteSpace(_)) | Ok(&Token::Comment(_)) => {},
-                _ => break
-            }
-        }
-        Ok(self.input.cached_token_ref())
+        self.skip_whitespace();
+        self.next_including_whitespace_and_comments()
     }
 
     /// Same as `Parser::next`, but does not skip whitespace tokens.
     pub fn next_including_whitespace(&mut self) -> Result<&Token<'i>, BasicParseError<'i>> {
         loop {
             match self.next_including_whitespace_and_comments() {
                 Err(e) => return Err(e),
                 Ok(&Token::Comment(_)) => {},
@@ -454,16 +486,17 @@ impl<'i: 't, 't> Parser<'i, 't> {
     ///
     /// This method retuns `Err(())` the first time that a closure call does,
     /// or if a closure call leaves some input before the next comma or the end of the input.
     #[inline]
     pub fn parse_comma_separated<F, T, E>(&mut self, mut parse_one: F) -> Result<Vec<T>, ParseError<'i, E>>
     where F: for<'tt> FnMut(&mut Parser<'i, 'tt>) -> Result<T, ParseError<'i, E>> {
         let mut values = vec![];
         loop {
+            self.skip_whitespace();  // Unnecessary for correctness, but may help try() in parse_one rewind less.
             values.push(self.parse_until_before(Delimiter::Comma, &mut parse_one)?);
             match self.next() {
                 Err(_) => return Ok(values),
                 Ok(&Token::Comma) => continue,
                 Ok(_) => unreachable!(),
             }
         }
     }
@@ -823,17 +856,18 @@ pub fn parse_nested_block<'i: 't, 't, F,
             consume_until_end_of_block(block_type, &mut nested_parser.input.tokenizer);
         }
     }
     consume_until_end_of_block(block_type, &mut parser.input.tokenizer);
     result
 }
 
 fn consume_until_end_of_block(block_type: BlockType, tokenizer: &mut Tokenizer) {
-    let mut stack = vec![block_type];
+    let mut stack = SmallVec::<[BlockType; 16]>::new();
+    stack.push(block_type);
 
     // FIXME: have a special-purpose tokenizer method for this that does less work.
     while let Ok(ref token) = tokenizer.next() {
         if let Some(b) = BlockType::closing(token) {
             if *stack.last().unwrap() == b {
                 stack.pop();
                 if stack.is_empty() {
                     return;
--- a/third_party/rust/cssparser/src/rules_and_declarations.rs
+++ b/third_party/rust/cssparser/src/rules_and_declarations.rs
@@ -337,37 +337,50 @@ where P: QualifiedRuleParser<'i, Qualifi
 /// `RuleListParser` is an iterator that yields `Ok(_)` for a rule or `Err(())` for an invalid one.
 impl<'i: 't, 't: 'a, 'a, R, P, E: 'i> Iterator for RuleListParser<'i, 't, 'a, P>
 where P: QualifiedRuleParser<'i, QualifiedRule = R, Error = E> +
          AtRuleParser<'i, AtRule = R, Error = E> {
     type Item = Result<R, PreciseParseError<'i, E>>;
 
     fn next(&mut self) -> Option<Result<R, PreciseParseError<'i, E>>> {
         loop {
+            if self.is_stylesheet {
+                self.input.skip_cdc_and_cdo()
+            } else {
+                self.input.skip_whitespace()
+            }
             let start = self.input.state();
-            // FIXME: remove intermediate variable when lifetimes are non-lexical
-            let at_keyword = match self.input.next_including_whitespace_and_comments() {
-                Ok(&Token::WhiteSpace(_)) | Ok(&Token::Comment(_)) => continue,
-                Ok(&Token::CDO) | Ok(&Token::CDC) if self.is_stylesheet => continue,
-                Ok(&Token::AtKeyword(ref name)) => Some(name.clone()),
-                Ok(_) => None,
-                Err(_) => return None,
-            };
+
+            let at_keyword;
+            match self.input.next_byte() {
+                Some(b'@') => {
+                    match self.input.next_including_whitespace_and_comments() {
+                        Ok(&Token::AtKeyword(ref name)) => at_keyword = Some(name.clone()),
+                        _ => at_keyword = None,
+                    }
+                    // FIXME: move this back inside `match` when lifetimes are non-lexical
+                    if at_keyword.is_none() {
+                        self.input.reset(&start)
+                    }
+                }
+                Some(_) => at_keyword = None,
+                None => return None
+            }
+
             if let Some(name) = at_keyword {
                 let first_stylesheet_rule = self.is_stylesheet && !self.any_rule_so_far;
                 self.any_rule_so_far = true;
                 if first_stylesheet_rule && name.eq_ignore_ascii_case("charset") {
                     let delimiters = Delimiter::Semicolon | Delimiter::CurlyBracketBlock;
                     let _: Result<(), ParseError<()>> = self.input.parse_until_after(delimiters, |_| Ok(()));
                 } else {
                     return Some(parse_at_rule(&start, name.clone(), self.input, &mut self.parser))
                 }
             } else {
                 self.any_rule_so_far = true;
-                self.input.reset(&start);
                 return Some(parse_qualified_rule(self.input, &mut self.parser)
                             .map_err(|e| PreciseParseError {
                                 error: e,
                                 slice: self.input.slice_from(start.position()),
                                 location: start.source_location(),
                             }))
             }
         }
@@ -395,30 +408,37 @@ pub fn parse_one_declaration<'i, 't, P, 
 
 
 /// Parse a single rule, such as for CSSOM’s `CSSStyleSheet.insertRule`.
 pub fn parse_one_rule<'i, 't, R, P, E>(input: &mut Parser<'i, 't>, parser: &mut P)
                                        -> Result<R, ParseError<'i, E>>
 where P: QualifiedRuleParser<'i, QualifiedRule = R, Error = E> +
          AtRuleParser<'i, AtRule = R, Error = E> {
     input.parse_entirely(|input| {
-        loop {
-            let start = input.state();
-            // FIXME: remove intermediate variable when lifetimes are non-lexical
-            let at_keyword = match *input.next_including_whitespace_and_comments()? {
-                Token::WhiteSpace(_) | Token::Comment(_) => continue,
-                Token::AtKeyword(ref name) => Some(name.clone()),
-                _ => None
-            };
-            if let Some(name) = at_keyword {
-                return parse_at_rule(&start, name, input, parser).map_err(|e| e.error)
-            } else {
-                input.reset(&start);
-                return parse_qualified_rule(input, parser)
+        input.skip_whitespace();
+        let start = input.state();
+
+        let at_keyword;
+        if input.next_byte() == Some(b'@') {
+            match *input.next_including_whitespace_and_comments()? {
+                Token::AtKeyword(ref name) => at_keyword = Some(name.clone()),
+                _ => at_keyword = None,
             }
+            // FIXME: move this back inside `match` when lifetimes are non-lexical
+            if at_keyword.is_none() {
+                input.reset(&start)
+            }
+        } else {
+            at_keyword = None
+        }
+
+        if let Some(name) = at_keyword {
+            parse_at_rule(&start, name, input, parser).map_err(|e| e.error)
+        } else {
+            parse_qualified_rule(input, parser)
         }
     })
 }
 
 /// A parse error with details of where it occured
 pub struct PreciseParseError<'i, E: 'i> {
     /// Error details
     pub error: ParseError<'i, E>,
--- a/third_party/rust/cssparser/src/tests.rs
+++ b/third_party/rust/cssparser/src/tests.rs
@@ -966,16 +966,39 @@ fn parser_maintains_current_line() {
     assert_eq!(parser.next(), Ok(&Token::Ident("ident".into())));
     assert_eq!(parser.next(), Ok(&Token::Semicolon));
 
     assert_eq!(parser.next(), Ok(&Token::Ident("ident".into())));
     assert_eq!(parser.current_line(), "ident");
 }
 
 #[test]
+fn parser_with_line_number_offset() {
+    let mut input = ParserInput::new_with_line_number_offset("ident\nident", 72);
+    let mut parser = Parser::new(&mut input);
+    assert_eq!(parser.current_source_location(), SourceLocation { line: 72, column: 0 });
+    assert_eq!(parser.next_including_whitespace_and_comments(), Ok(&Token::Ident("ident".into())));
+    assert_eq!(parser.current_source_location(), SourceLocation { line: 72, column: 5 });
+    assert_eq!(parser.next_including_whitespace_and_comments(),
+               Ok(&Token::WhiteSpace("\n".into())));
+    assert_eq!(parser.current_source_location(), SourceLocation { line: 73, column: 0 });
+    assert_eq!(parser.next_including_whitespace_and_comments(), Ok(&Token::Ident("ident".into())));
+    assert_eq!(parser.current_source_location(), SourceLocation { line: 73, column: 5 });
+}
+
+#[test]
+fn cdc_regression_test() {
+    let mut input = ParserInput::new("-->x");
+    let mut parser = Parser::new(&mut input);
+    parser.skip_cdc_and_cdo();
+    assert_eq!(parser.next(), Ok(&Token::Ident("x".into())));
+    assert_eq!(parser.next(), Err(BasicParseError::EndOfInput));
+}
+
+#[test]
 fn parse_entirely_reports_first_error() {
     #[derive(PartialEq, Debug)]
     enum E { Foo }
     let mut input = ParserInput::new("ident");
     let mut parser = Parser::new(&mut input);
     let result: Result<(), _> = parser.parse_entirely(|_| Err(ParseError::Custom(E::Foo)));
     assert_eq!(result, Err(ParseError::Custom(E::Foo)));
 }
--- a/third_party/rust/cssparser/src/tokenizer.rs
+++ b/third_party/rust/cssparser/src/tokenizer.rs
@@ -406,16 +406,86 @@ impl<'a> Tokenizer<'a> {
         self.position += c.len_utf8();
         c
     }
 
     #[inline]
     fn starts_with(&self, needle: &[u8]) -> bool {
         self.input.as_bytes()[self.position..].starts_with(needle)
     }
+
+    pub fn skip_whitespace(&mut self) {
+        while !self.is_eof() {
+            match_byte! { self.next_byte_unchecked(),
+                b' ' | b'\t' => {
+                    self.advance(1)
+                },
+                b'\n' | b'\x0C' => {
+                    self.advance(1);
+                    self.seen_newline(false);
+                },
+                b'\r' => {
+                    self.advance(1);
+                    self.seen_newline(true);
+                },
+                b'/' => {
+                    if self.starts_with(b"/*") {
+                        consume_comment(self);
+                    } else {
+                        return
+                    }
+                }
+                _ => {
+                    return
+                }
+            }
+        }
+    }
+
+    pub fn skip_cdc_and_cdo(&mut self) {
+        while !self.is_eof() {
+            match_byte! { self.next_byte_unchecked(),
+                b' ' | b'\t' => {
+                    self.advance(1)
+                },
+                b'\n' | b'\x0C' => {
+                    self.advance(1);
+                    self.seen_newline(false);
+                },
+                b'\r' => {
+                    self.advance(1);
+                    self.seen_newline(true);
+                },
+                b'/' => {
+                    if self.starts_with(b"/*") {
+                        consume_comment(self);
+                    } else {
+                        return
+                    }
+                }
+                b'<' => {
+                    if self.starts_with(b"<!--") {
+                        self.advance(4)
+                    } else {
+                        return
+                    }
+                }
+                b'-' => {
+                    if self.starts_with(b"-->") {
+                        self.advance(3)
+                    } else {
+                        return
+                    }
+                }
+                _ => {
+                    return
+                }
+            }
+        }
+    }
 }
 
 /// A position from the start of the input, counted in UTF-8 bytes.
 #[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)]
 pub struct SourcePosition(pub(crate) usize);
 
 
 /// The line and column number for a given position within the input.
@@ -509,19 +579,17 @@ fn next_token<'a>(tokenizer: &mut Tokeni
                 consume_numeric(tokenizer)
             } else {
                 tokenizer.advance(1);
                 Delim('.')
             }
         }
         b'/' => {
             if tokenizer.starts_with(b"/*") {
-                let contents = consume_comment(tokenizer);
-                check_for_source_map(tokenizer, contents);
-                Comment(contents)
+                Comment(consume_comment(tokenizer))
             } else {
                 tokenizer.advance(1);
                 Delim('/')
             }
         }
         b'0'...b'9' => { consume_numeric(tokenizer) },
         b':' => { tokenizer.advance(1); Colon },
         b';' => { tokenizer.advance(1); Semicolon },
@@ -622,33 +690,37 @@ fn consume_comment<'a>(tokenizer: &mut T
     let start_position = tokenizer.position();
     while !tokenizer.is_eof() {
         match_byte! { tokenizer.next_byte_unchecked(),
             b'*' => {
                 let end_position = tokenizer.position();
                 tokenizer.advance(1);
                 if tokenizer.next_byte() == Some(b'/') {
                     tokenizer.advance(1);
-                    return tokenizer.slice(start_position..end_position)
+                    let contents = tokenizer.slice(start_position..end_position);
+                    check_for_source_map(tokenizer, contents);
+                    return contents
                 }
             }
             b'\n' | b'\x0C' => {
                 tokenizer.advance(1);
                 tokenizer.seen_newline(false);
             }
             b'\r' => {
                 tokenizer.advance(1);
                 tokenizer.seen_newline(true);
             }
             _ => {
                 tokenizer.advance(1);
             }
         }
     }
-    tokenizer.slice_from(start_position)
+    let contents = tokenizer.slice_from(start_position);
+    check_for_source_map(tokenizer, contents);
+    contents
 }
 
 fn consume_string<'a>(tokenizer: &mut Tokenizer<'a>, single_quote: bool) -> Token<'a> {
     match consume_quoted_string(tokenizer, single_quote) {
         Ok(value) => QuotedString(value),
         Err(value) => BadString(value)
     }
 }
--- a/third_party/rust/parking_lot_core/.cargo-checksum.json
+++ b/third_party/rust/parking_lot_core/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"8ba636346d2228cb56ba5468f224fde5be21f90b903422ac462ca7b3cfbd1f97","src/lib.rs":"6649792fe4bef4cbac34090bc599a86dc58d4528a8bfba4fce6a56bee3537c46","src/parking_lot.rs":"f18ed052d295746d1495a2cfab5a7fd25947542764d294dd1df1f43b36e5361e","src/spinwait.rs":"682e5a3fc71d1d7a7d8da377d1d93415fa64b4f53809bd80bbf2942628e3a23d","src/stable.rs":"cc18c58404dc6017924d88fb9f4ed94e5320b8cb0a36985162b23130b8cd7480","src/thread_parker/generic.rs":"6e3c7ef287691673c5001362da8757ac30f47481c804397f1c313153971f1d61","src/thread_parker/linux.rs":"0a3c63a8cba192827edb55dd785ccab22229370ad2bc4b52e81cc25c1fb63696","src/thread_parker/unix.rs":"bb1102ff79ab9ef98ce0df55e74ba561b92e39db55bcf5260c3dc017129994f4","src/thread_parker/windows/keyed_event.rs":"ceea3746ae04f59f86a6ccddde651cbbf8a203eb53a9e83349dfb5159eca4d88","src/thread_parker/windows/mod.rs":"d0caa762effeba24a5d866be812d8b1e8e076394142cdde5ef873a1247e867d9","src/thread_parker/windows/waitaddress.rs":"7f280d3c60bc4290b5bf30bc9740322cc0723742cfce58dcfcbfe4058e32d3a0","src/util.rs":"2d07c0c010a857790ae2ed6a1215eeed8af76859e076797ea1ba8dec82169e84","src/word_lock.rs":"a3a33b4e13c79ff84cf049f47694f165c050baa179dac6262318ef05b8c9f8db"},"package":"56a19dcbb5d1e32b6cccb8a9aa1fc2a38418c8699652e735e2bf391a3dc0aa16"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"0fbc0225f4a4220fa4e6390f5fd889f1739ae67fd6144baf8698f601f65632e4","src/lib.rs":"76b3e0b8c7c5931e71f2f563ca629b3b1a668a195ea454104537e39c4a43d8da","src/parking_lot.rs":"b451509ab016630edb5d17aafd6b0de1011663e2fe6e1b8c71361fe6f877fc98","src/spinwait.rs":"682e5a3fc71d1d7a7d8da377d1d93415fa64b4f53809bd80bbf2942628e3a23d","src/stable.rs":"cc18c58404dc6017924d88fb9f4ed94e5320b8cb0a36985162b23130b8cd7480","src/thread_parker/generic.rs":"041c56505851c0f2f68f250cb74851a198ea15e86d0b4fc2f8065fd024b9dc7b","src/thread_parker/linux.rs":"0a3c63a8cba192827edb55dd785ccab22229370ad2bc4b52e81cc25c1fb63696","src/thread_parker/unix.rs":"64d18bf39ebe13e08a43d641ec3c9e66048663b4fd0bae1af555375cf735f7fd","src/thread_parker/windows/keyed_event.rs":"ceea3746ae04f59f86a6ccddde651cbbf8a203eb53a9e83349dfb5159eca4d88","src/thread_parker/windows/mod.rs":"d0caa762effeba24a5d866be812d8b1e8e076394142cdde5ef873a1247e867d9","src/thread_parker/windows/waitaddress.rs":"7f280d3c60bc4290b5bf30bc9740322cc0723742cfce58dcfcbfe4058e32d3a0","src/util.rs":"2d07c0c010a857790ae2ed6a1215eeed8af76859e076797ea1ba8dec82169e84","src/word_lock.rs":"c33355107175d58f16fc6814cbd7792d2b9d92deae8311baf4306542c35c9853"},"package":"a25dd36576d01cca115881dc920b1f0dd0037303ed8cfa0c5d0a4966151757f7"}
\ No newline at end of file
--- a/third_party/rust/parking_lot_core/Cargo.toml
+++ b/third_party/rust/parking_lot_core/Cargo.toml
@@ -1,23 +1,36 @@
+# 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 = "parking_lot_core"
-version = "0.2.1"
+version = "0.2.4"
 authors = ["Amanieu d'Antras <amanieu@gmail.com>"]
 description = "An advanced API for creating custom synchronization primitives."
 documentation = "https://amanieu.github.io/parking_lot/parking_lot_core/index.html"
+keywords = ["mutex", "condvar", "rwlock", "once", "thread"]
 license = "Apache-2.0/MIT"
 repository = "https://github.com/Amanieu/parking_lot"
-keywords = ["mutex", "condvar", "rwlock", "once", "thread"]
-
-[dependencies]
-smallvec = "0.3"
-rand = "0.3"
+[dependencies.rand]
+version = "0.3"
 
-[target.'cfg(unix)'.dependencies]
-libc = "0.2.15"
-
-[target.'cfg(windows)'.dependencies]
-winapi = "0.2"
-kernel32-sys = "0.2"
+[dependencies.smallvec]
+version = "0.4"
 
 [features]
 nightly = []
+[target."cfg(unix)".dependencies.libc]
+version = "0.2.15"
+[target."cfg(windows)".dependencies.winapi]
+version = "0.2"
+
+[target."cfg(windows)".dependencies.kernel32-sys]
+version = "0.2"
--- a/third_party/rust/parking_lot_core/src/lib.rs
+++ b/third_party/rust/parking_lot_core/src/lib.rs
@@ -32,17 +32,17 @@
 //! Building custom synchronization primitives is very simple since the parking
 //! lot takes care of all the hard parts for you. A simple example for a
 //! custom primitive would be to integrate a `Mutex` inside another data type.
 //! Since a mutex only requires 2 bits, it can share space with other data.
 //! For example, one could create an `ArcMutex` type that combines the atomic
 //! reference count and the two mutex bits in the same atomic word.
 
 #![warn(missing_docs)]
-#![cfg_attr(feature = "nightly", feature(const_fn))]
+#![cfg_attr(feature = "nightly", feature(const_fn, thread_local_state))]
 #![cfg_attr(all(feature = "nightly", target_os = "linux"), feature(integer_atomics))]
 #![cfg_attr(feature = "nightly", feature(asm))]
 
 extern crate smallvec;
 extern crate rand;
 
 #[cfg(unix)]
 extern crate libc;
--- a/third_party/rust/parking_lot_core/src/parking_lot.rs
+++ b/third_party/rust/parking_lot_core/src/parking_lot.rs
@@ -8,25 +8,27 @@
 #[cfg(feature = "nightly")]
 use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
 #[cfg(not(feature = "nightly"))]
 use stable::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
 use std::time::{Instant, Duration};
 use std::cell::{Cell, UnsafeCell};
 use std::ptr;
 use std::mem;
+use std::thread::LocalKey;
+#[cfg(not(feature = "nightly"))]
+use std::panic;
 use smallvec::SmallVec;
 use rand::{self, XorShiftRng, Rng};
 use thread_parker::ThreadParker;
 use word_lock::WordLock;
 use util::UncheckedOptionExt;
 
 static NUM_THREADS: AtomicUsize = ATOMIC_USIZE_INIT;
 static HASHTABLE: AtomicUsize = ATOMIC_USIZE_INIT;
-thread_local!(static THREAD_DATA: ThreadData = ThreadData::new());
 
 // Even with 3x more buckets than threads, the memory overhead per thread is
 // still only a few hundred bytes per thread.
 const LOAD_FACTOR: usize = 3;
 
 struct HashTable {
     // Hash buckets for the table
     entries: Box<[Bucket]>,
@@ -146,16 +148,41 @@ impl ThreadData {
             key: AtomicUsize::new(0),
             next_in_queue: Cell::new(ptr::null()),
             unpark_token: Cell::new(DEFAULT_UNPARK_TOKEN),
             park_token: Cell::new(DEFAULT_PARK_TOKEN),
         }
     }
 }
 
+// Returns a ThreadData structure for the current thread
+unsafe fn get_thread_data(local: &mut Option<ThreadData>) -> &ThreadData {
+    // Try to read from thread-local storage, but return None if the TLS has
+    // already been destroyed.
+    #[cfg(feature = "nightly")]
+    fn try_get_tls(key: &'static LocalKey<ThreadData>) -> Option<*const ThreadData> {
+        key.try_with(|x| x as *const ThreadData).ok()
+    }
+    #[cfg(not(feature = "nightly"))]
+    fn try_get_tls(key: &'static LocalKey<ThreadData>) -> Option<*const ThreadData> {
+        panic::catch_unwind(|| key.with(|x| x as *const ThreadData)).ok()
+    }
+
+    // Unlike word_lock::ThreadData, parking_lot::ThreadData is always expensive
+    // to construct. Try to use a thread-local version if possible.
+    thread_local!(static THREAD_DATA: ThreadData = ThreadData::new());
+    if let Some(tls) = try_get_tls(&THREAD_DATA) {
+        return &*tls;
+    }
+
+    // Otherwise just create a ThreadData on the stack
+    *local = Some(ThreadData::new());
+    local.as_ref().unwrap()
+}
+
 impl Drop for ThreadData {
     fn drop(&mut self) {
         NUM_THREADS.fetch_sub(1, Ordering::Relaxed);
     }
 }
 
 // Get a pointer to the latest hash table, creating one if it doesn't exist yet.
 unsafe fn get_hashtable() -> *const HashTable {
@@ -507,17 +534,18 @@ pub unsafe fn park<V, B, T>(key: usize,
 unsafe fn park_internal(key: usize,
                         validate: &mut FnMut() -> bool,
                         before_sleep: &mut FnMut(),
                         timed_out: &mut FnMut(usize, bool),
                         park_token: ParkToken,
                         timeout: Option<Instant>)
                         -> ParkResult {
     // Grab our thread data, this also ensures that the hash table exists
-    let thread_data = &*THREAD_DATA.with(|x| x as *const ThreadData);
+    let mut thread_data = None;
+    let thread_data = get_thread_data(&mut thread_data);
 
     // Lock the bucket for the given key
     let bucket = lock_bucket(key);
 
     // If the validation function fails, just return
     if !validate() {
         bucket.mutex.unlock();
         return ParkResult::Invalid;
--- a/third_party/rust/parking_lot_core/src/thread_parker/generic.rs
+++ b/third_party/rust/parking_lot_core/src/thread_parker/generic.rs
@@ -28,16 +28,20 @@ impl ThreadParker {
     // Prepares the parker. This should be called before adding it to the queue.
     pub unsafe fn prepare_park(&self) {
         self.should_park.set(true);
     }
 
     // Checks if the park timed out. This should be called while holding the
     // queue lock after park_until has returned false.
     pub unsafe fn timed_out(&self) -> bool {
+        // We need to grab the mutex here because another thread may be
+        // concurrently executing UnparkHandle::unpark, which is done without
+        // holding the queue lock.
+        let _lock = self.mutex.lock().unwrap();
         self.should_park.get()
     }
 
     // Parks the thread until it is unparked. This should be called after it has
     // been added to the queue, after unlocking the queue.
     pub unsafe fn park(&self) {
         let mut lock = self.mutex.lock().unwrap();
         while self.should_park.get() {
--- a/third_party/rust/parking_lot_core/src/thread_parker/unix.rs
+++ b/third_party/rust/parking_lot_core/src/thread_parker/unix.rs
@@ -53,17 +53,25 @@ impl ThreadParker {
             self.init();
             self.initialized.set(true);
         }
     }
 
     // Checks if the park timed out. This should be called while holding the
     // queue lock after park_until has returned false.
     pub unsafe fn timed_out(&self) -> bool {
-        self.should_park.get()
+        // We need to grab the mutex here because another thread may be
+        // concurrently executing UnparkHandle::unpark, which is done without
+        // holding the queue lock.
+        let r = libc::pthread_mutex_lock(self.mutex.get());
+        debug_assert_eq!(r, 0);
+        let should_park = self.should_park.get();
+        let r = libc::pthread_mutex_unlock(self.mutex.get());
+        debug_assert_eq!(r, 0);
+        should_park
     }
 
     // Parks the thread until it is unparked. This should be called after it has
     // been added to the queue, after unlocking the queue.
     pub unsafe fn park(&self) {
         let r = libc::pthread_mutex_lock(self.mutex.get());
         debug_assert_eq!(r, 0);
         while self.should_park.get() {
--- a/third_party/rust/parking_lot_core/src/word_lock.rs
+++ b/third_party/rust/parking_lot_core/src/word_lock.rs
@@ -7,16 +7,19 @@
 
 #[cfg(feature = "nightly")]
 use std::sync::atomic::{AtomicUsize, Ordering, fence};
 #[cfg(not(feature = "nightly"))]
 use stable::{AtomicUsize, Ordering, fence};
 use std::ptr;
 use std::mem;
 use std::cell::Cell;
+use std::thread::LocalKey;
+#[cfg(not(feature = "nightly"))]
+use std::panic;
 use spinwait::SpinWait;
 use thread_parker::ThreadParker;
 
 struct ThreadData {
     parker: ThreadParker,
 
     // Linked list of threads in the queue. The queue is split into two parts:
     // the processed part and the unprocessed part. When new nodes are added to
@@ -41,17 +44,42 @@ impl ThreadData {
             parker: ThreadParker::new(),
             queue_tail: Cell::new(ptr::null()),
             prev: Cell::new(ptr::null()),
             next: Cell::new(ptr::null()),
         }
     }
 }
 
-thread_local!(static THREAD_DATA: ThreadData = ThreadData::new());
+// Returns a ThreadData structure for the current thread
+unsafe fn get_thread_data(local: &mut Option<ThreadData>) -> &ThreadData {
+    // Try to read from thread-local storage, but return None if the TLS has
+    // already been destroyed.
+    #[cfg(feature = "nightly")]
+    fn try_get_tls(key: &'static LocalKey<ThreadData>) -> Option<*const ThreadData> {
+        key.try_with(|x| x as *const ThreadData).ok()
+    }
+    #[cfg(not(feature = "nightly"))]
+    fn try_get_tls(key: &'static LocalKey<ThreadData>) -> Option<*const ThreadData> {
+        panic::catch_unwind(|| key.with(|x| x as *const ThreadData)).ok()
+    }
+
+    // If ThreadData is expensive to construct, then we want to use a cached
+    // version in thread-local storage if possible.
+    if !cfg!(windows) && !cfg!(all(feature = "nightly", target_os = "linux")) {
+        thread_local!(static THREAD_DATA: ThreadData = ThreadData::new());
+        if let Some(tls) = try_get_tls(&THREAD_DATA) {
+            return &*tls;
+        }
+    }
+
+    // Otherwise just create a ThreadData on the stack
+    *local = Some(ThreadData::new());
+    local.as_ref().unwrap()
+}
 
 const LOCKED_BIT: usize = 1;
 const QUEUE_LOCKED_BIT: usize = 2;
 const QUEUE_MASK: usize = !3;
 
 // Word-sized lock that is used to implement the parking_lot API. Since this
 // can't use parking_lot, it instead manages its own queue of waiting threads.
 pub struct WordLock {
@@ -104,17 +132,18 @@ impl WordLock {
 
             // If there is no queue, try spinning a few times
             if state & QUEUE_MASK == 0 && spinwait.spin() {
                 state = self.state.load(Ordering::Relaxed);
                 continue;
             }
 
             // Get our thread data and prepare it for parking
-            let thread_data = &*THREAD_DATA.with(|x| x as *const ThreadData);
+            let mut thread_data = None;
+            let thread_data = get_thread_data(&mut thread_data);
             assert!(mem::align_of_val(thread_data) > !QUEUE_MASK);
             thread_data.parker.prepare_park();
 
             // Add our thread to the front of the queue
             let queue_head = (state & QUEUE_MASK) as *const ThreadData;
             if queue_head.is_null() {
                 thread_data.queue_tail.set(thread_data);
                 thread_data.prev.set(ptr::null());
deleted file mode 100644
--- a/third_party/rust/smallvec-0.3.3/.cargo-checksum.json
+++ /dev/null
@@ -1,1 +0,0 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".travis.yml":"8d8372a5e10c6d301d70d45da3d51a4b8cbd6d51b57a62e7730942adc69da200","Cargo.toml":"48402d1ef9c6e0015e98104e1b9ec5c406a2e5ca5d8f8b0382a1ed4decdf96f8","README.md":"85c6105e404b1febba9e06773350cc81fe5966369530210669b3465c66237a09","benches/bench.rs":"54cf4879d36ba2a9f3423af91bb93227b70849200e5bf74e384a166d6aa09893","lib.rs":"acdf2c4778adb0b613efb08ff4612d8d7fb2d67747da026ab3894539e7f3e3ed"},"package":"4f8266519bc1d17d0b5b16f6c21295625d562841c708f6376f49028a43e9c11e"}
\ No newline at end of file
deleted file mode 100644
deleted file mode 100644
--- a/third_party/rust/smallvec-0.3.3/.travis.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-language: rust
-rust:
-  - nightly
-  - beta
-  - stable
-script: |
-  cargo build --verbose &&
-  cargo build --features=heapsizeof --verbose &&
-  cargo test --verbose &&
-  cargo test --features=heapsizeof --verbose &&
-  ([ $TRAVIS_RUST_VERSION != nightly ] || cargo bench --verbose bench)
-notifications:
-  webhooks: http://build.servo.org:54856/travis
deleted file mode 100644
--- a/third_party/rust/smallvec-0.3.3/Cargo.toml
+++ /dev/null
@@ -1,20 +0,0 @@
-[package]
-name = "smallvec"
-version = "0.3.3"
-authors = ["Simon Sapin <simon.sapin@exyr.org>"]
-license = "MPL-2.0"
-repository = "https://github.com/servo/rust-smallvec"
-description = "'Small vector' optimization: store up to a small number of items on the stack"
-keywords = ["small", "vec", "vector", "stack"]
-readme = "README.md"
-documentation = "http://doc.servo.org/smallvec/"
-
-[features]
-heapsizeof = ["heapsize"]
-
-[lib]
-name = "smallvec"
-path = "lib.rs"
-
-[dependencies]
-heapsize = { version = "0.3", optional = true }
deleted file mode 100644
--- a/third_party/rust/smallvec-0.3.3/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-rust-smallvec
-=============
-
-[Documentation](http://doc.servo.org/smallvec/)
-
-"Small vector" optimization for Rust: store up to a small number of items on the stack
deleted file mode 100644
--- a/third_party/rust/smallvec-0.3.3/benches/bench.rs
+++ /dev/null
@@ -1,111 +0,0 @@
-#![feature(test)]
-
-extern crate smallvec;
-extern crate test;
-
-use smallvec::SmallVec;
-use self::test::Bencher;
-
-#[bench]
-fn bench_push(b: &mut Bencher) {
-    #[inline(never)]
-    fn push_noinline(vec: &mut SmallVec<[u64; 16]>, x: u64) {
-        vec.push(x)
-    }
-
-    b.iter(|| {
-        let mut vec: SmallVec<[u64; 16]> = SmallVec::new();
-        for x in 0..100 {
-            push_noinline(&mut vec, x);
-        }
-        vec
-    });
-}
-
-#[bench]
-fn bench_insert(b: &mut Bencher) {
-    #[inline(never)]
-    fn insert_noinline(vec: &mut SmallVec<[u64; 16]>, x: u64) {
-        vec.insert(0, x)
-    }
-
-    b.iter(|| {
-        let mut vec: SmallVec<[u64; 16]> = SmallVec::new();
-        for x in 0..100 {
-            insert_noinline(&mut vec, x);
-        }
-        vec
-    });
-}
-
-#[bench]
-fn bench_insert_many(b: &mut Bencher) {
-    #[inline(never)]
-    fn insert_many_noinline<I: IntoIterator<Item=u64>>(
-        vec: &mut SmallVec<[u64; 16]>, index: usize, iterable: I) {
-        vec.insert_many(index, iterable)
-    }
-
-    b.iter(|| {
-        let mut vec: SmallVec<[u64; 16]> = SmallVec::new();
-        insert_many_noinline(&mut vec, 0, 0..100);
-        insert_many_noinline(&mut vec, 0, 0..100);
-        vec
-    });
-}
-
-#[bench]
-fn bench_extend(b: &mut Bencher) {
-    b.iter(|| {
-        let mut vec: SmallVec<[u64; 16]> = SmallVec::new();
-        vec.extend(0..100);
-        vec
-    });
-}
-
-#[bench]
-fn bench_from_slice(b: &mut Bencher) {
-    let v: Vec<u64> = (0..100).collect();
-    b.iter(|| {
-        let vec: SmallVec<[u64; 16]> = SmallVec::from_slice(&v);
-        vec
-    });
-}
-
-#[bench]
-fn bench_extend_from_slice(b: &mut Bencher) {
-    let v: Vec<u64> = (0..100).collect();
-    b.iter(|| {
-        let mut vec: SmallVec<[u64; 16]> = SmallVec::new();
-        vec.extend_from_slice(&v);
-        vec
-    });
-}
-
-#[bench]
-fn bench_insert_from_slice(b: &mut Bencher) {
-    let v: Vec<u64> = (0..100).collect();
-    b.iter(|| {
-        let mut vec: SmallVec<[u64; 16]> = SmallVec::new();
-        vec.insert_from_slice(0, &v);
-        vec.insert_from_slice(0, &v);
-        vec
-    });
-}
-
-#[bench]
-fn bench_pushpop(b: &mut Bencher) {
-    #[inline(never)]
-    fn pushpop_noinline(vec: &mut SmallVec<[u64; 16]>, x: u64) {
-        vec.push(x);
-        vec.pop();
-    }
-
-    b.iter(|| {
-        let mut vec: SmallVec<[u64; 16]> = SmallVec::new();
-        for x in 0..100 {
-            pushpop_noinline(&mut vec, x);
-        }
-        vec
-    });
-}
deleted file mode 100644
--- a/third_party/rust/smallvec-0.3.3/lib.rs
+++ /dev/null
@@ -1,1424 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//! Small vectors in various sizes. These store a certain number of elements inline, and fall back
-//! to the heap for larger allocations.  This can be a useful optimization for improving cache
-//! locality and reducing allocator traffic for workloads that fit within the inline buffer.
-
-#[cfg(feature="heapsizeof")]
-extern crate heapsize;
-
-use std::borrow::{Borrow, BorrowMut};
-use std::cmp;
-use std::fmt;
-use std::hash::{Hash, Hasher};
-use std::iter::{IntoIterator, FromIterator};
-use std::mem;
-use std::ops;
-use std::ptr;
-use std::slice;
-#[cfg(feature="heapsizeof")]
-use std::os::raw::c_void;
-
-#[cfg(feature="heapsizeof")]
-use heapsize::{HeapSizeOf, heap_size_of};
-use SmallVecData::{Inline, Heap};
-
-/// Common operations implemented by both `Vec` and `SmallVec`.
-///
-/// This can be used to write generic code that works with both `Vec` and `SmallVec`.
-///
-/// ## Example
-///
-/// ```rust
-/// use smallvec::{VecLike, SmallVec8};
-///
-/// fn initialize<V: VecLike<u8>>(v: &mut V) {
-///     for i in 0..5 {
-///         v.push(i);
-///     }
-/// }
-///
-/// let mut vec = Vec::new();
-/// initialize(&mut vec);
-///
-/// let mut small_vec = SmallVec8::new();
-/// initialize(&mut small_vec);
-/// ```
-pub trait VecLike<T>:
-        ops::Index<usize, Output=T> +
-        ops::IndexMut<usize> +
-        ops::Index<ops::Range<usize>, Output=[T]> +
-        ops::IndexMut<ops::Range<usize>> +
-        ops::Index<ops::RangeFrom<usize>, Output=[T]> +
-        ops::IndexMut<ops::RangeFrom<usize>> +
-        ops::Index<ops::RangeTo<usize>, Output=[T]> +
-        ops::IndexMut<ops::RangeTo<usize>> +
-        ops::Index<ops::RangeFull, Output=[T]> +
-        ops::IndexMut<ops::RangeFull> +
-        ops::DerefMut<Target = [T]> +
-        Extend<T> {
-
-    /// Append an element to the vector.
-    fn push(&mut self, value: T);
-}
-
-impl<T> VecLike<T> for Vec<T> {
-    #[inline]
-    fn push(&mut self, value: T) {
-        Vec::push(self, value);
-    }
-}
-
-unsafe fn deallocate<T>(ptr: *mut T, capacity: usize) {
-    let _vec: Vec<T> = Vec::from_raw_parts(ptr, 0, capacity);
-    // Let it drop.
-}
-
-pub struct Drain<'a, T: 'a> {
-    iter: slice::IterMut<'a,T>,
-}
-
-impl<'a, T: 'a> Iterator for Drain<'a,T> {
-    type Item = T;
-
-    #[inline]
-    fn next(&mut self) -> Option<T> {
-        match self.iter.next() {
-            None => None,
-            Some(reference) => {
-                unsafe {
-                    Some(ptr::read(reference))
-                }
-            }
-        }
-    }
-
-    #[inline]
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        self.iter.size_hint()
-    }
-}
-
-impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> {
-    #[inline]
-    fn next_back(&mut self) -> Option<T> {
-        match self.iter.next_back() {
-            None => None,
-            Some(reference) => {
-                unsafe {
-                    Some(ptr::read(reference))
-                }
-            }
-        }
-    }
-}
-
-impl<'a, T> ExactSizeIterator for Drain<'a, T> { }
-
-impl<'a, T: 'a> Drop for Drain<'a,T> {
-    fn drop(&mut self) {
-        // Destroy the remaining elements.
-        for _ in self.by_ref() {}
-    }
-}
-
-enum SmallVecData<A: Array> {
-    Inline { array: A },
-    Heap { ptr: *mut A::Item, capacity: usize },
-}
-
-impl<A: Array> SmallVecData<A> {
-    fn ptr_mut(&mut self) -> *mut A::Item {
-        match *self {
-            Inline { ref mut array } => array.ptr_mut(),
-            Heap { ptr, .. } => ptr,
-        }
-    }
-}
-
-unsafe impl<A: Array + Send> Send for SmallVecData<A> {}
-unsafe impl<A: Array + Sync> Sync for SmallVecData<A> {}
-
-impl<A: Array> Drop for SmallVecData<A> {
-    fn drop(&mut self) {
-        unsafe {
-            match *self {
-                ref mut inline @ Inline { .. } => {
-                    // Inhibit the array destructor.
-                    ptr::write(inline, Heap {
-                        ptr: ptr::null_mut(),
-                        capacity: 0,
-                    });
-                }
-                Heap { ptr, capacity } => deallocate(ptr, capacity),
-            }
-        }
-    }
-}
-
-/// A `Vec`-like container that can store a small number of elements inline.
-///
-/// `SmallVec` acts like a vector, but can store a limited amount of data inline within the
-/// `Smallvec` struct rather than in a separate allocation.  If the data exceeds this limit, the
-/// `SmallVec` will "spill" its data onto the heap, allocating a new buffer to hold it.
-///
-/// The amount of data that a `SmallVec` can store inline depends on its backing store. The backing
-/// store can be any type that implements the `Array` trait; usually it is a small fixed-sized
-/// array.  For example a `SmallVec<[u64; 8]>` can hold up to eight 64-bit integers inline.
-///
-/// Type aliases like `SmallVec8<T>` are provided as convenient shorthand for types like
-/// `SmallVec<[T; 8]>`.
-///
-/// ## Example
-///
-/// ```rust
-/// use smallvec::SmallVec;
-/// let mut v = SmallVec::<[u8; 4]>::new(); // initialize an empty vector
-///
-/// use smallvec::SmallVec4;
-/// let mut v: SmallVec4<u8> = SmallVec::new(); // alternate way to write the above
-///
-/// // SmallVec4 can hold up to 4 items without spilling onto the heap.
-/// v.extend(0..4);
-/// assert_eq!(v.len(), 4);
-/// assert!(!v.spilled());
-///
-/// // Pushing another element will force the buffer to spill:
-/// v.push(4);
-/// assert_eq!(v.len(), 5);
-/// assert!(v.spilled());
-/// ```
-pub struct SmallVec<A: Array> {
-    len: usize,
-    data: SmallVecData<A>,
-}
-
-impl<A: Array> SmallVec<A> {
-    /// Construct an empty vector
-    #[inline]
-    pub fn new() -> SmallVec<A> {
-        unsafe {
-            SmallVec {
-                len: 0,
-                data: Inline { array: mem::uninitialized() },
-            }
-        }
-    }
-
-    /// Construct a new `SmallVec` from a `Vec<A::Item>` without copying
-    /// elements.
-    ///
-    /// ```rust
-    /// use smallvec::SmallVec;
-    ///
-    /// let vec = vec![1, 2, 3, 4, 5];
-    /// let small_vec: SmallVec<[_; 3]> = SmallVec::from_vec(vec);
-    ///
-    /// assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
-    /// ```
-    #[inline]
-    pub fn from_vec(mut vec: Vec<A::Item>) -> SmallVec<A> {
-        let (ptr, cap, len) = (vec.as_mut_ptr(), vec.capacity(), vec.len());
-        mem::forget(vec);
-
-        SmallVec {
-            len: len,
-            data: SmallVecData::Heap {
-                ptr: ptr,
-                capacity: cap
-            }
-        }
-    }
-
-    /// Sets the length of a vector.
-    ///
-    /// This will explicitly set the size of the vector, without actually
-    /// modifying its buffers, so it is up to the caller to ensure that the
-    /// vector is actually the specified size.
-    pub unsafe fn set_len(&mut self, new_len: usize) {
-        self.len = new_len
-    }
-
-    /// The maximum number of elements this vector can hold inline
-    #[inline]
-    pub fn inline_size(&self) -> usize {
-        A::size()
-    }
-
-    /// The number of elements stored in the vector
-    #[inline]
-    pub fn len(&self) -> usize {
-        self.len
-    }
-
-    /// Returns `true` if the vector is empty
-    #[inline]
-    pub fn is_empty(&self) -> bool {
-        self.len == 0
-    }
-
-    /// The number of items the vector can hold without reallocating
-    #[inline]
-    pub fn capacity(&self) -> usize {
-        match self.data {
-            Inline { .. } => A::size(),
-            Heap { capacity, .. } => capacity,
-        }
-    }
-
-    /// Returns `true` if the data has spilled into a separate heap-allocated buffer.
-    #[inline]
-    pub fn spilled(&self) -> bool {
-        match self.data {
-            Inline { .. } => false,
-            Heap { .. } => true,
-        }
-    }
-
-    /// Empty the vector and return an iterator over its former contents.
-    pub fn drain(&mut self) -> Drain<A::Item> {
-        unsafe {
-            let current_len = self.len();
-            self.set_len(0);
-
-            let ptr = self.data.ptr_mut();
-
-            let slice = slice::from_raw_parts_mut(ptr, current_len);
-
-            Drain {
-                iter: slice.iter_mut(),
-            }
-        }
-    }
-
-    /// Append an item to the vector.
-    #[inline]
-    pub fn push(&mut self, value: A::Item) {
-        let cap = self.capacity();
-        if self.len == cap {
-            self.grow(cmp::max(cap * 2, 1))
-        }
-        unsafe {
-            let end = self.as_mut_ptr().offset(self.len as isize);
-            ptr::write(end, value);
-            let len = self.len;
-            self.set_len(len + 1)
-        }
-    }
-
-    /// Append elements from an iterator.
-    ///
-    /// This function is deprecated; it has been replaced by `Extend::extend`.
-    #[deprecated(note = "Use `extend` instead")]
-    pub fn push_all_move<V: IntoIterator<Item=A::Item>>(&mut self, other: V) {
-        self.extend(other)
-    }
-
-    /// Remove an item from the end of the vector and return it, or None if empty.
-    #[inline]
-    pub fn pop(&mut self) -> Option<A::Item> {
-        if self.len == 0 {
-            return None
-        }
-        let last_index = self.len - 1;
-        if (last_index as isize) < 0 {
-            panic!("overflow")
-        }
-        unsafe {
-            let end_ptr = self.as_mut_ptr().offset(last_index as isize);
-            let value = ptr::replace(end_ptr, mem::uninitialized());
-            self.set_len(last_index);
-            Some(value)
-        }
-    }
-
-    /// Re-allocate to set the capacity to `new_cap`.
-    ///
-    /// Panics if `new_cap` is less than the vector's length.
-    pub fn grow(&mut self, new_cap: usize) {
-        assert!(new_cap >= self.len);
-        let mut vec: Vec<A::Item> = Vec::with_capacity(new_cap);
-        let new_alloc = vec.as_mut_ptr();
-        unsafe {
-            mem::forget(vec);
-            ptr::copy_nonoverlapping(self.as_ptr(), new_alloc, self.len);
-
-            match self.data {
-                Inline { .. } => {}
-                Heap { ptr, capacity } => deallocate(ptr, capacity),
-            }
-            ptr::write(&mut self.data, Heap {
-                ptr: new_alloc,
-                capacity: new_cap,
-            });
-        }
-    }
-
-    /// Reserve capacity for `additional` more elements to be inserted.
-    ///
-    /// May reserve more space to avoid frequent reallocations.
-    ///
-    /// If the new capacity would overflow `usize` then it will be set to `usize::max_value()`
-    /// instead. (This means that inserting `additional` new elements is not guaranteed to be
-    /// possible after calling this function.)
-    pub fn reserve(&mut self, additional: usize) {
-        let len = self.len();
-        if self.capacity() - len < additional {
-            match len.checked_add(additional).and_then(usize::checked_next_power_of_two) {
-                Some(cap) => self.grow(cap),
-                None => self.grow(usize::max_value()),
-            }
-        }
-    }
-
-    /// Reserve the minumum capacity for `additional` more elements to be inserted.
-    ///
-    /// Panics if the new capacity overflows `usize`.
-    pub fn reserve_exact(&mut self, additional: usize) {
-        let len = self.len();
-        if self.capacity() - len < additional {
-            match len.checked_add(additional) {
-                Some(cap) => self.grow(cap),
-                None => panic!("reserve_exact overflow"),
-            }
-        }
-    }
-
-    /// Shrink the capacity of the vector as much as possible.
-    ///
-    /// When possible, this will move data from an external heap buffer to the vector's inline
-    /// storage.
-    pub fn shrink_to_fit(&mut self) {
-        let len = self.len;
-        if self.inline_size() >= len {
-            unsafe {
-                let (ptr, capacity) = match self.data {
-                    Inline { .. } => return,
-                    Heap { ptr, capacity } => (ptr, capacity),
-                };
-                ptr::write(&mut self.data, Inline { array: mem::uninitialized() });
-                ptr::copy_nonoverlapping(ptr, self.as_mut_ptr(), len);
-                deallocate(ptr, capacity);
-            }
-        } else if self.capacity() > len {
-            self.grow(len);
-        }
-    }
-
-    /// Shorten the vector, keeping the first `len` elements and dropping the rest.
-    ///
-    /// If `len` is greater than or equal to the vector's current length, this has no
-    /// effect.
-    ///
-    /// This does not re-allocate.  If you want the vector's capacity to shrink, call
-    /// `shrink_to_fit` after truncating.
-    pub fn truncate(&mut self, len: usize) {
-        let end_ptr = self.as_ptr();
-        while len < self.len {
-            unsafe {
-                let last_index = self.len - 1;
-                self.set_len(last_index);
-                ptr::read(end_ptr.offset(last_index as isize));
-            }
-        }
-    }
-
-    /// Remove the element at position `index`, replacing it with the last element.
-    ///
-    /// This does not preserve ordering, but is O(1).
-    ///
-    /// Panics if `index` is out of bounds.
-    #[inline]
-    pub fn swap_remove(&mut self, index: usize) -> A::Item {
-        let len = self.len;
-        self.swap(len - 1, index);
-        self.pop().unwrap()
-    }
-
-    /// Remove all elements from the vector.
-    #[inline]
-    pub fn clear(&mut self) {
-        self.truncate(0);
-    }
-
-    /// Remove and return the element at position `index`, shifting all elements after it to the
-    /// left.
-    ///
-    /// Panics if `index` is out of bounds.
-    pub fn remove(&mut self, index: usize) -> A::Item {
-        let len = self.len();
-
-        assert!(index < len);
-
-        unsafe {
-            let ptr = self.as_mut_ptr().offset(index as isize);
-            let item = ptr::read(ptr);
-            ptr::copy(ptr.offset(1), ptr, len - index - 1);
-            self.set_len(len - 1);
-            item
-        }
-    }
-
-    /// Insert an element at position `index`, shifting all elements after it to the right.
-    ///
-    /// Panics if `index` is out of bounds.
-    pub fn insert(&mut self, index: usize, element: A::Item) {
-        self.reserve(1);
-
-        let len = self.len;
-        assert!(index <= len);
-
-        unsafe {
-            let ptr = self.as_mut_ptr().offset(index as isize);
-            ptr::copy(ptr, ptr.offset(1), len - index);
-            ptr::write(ptr, element);
-            self.set_len(len + 1);
-        }
-    }
-
-    pub fn insert_many<I: IntoIterator<Item=A::Item>>(&mut self, index: usize, iterable: I) {
-        let iter = iterable.into_iter();
-        let (lower_size_bound, _) = iter.size_hint();
-        assert!(lower_size_bound <= std::isize::MAX as usize);  // Ensure offset is indexable
-        assert!(index + lower_size_bound >= index);  // Protect against overflow
-        self.reserve(lower_size_bound);
-
-        unsafe {
-            let old_len = self.len;
-            assert!(index <= old_len);
-            let ptr = self.as_mut_ptr().offset(index as isize);
-            ptr::copy(ptr, ptr.offset(lower_size_bound as isize), old_len - index);
-            for (off, element) in iter.enumerate() {
-                if off < lower_size_bound {
-                    ptr::write(ptr.offset(off as isize), element);
-                    self.len = self.len + 1;
-                } else {
-                    // Iterator provided more elements than the hint.
-                    assert!(index + off >= index);  // Protect against overflow.
-                    self.insert(index + off, element);
-                }
-            }
-            let num_added = self.len - old_len;
-            if num_added < lower_size_bound {
-                // Iterator provided fewer elements than the hint
-                ptr::copy(ptr.offset(lower_size_bound as isize), ptr.offset(num_added as isize), old_len - index);
-            }
-        }
-    }
-
-    /// Convert a SmallVec to a Vec, without reallocating if the SmallVec has already spilled onto
-    /// the heap.
-    pub fn into_vec(self) -> Vec<A::Item> {
-        match self.data {
-            Inline { .. } => self.into_iter().collect(),
-            Heap { ptr, capacity } => unsafe {
-                let v = Vec::from_raw_parts(ptr, self.len, capacity);
-                mem::forget(self);
-                v
-            }
-        }
-    }
-}
-
-impl<A: Array> SmallVec<A> where A::Item: Copy {
-    pub fn from_slice(slice: &[A::Item]) -> Self {
-        let mut vec = Self::new();
-        vec.extend_from_slice(slice);
-        vec
-    }
-
-    pub fn insert_from_slice(&mut self, index: usize, slice: &[A::Item]) {
-        self.reserve(slice.len());
-
-        let len = self.len;
-        assert!(index <= len);
-
-        unsafe {
-            let slice_ptr = slice.as_ptr();
-            let ptr = self.as_mut_ptr().offset(index as isize);
-            ptr::copy(ptr, ptr.offset(slice.len() as isize), len - index);
-            ptr::copy(slice_ptr, ptr, slice.len());
-            self.set_len(len + slice.len());
-        }
-    }
-
-    #[inline]
-    pub fn extend_from_slice(&mut self, slice: &[A::Item]) {
-        let len = self.len();
-        self.insert_from_slice(len, slice);
-    }
-}
-
-#[cfg(feature="heapsizeof")]
-impl<A: Array> HeapSizeOf for SmallVec<A> where A::Item: HeapSizeOf {
-    fn heap_size_of_children(&self) -> usize {
-        match self.data {
-            Inline { .. } => 0,
-            Heap { ptr, .. } => {
-                self.iter().fold(
-                    unsafe { heap_size_of(ptr as *const c_void) },
-                    |n, elem| n + elem.heap_size_of_children())
-            },
-        }
-    }
-}
-
-impl<A: Array> ops::Deref for SmallVec<A> {
-    type Target = [A::Item];
-    #[inline]
-    fn deref(&self) -> &[A::Item] {
-        let ptr: *const _ = match self.data {
-            Inline { ref array } => array.ptr(),
-            Heap { ptr, .. } => ptr,
-        };
-        unsafe {
-            slice::from_raw_parts(ptr, self.len)
-        }
-    }
-}
-
-impl<A: Array> ops::DerefMut for SmallVec<A> {
-    #[inline]
-    fn deref_mut(&mut self) -> &mut [A::Item] {
-        let ptr = self.data.ptr_mut();
-        unsafe {
-            slice::from_raw_parts_mut(ptr, self.len)
-        }
-    }
-}
-
-impl<A: Array> AsRef<[A::Item]> for SmallVec<A> {
-    #[inline]
-    fn as_ref(&self) -> &[A::Item] {
-        self
-    }
-}
-
-impl<A: Array> AsMut<[A::Item]> for SmallVec<A> {
-    #[inline]
-    fn as_mut(&mut self) -> &mut [A::Item] {
-        self
-    }
-}
-
-impl<A: Array> Borrow<[A::Item]> for SmallVec<A> {
-    #[inline]
-    fn borrow(&self) -> &[A::Item] {
-        self
-    }
-}
-
-impl<A: Array> BorrowMut<[A::Item]> for SmallVec<A> {
-    #[inline]
-    fn borrow_mut(&mut self) -> &mut [A::Item] {
-        self
-    }
-}
-
-impl<'a, A: Array> From<&'a [A::Item]> for SmallVec<A> where A::Item: Clone {
-    #[inline]
-    fn from(slice: &'a [A::Item]) -> SmallVec<A> {
-        slice.into_iter().cloned().collect()
-    }
-}
-
-macro_rules! impl_index {
-    ($index_type: ty, $output_type: ty) => {
-        impl<A: Array> ops::Index<$index_type> for SmallVec<A> {
-            type Output = $output_type;
-            #[inline]
-            fn index(&self, index: $index_type) -> &$output_type {
-                &(&**self)[index]
-            }
-        }
-
-        impl<A: Array> ops::IndexMut<$index_type> for SmallVec<A> {
-            #[inline]
-            fn index_mut(&mut self, index: $index_type) -> &mut $output_type {
-                &mut (&mut **self)[index]
-            }
-        }
-    }
-}
-
-impl_index!(usize, A::Item);
-impl_index!(ops::Range<usize>, [A::Item]);
-impl_index!(ops::RangeFrom<usize>, [A::Item]);
-impl_index!(ops::RangeTo<usize>, [A::Item]);
-impl_index!(ops::RangeFull, [A::Item]);
-
-
-impl<A: Array> VecLike<A::Item> for SmallVec<A> {
-    #[inline]
-    fn push(&mut self, value: A::Item) {
-        SmallVec::push(self, value);
-    }
-}
-
-impl<A: Array> FromIterator<A::Item> for SmallVec<A> {
-    fn from_iter<I: IntoIterator<Item=A::Item>>(iterable: I) -> SmallVec<A> {
-        let mut v = SmallVec::new();
-        v.extend(iterable);
-        v
-    }
-}
-
-impl<A: Array> Extend<A::Item> for SmallVec<A> {
-    fn extend<I: IntoIterator<Item=A::Item>>(&mut self, iterable: I) {
-        let iter = iterable.into_iter();
-        let (lower_size_bound, _) = iter.size_hint();
-
-        let target_len = self.len + lower_size_bound;
-
-        if target_len > self.capacity() {
-           self.grow(target_len);
-        }
-
-        for elem in iter {
-            self.push(elem);
-        }
-    }
-}
-
-impl<A: Array> fmt::Debug for SmallVec<A> where A::Item: fmt::Debug {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{:?}", &**self)
-    }
-}
-
-impl<A: Array> Default for SmallVec<A> {
-    #[inline]
-    fn default() -> SmallVec<A> {
-        SmallVec::new()
-    }
-}
-
-impl<A: Array> Drop for SmallVec<A> {
-    fn drop(&mut self) {
-        // Note on panic safety: dropping an element may panic,
-        // but the inner SmallVecData destructor will still run
-        unsafe {
-            let ptr = self.as_ptr();
-            for i in 0 .. self.len {
-                ptr::read(ptr.offset(i as isize));
-            }
-        }
-    }
-}
-
-impl<A: Array> Clone for SmallVec<A> where A::Item: Clone {
-    fn clone(&self) -> SmallVec<A> {
-        let mut new_vector = SmallVec::new();
-        for element in self.iter() {
-            new_vector.push((*element).clone())
-        }
-        new_vector
-    }
-}
-
-impl<A: Array, B: Array> PartialEq<SmallVec<B>> for SmallVec<A>
-    where A::Item: PartialEq<B::Item> {
-    #[inline]
-    fn eq(&self, other: &SmallVec<B>) -> bool { self[..] == other[..] }
-    #[inline]
-    fn ne(&self, other: &SmallVec<B>) -> bool { self[..] != other[..] }
-}
-
-impl<A: Array> Eq for SmallVec<A> where A::Item: Eq {}
-
-impl<A: Array> PartialOrd for SmallVec<A> where A::Item: PartialOrd {
-    #[inline]
-    fn partial_cmp(&self, other: &SmallVec<A>) -> Option<cmp::Ordering> {
-        PartialOrd::partial_cmp(&**self, &**other)
-    }
-}
-
-impl<A: Array> Ord for SmallVec<A> where A::Item: Ord {
-    #[inline]
-    fn cmp(&self, other: &SmallVec<A>) -> cmp::Ordering {
-        Ord::cmp(&**self, &**other)
-    }
-}
-
-impl<A: Array> Hash for SmallVec<A> where A::Item: Hash {
-    fn hash<H: Hasher>(&self, state: &mut H) {
-        (**self).hash(state)
-    }
-}
-
-unsafe impl<A: Array> Send for SmallVec<A> where A::Item: Send {}
-
-pub struct IntoIter<A: Array> {
-    data: SmallVecData<A>,
-    current: usize,
-    end: usize,
-}
-
-impl<A: Array> Drop for IntoIter<A> {
-    fn drop(&mut self) {
-        for _ in self { }
-    }
-}
-
-impl<A: Array> Iterator for IntoIter<A> {
-    type Item = A::Item;
-
-    #[inline]
-    fn next(&mut self) -> Option<A::Item> {
-        if self.current == self.end {
-            None
-        }
-        else {
-            unsafe {
-                let current = self.current as isize;
-                self.current += 1;
-                Some(ptr::read(self.data.ptr_mut().offset(current)))
-            }
-        }
-    }
-
-    #[inline]
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        let size = self.end - self.current;
-        (size, Some(size))
-    }
-}
-
-impl<A: Array> DoubleEndedIterator for IntoIter<A> {
-    #[inline]
-    fn next_back(&mut self) -> Option<A::Item> {
-        if self.current == self.end {
-            None
-        }
-        else {
-            unsafe {
-                self.end -= 1;
-                Some(ptr::read(self.data.ptr_mut().offset(self.end as isize)))
-            }
-        }
-    }
-}
-
-impl<A: Array> ExactSizeIterator for IntoIter<A> { }
-
-impl<A: Array> IntoIterator for SmallVec<A> {
-    type IntoIter = IntoIter<A>;
-    type Item = A::Item;
-    fn into_iter(mut self) -> Self::IntoIter {
-        let len = self.len();
-        unsafe {
-            // Only grab the `data` field, the `IntoIter` type handles dropping of the elements
-            let data = ptr::read(&mut self.data);
-            mem::forget(self);
-            IntoIter {
-                data: data,
-                current: 0,
-                end: len,
-            }
-        }
-    }
-}
-
-impl<'a, A: Array> IntoIterator for &'a SmallVec<A> {
-    type IntoIter = slice::Iter<'a, A::Item>;
-    type Item = &'a A::Item;
-    fn into_iter(self) -> Self::IntoIter {
-        self.iter()
-    }
-}
-
-impl<'a, A: Array> IntoIterator for &'a mut SmallVec<A> {
-    type IntoIter = slice::IterMut<'a, A::Item>;
-    type Item = &'a mut A::Item;
-    fn into_iter(self) -> Self::IntoIter {
-        self.iter_mut()
-    }
-}
-
-// TODO: Remove these and its users.
-
-/// Deprecated alias to ease transition from an earlier version.
-#[deprecated]
-pub type SmallVec1<T> = SmallVec<[T; 1]>;
-
-/// Deprecated alias to ease transition from an earlier version.
-#[deprecated]
-pub type SmallVec2<T> = SmallVec<[T; 2]>;
-
-/// Deprecated alias to ease transition from an earlier version.
-#[deprecated]
-pub type SmallVec4<T> = SmallVec<[T; 4]>;
-
-/// Deprecated alias to ease transition from an earlier version.
-#[deprecated]
-pub type SmallVec8<T> = SmallVec<[T; 8]>;
-
-/// Deprecated alias to ease transition from an earlier version.
-#[deprecated]
-pub type SmallVec16<T> = SmallVec<[T; 16]>;
-
-/// Deprecated alias to ease transition from an earlier version.
-#[deprecated]
-pub type SmallVec24<T> = SmallVec<[T; 24]>;
-
-/// Deprecated alias to ease transition from an earlier version.
-#[deprecated]
-pub type SmallVec32<T> = SmallVec<[T; 32]>;
-
-/// Types that can be used as the backing store for a SmallVec
-pub unsafe trait Array {
-    type Item;
-    fn size() -> usize;
-    fn ptr(&self) -> *const Self::Item;
-    fn ptr_mut(&mut self) -> *mut Self::Item;
-}
-
-macro_rules! impl_array(
-    ($($size:expr),+) => {
-        $(
-            unsafe impl<T> Array for [T; $size] {
-                type Item = T;
-                fn size() -> usize { $size }
-                fn ptr(&self) -> *const T { &self[0] }
-                fn ptr_mut(&mut self) -> *mut T { &mut self[0] }
-            }
-        )+
-    }
-);
-
-impl_array!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 24, 32, 36,
-            0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000,
-            0x10000, 0x20000, 0x40000, 0x80000, 0x100000);
-
-#[cfg(test)]
-pub mod tests {
-    use SmallVec;
-    use std::borrow::ToOwned;
-    use std::iter::FromIterator;
-
-    #[cfg(feature="heapsizeof")]
-    use heapsize::HeapSizeOf;
-    #[cfg(feature="heapsizeof")]
-    use std::mem::size_of;
-
-    // We heap allocate all these strings so that double frees will show up under valgrind.
-
-    #[test]
-    pub fn test_inline() {
-        let mut v = SmallVec::<[_; 16]>::new();
-        v.push("hello".to_owned());
-        v.push("there".to_owned());
-        assert_eq!(&*v, &[
-            "hello".to_owned(),
-            "there".to_owned(),
-        ][..]);
-    }
-
-    #[test]
-    pub fn test_spill() {
-        let mut v = SmallVec::<[_; 2]>::new();
-        v.push("hello".to_owned());
-        assert_eq!(v[0], "hello");
-        v.push("there".to_owned());
-        v.push("burma".to_owned());
-        assert_eq!(v[0], "hello");
-        v.push("shave".to_owned());
-        assert_eq!(&*v, &[
-            "hello".to_owned(),
-            "there".to_owned(),
-            "burma".to_owned(),
-            "shave".to_owned(),
-        ][..]);
-    }
-
-    #[test]
-    pub fn test_double_spill() {
-        let mut v = SmallVec::<[_; 2]>::new();
-        v.push("hello".to_owned());
-        v.push("there".to_owned());
-        v.push("burma".to_owned());
-        v.push("shave".to_owned());
-        v.push("hello".to_owned());
-        v.push("there".to_owned());
-        v.push("burma".to_owned());
-        v.push("shave".to_owned());
-        assert_eq!(&*v, &[
-            "hello".to_owned(),
-            "there".to_owned(),
-            "burma".to_owned(),
-            "shave".to_owned(),
-            "hello".to_owned(),
-            "there".to_owned(),
-            "burma".to_owned(),
-            "shave".to_owned(),
-        ][..]);
-    }
-
-    /// https://github.com/servo/rust-smallvec/issues/4
-    #[test]
-    fn issue_4() {
-        SmallVec::<[Box<u32>; 2]>::new();
-    }
-
-    /// https://github.com/servo/rust-smallvec/issues/5
-    #[test]
-    fn issue_5() {
-        assert!(Some(SmallVec::<[&u32; 2]>::new()).is_some());
-    }
-
-    #[test]
-    fn drain() {
-        let mut v: SmallVec<[u8; 2]> = SmallVec::new();
-        v.push(3);
-        assert_eq!(v.drain().collect::<Vec<_>>(), &[3]);
-
-        // spilling the vec
-        v.push(3);
-        v.push(4);
-        v.push(5);
-        assert_eq!(v.drain().collect::<Vec<_>>(), &[3, 4, 5]);
-    }
-
-    #[test]
-    fn drain_rev() {
-        let mut v: SmallVec<[u8; 2]> = SmallVec::new();
-        v.push(3);
-        assert_eq!(v.drain().rev().collect::<Vec<_>>(), &[3]);
-
-        // spilling the vec
-        v.push(3);
-        v.push(4);
-        v.push(5);
-        assert_eq!(v.drain().rev().collect::<Vec<_>>(), &[5, 4, 3]);
-    }
-
-    #[test]
-    fn into_iter() {
-        let mut v: SmallVec<[u8; 2]> = SmallVec::new();
-        v.push(3);
-        assert_eq!(v.into_iter().collect::<Vec<_>>(), &[3]);
-
-        // spilling the vec
-        let mut v: SmallVec<[u8; 2]> = SmallVec::new();
-        v.push(3);
-        v.push(4);
-        v.push(5);
-        assert_eq!(v.into_iter().collect::<Vec<_>>(), &[3, 4, 5]);
-    }
-
-    #[test]
-    fn into_iter_rev() {
-        let mut v: SmallVec<[u8; 2]> = SmallVec::new();
-        v.push(3);
-        assert_eq!(v.into_iter().rev().collect::<Vec<_>>(), &[3]);
-
-        // spilling the vec
-        let mut v: SmallVec<[u8; 2]> = SmallVec::new();
-        v.push(3);
-        v.push(4);
-        v.push(5);
-        assert_eq!(v.into_iter().rev().collect::<Vec<_>>(), &[5, 4, 3]);
-    }
-
-    #[test]
-    fn into_iter_drop() {
-        use std::cell::Cell;
-
-        struct DropCounter<'a>(&'a Cell<i32>);
-
-        impl<'a> Drop for DropCounter<'a> {
-            fn drop(&mut self) {
-                self.0.set(self.0.get() + 1);
-            }
-        }
-
-        {
-            let cell = Cell::new(0);
-            let mut v: SmallVec<[DropCounter; 2]> = SmallVec::new();
-            v.push(DropCounter(&cell));
-            v.into_iter();
-            assert_eq!(cell.get(), 1);
-        }
-
-        {
-            let cell = Cell::new(0);
-            let mut v: SmallVec<[DropCounter; 2]> = SmallVec::new();
-            v.push(DropCounter(&cell));
-            v.push(DropCounter(&cell));
-            assert!(v.into_iter().next().is_some());
-            assert_eq!(cell.get(), 2);
-        }
-
-        {
-            let cell = Cell::new(0);
-            let mut v: SmallVec<[DropCounter; 2]> = SmallVec::new();
-            v.push(DropCounter(&cell));
-            v.push(DropCounter(&cell));
-            v.push(DropCounter(&cell));
-            assert!(v.into_iter().next().is_some());
-            assert_eq!(cell.get(), 3);
-        }
-        {
-            let cell = Cell::new(0);
-            let mut v: SmallVec<[DropCounter; 2]> = SmallVec::new();
-            v.push(DropCounter(&cell));
-            v.push(DropCounter(&cell));
-            v.push(DropCounter(&cell));
-            {
-                let mut it = v.into_iter();
-                assert!(it.next().is_some());
-                assert!(it.next_back().is_some());
-            }
-            assert_eq!(cell.get(), 3);
-        }
-    }
-
-    #[test]
-    fn test_capacity() {
-        let mut v: SmallVec<[u8; 2]> = SmallVec::new();
-        v.reserve(1);
-        assert_eq!(v.capacity(), 2);
-        assert!(!v.spilled());
-
-        v.reserve_exact(0x100);
-        assert!(v.capacity() >= 0x100);
-
-        v.push(0);
-        v.push(1);
-        v.push(2);
-        v.push(3);
-
-        v.shrink_to_fit();
-        assert!(v.capacity() < 0x100);
-    }
-
-    #[test]
-    fn test_truncate() {
-        let mut v: SmallVec<[Box<u8>; 8]> = SmallVec::new();
-
-        for x in 0..8 {
-            v.push(Box::new(x));
-        }
-        v.truncate(4);
-
-        assert_eq!(v.len(), 4);
-        assert!(!v.spilled());
-
-        assert_eq!(*v.swap_remove(1), 1);
-        assert_eq!(*v.remove(1), 3);
-        v.insert(1, Box::new(3));
-
-        assert_eq!(&v.iter().map(|v| **v).collect::<Vec<_>>(), &[0, 3, 2]);
-    }
-
-    #[test]
-    fn test_insert_many() {
-        let mut v: SmallVec<[u8; 8]> = SmallVec::new();
-        for x in 0..4 {
-            v.push(x);
-        }
-        assert_eq!(v.len(), 4);
-        v.insert_many(1, [5, 6].iter().cloned());
-        assert_eq!(&v.iter().map(|v| *v).collect::<Vec<_>>(), &[0, 5, 6, 1, 2, 3]);
-    }
-
-    struct MockHintIter<T: Iterator>{x: T, hint: usize}
-    impl<T: Iterator> Iterator for MockHintIter<T> {
-        type Item = T::Item;
-        fn next(&mut self) -> Option<Self::Item> {self.x.next()}
-        fn size_hint(&self) -> (usize, Option<usize>) {(self.hint, None)}
-    }
-
-    #[test]
-    fn test_insert_many_short_hint() {
-        let mut v: SmallVec<[u8; 8]> = SmallVec::new();
-        for x in 0..4 {
-            v.push(x);
-        }
-        assert_eq!(v.len(), 4);
-        v.insert_many(1, MockHintIter{x: [5, 6].iter().cloned(), hint: 5});
-        assert_eq!(&v.iter().map(|v| *v).collect::<Vec<_>>(), &[0, 5, 6, 1, 2, 3]);
-    }
-
-    #[test]
-    fn test_insert_many_long_hint() {
-        let mut v: SmallVec<[u8; 8]> = SmallVec::new();
-        for x in 0..4 {
-            v.push(x);
-        }
-        assert_eq!(v.len(), 4);
-        v.insert_many(1, MockHintIter{x: [5, 6].iter().cloned(), hint: 1});
-        assert_eq!(&v.iter().map(|v| *v).collect::<Vec<_>>(), &[0, 5, 6, 1, 2, 3]);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_invalid_grow() {
-        let mut v: SmallVec<[u8; 8]> = SmallVec::new();
-        v.extend(0..8);
-        v.grow(5);
-    }
-
-    #[test]
-    fn test_insert_from_slice() {
-        let mut v: SmallVec<[u8; 8]> = SmallVec::new();
-        for x in 0..4 {
-            v.push(x);
-        }
-        assert_eq!(v.len(), 4);
-        v.insert_from_slice(1, &[5, 6]);
-        assert_eq!(&v.iter().map(|v| *v).collect::<Vec<_>>(), &[0, 5, 6, 1, 2, 3]);
-    }
-
-    #[test]
-    fn test_extend_from_slice() {
-        let mut v: SmallVec<[u8; 8]> = SmallVec::new();
-        for x in 0..4 {
-            v.push(x);
-        }
-        assert_eq!(v.len(), 4);
-        v.extend_from_slice(&[5, 6]);
-        assert_eq!(&v.iter().map(|v| *v).collect::<Vec<_>>(), &[0, 1, 2, 3, 5, 6]);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_drop_panic_smallvec() {
-        // This test should only panic once, and not double panic,
-        // which would mean a double drop
-        struct DropPanic;
-
-        impl Drop for DropPanic {
-            fn drop(&mut self) {
-                panic!("drop");
-            }
-        }
-
-        let mut v = SmallVec::<[_; 1]>::new();
-        v.push(DropPanic);
-    }
-
-    #[test]
-    fn test_eq() {
-        let mut a: SmallVec<[u32; 2]> = SmallVec::new();
-        let mut b: SmallVec<[u32; 2]> = SmallVec::new();
-        let mut c: SmallVec<[u32; 2]> = SmallVec::new();
-        // a = [1, 2]
-        a.push(1);
-        a.push(2);
-        // b = [1, 2]
-        b.push(1);
-        b.push(2);
-        // c = [3, 4]
-        c.push(3);
-        c.push(4);
-
-        assert!(a == b);
-        assert!(a != c);
-    }
-
-    #[test]
-    fn test_ord() {
-        let mut a: SmallVec<[u32; 2]> = SmallVec::new();
-        let mut b: SmallVec<[u32; 2]> = SmallVec::new();
-        let mut c: SmallVec<[u32; 2]> = SmallVec::new();
-        // a = [1]
-        a.push(1);
-        // b = [1, 1]
-        b.push(1);
-        b.push(1);
-        // c = [1, 2]
-        c.push(1);
-        c.push(2);
-
-        assert!(a < b);
-        assert!(b > a);
-        assert!(b < c);
-        assert!(c > b);
-    }
-
-    #[test]
-    fn test_hash() {
-        use std::hash::Hash;
-        use std::collections::hash_map::DefaultHasher;
-
-        {
-            let mut a: SmallVec<[u32; 2]> = SmallVec::new();
-            let b = [1, 2];
-            a.extend(b.iter().cloned());
-            let mut hasher = DefaultHasher::new();
-            assert_eq!(a.hash(&mut hasher), b.hash(&mut hasher));
-        }
-        {
-            let mut a: SmallVec<[u32; 2]> = SmallVec::new();
-            let b = [1, 2, 11, 12];
-            a.extend(b.iter().cloned());
-            let mut hasher = DefaultHasher::new();
-            assert_eq!(a.hash(&mut hasher), b.hash(&mut hasher));
-        }
-    }
-
-    #[test]
-    fn test_as_ref() {
-        let mut a: SmallVec<[u32; 2]> = SmallVec::new();
-        a.push(1);
-        assert_eq!(a.as_ref(), [1]);
-        a.push(2);
-        assert_eq!(a.as_ref(), [1, 2]);
-        a.push(3);
-        assert_eq!(a.as_ref(), [1, 2, 3]);
-    }
-
-    #[test]
-    fn test_as_mut() {
-        let mut a: SmallVec<[u32; 2]> = SmallVec::new();
-        a.push(1);
-        assert_eq!(a.as_mut(), [1]);
-        a.push(2);
-        assert_eq!(a.as_mut(), [1, 2]);
-        a.push(3);
-        assert_eq!(a.as_mut(), [1, 2, 3]);
-        a.as_mut()[1] = 4;
-        assert_eq!(a.as_mut(), [1, 4, 3]);
-    }
-
-    #[test]
-    fn test_borrow() {
-        use std::borrow::Borrow;
-
-        let mut a: SmallVec<[u32; 2]> = SmallVec::new();
-        a.push(1);
-        assert_eq!(a.borrow(), [1]);
-        a.push(2);
-        assert_eq!(a.borrow(), [1, 2]);
-        a.push(3);
-        assert_eq!(a.borrow(), [1, 2, 3]);
-    }
-
-    #[test]
-    fn test_borrow_mut() {
-        use std::borrow::BorrowMut;
-
-        let mut a: SmallVec<[u32; 2]> = SmallVec::new();
-        a.push(1);
-        assert_eq!(a.borrow_mut(), [1]);
-        a.push(2);
-        assert_eq!(a.borrow_mut(), [1, 2]);
-        a.push(3);
-        assert_eq!(a.borrow_mut(), [1, 2, 3]);
-        BorrowMut::<[u32]>::borrow_mut(&mut a)[1] = 4;
-        assert_eq!(a.borrow_mut(), [1, 4, 3]);
-    }
-
-    #[test]
-    fn test_from() {
-        assert_eq!(&SmallVec::<[u32; 2]>::from(&[1][..])[..], [1]);
-        assert_eq!(&SmallVec::<[u32; 2]>::from(&[1, 2, 3][..])[..], [1, 2, 3]);
-    }
-
-    #[test]
-    fn test_from_slice() {
-        assert_eq!(&SmallVec::<[u32; 2]>::from_slice(&[1][..])[..], [1]);
-        assert_eq!(&SmallVec::<[u32; 2]>::from_slice(&[1, 2, 3][..])[..], [1, 2, 3]);
-    }
-
-    #[cfg(feature="heapsizeof")]
-    #[test]
-    fn test_heap_size_of_children() {
-        let mut vec = SmallVec::<[u32; 2]>::new();
-        assert_eq!(vec.heap_size_of_children(), 0);
-        vec.push(1);
-        vec.push(2);
-        assert_eq!(vec.heap_size_of_children(), 0);
-        vec.push(3);
-        assert_eq!(vec.heap_size_of_children(), 16);
-
-        // Now check with reserved space
-        let mut vec = SmallVec::<[u32; 2]>::new();
-        vec.reserve(10);  // Rounds up to 16
-        assert_eq!(vec.heap_size_of_children(), 64);
-
-        // Check with nested heap structures
-        let mut vec = SmallVec::<[Vec<u32>; 2]>::new();
-        vec.reserve(10);
-        vec.push(vec![2, 3, 4]);
-        assert_eq!(vec.heap_size_of_children(),
-                   vec![2, 3, 4].heap_size_of_children() + 16 * size_of::<Vec<u32>>());
-    }
-
-    #[test]
-    fn test_exact_size_iterator() {
-        let mut vec = SmallVec::<[u32; 2]>::from(&[1, 2, 3][..]);
-        assert_eq!(vec.clone().into_iter().len(), 3);
-        assert_eq!(vec.drain().len(), 3);
-    }
-
-    #[test]
-    fn veclike_deref_slice() {
-        use super::VecLike;
-
-        fn test<T: VecLike<i32>>(vec: &mut T) {
-            assert!(!vec.is_empty());
-            assert_eq!(vec.len(), 3);
-
-            vec.sort();
-            assert_eq!(&vec[..], [1, 2, 3]);
-        }
-
-        let mut vec = SmallVec::<[i32; 2]>::from(&[3, 1, 2][..]);
-        test(&mut vec);
-    }
-
-    #[test]
-    fn shrink_to_fit_unspill() {
-        let mut vec = SmallVec::<[u8; 2]>::from_iter(0..3);
-        vec.pop();
-        assert!(vec.spilled());
-        vec.shrink_to_fit();
-        assert!(!vec.spilled(), "shrink_to_fit will un-spill if possible");
-    }
-
-    #[test]
-    fn test_into_vec() {
-        let vec = SmallVec::<[u8; 2]>::from_iter(0..2);
-        assert_eq!(vec.into_vec(), vec![0, 1]);
-
-        let vec = SmallVec::<[u8; 2]>::from_iter(0..3);
-        assert_eq!(vec.into_vec(), vec![0, 1, 2]);
-    }
-
-    #[test]
-    fn test_from_vec() {
-        let vec = vec![];
-        let small_vec: SmallVec<[u8; 3]> = SmallVec::from_vec(vec);
-        assert_eq!(&*small_vec, &[]);
-        drop(small_vec);
-
-        let vec = vec![];
-        let small_vec: SmallVec<[u8; 1]> = SmallVec::from_vec(vec);
-        assert_eq!(&*small_vec, &[]);
-        drop(small_vec);
-
-        let vec = vec![1];
-        let small_vec: SmallVec<[u8; 3]> = SmallVec::from_vec(vec);
-        assert_eq!(&*small_vec, &[1]);
-        drop(small_vec);
-
-        let vec = vec![1, 2, 3];
-        let small_vec: SmallVec<[u8; 3]> = SmallVec::from_vec(vec);
-        assert_eq!(&*small_vec, &[1, 2, 3]);
-        drop(small_vec);
-
-        let vec = vec![1, 2, 3, 4, 5];
-        let small_vec: SmallVec<[u8; 3]> = SmallVec::from_vec(vec);
-        assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
-        drop(small_vec);
-
-        let vec = vec![1, 2, 3, 4, 5];
-        let small_vec: SmallVec<[u8; 1]> = SmallVec::from_vec(vec);
-        assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
-        drop(small_vec);
-    }
-}
--- a/third_party/rust/smallvec/.cargo-checksum.json
+++ b/third_party/rust/smallvec/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".travis.yml":"8d8372a5e10c6d301d70d45da3d51a4b8cbd6d51b57a62e7730942adc69da200","Cargo.toml":"faecc14df6dfd788ebcb312f891846ecf2ea08fd081d242a7318e3015490ee77","README.md":"85c6105e404b1febba9e06773350cc81fe5966369530210669b3465c66237a09","benches/bench.rs":"54cf4879d36ba2a9f3423af91bb93227b70849200e5bf74e384a166d6aa09893","lib.rs":"acdf2c4778adb0b613efb08ff4612d8d7fb2d67747da026ab3894539e7f3e3ed"},"package":"2e40af10aafe98b4d8294ae8388d8a5cd0707c65d364872efe72d063ec44bee0"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".travis.yml":"91edce5ea2a1956399db4b17f580c8b7995af3aa9801c4314865f560c55d6d09","Cargo.toml":"107fc4138f10e17b1b3e7b3ac7f95787100fed0a170303f6bbfaee1c0eedea43","README.md":"ecca7edfce86fe7b219535e3c14721d1de838de7035de077a4d497959260bccc","benches/bench.rs":"54cf4879d36ba2a9f3423af91bb93227b70849200e5bf74e384a166d6aa09893","lib.rs":"2d6b7216296c2f1b1e44bf41c0567f5e47de5fa8a3d984200ef315e8b7939aa3"},"package":"8fcd03faf178110ab0334d74ca9631d77f94c8c11cc77fcb59538abf0025695d"}
\ No newline at end of file
--- a/third_party/rust/smallvec/.travis.yml
+++ b/third_party/rust/smallvec/.travis.yml
@@ -1,13 +1,14 @@
 language: rust
 rust:
   - nightly
   - beta
   - stable
 script: |
   cargo build --verbose &&
-  cargo build --features=heapsizeof --verbose &&
+  cargo build --all-features --verbose &&
   cargo test --verbose &&
-  cargo test --features=heapsizeof --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/smallvec/Cargo.toml
+++ b/third_party/rust/smallvec/Cargo.toml
@@ -1,20 +1,40 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g. crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
 [package]
 name = "smallvec"
-version = "0.4.0"
+version = "0.4.3"
 authors = ["Simon Sapin <simon.sapin@exyr.org>"]
+description = "'Small vector' optimization: store up to a small number of items on the stack"
+documentation = "http://doc.servo.org/smallvec/"
+readme = "README.md"
+keywords = ["small", "vec", "vector", "stack", "no_std"]
 license = "MPL-2.0"
 repository = "https://github.com/servo/rust-smallvec"
-description = "'Small vector' optimization: store up to a small number of items on the stack"
-keywords = ["small", "vec", "vector", "stack"]
-readme = "README.md"
-documentation = "http://doc.servo.org/smallvec/"
-
-[features]
-heapsizeof = ["heapsize"]
 
 [lib]
 name = "smallvec"
 path = "lib.rs"
+[dependencies.serde]
+version = "1"
+optional = true
 
-[dependencies]
-heapsize = { version = "0.4", optional = true }
+[dependencies.heapsize]
+version = "0.4"
+optional = true
+[dev-dependencies.bincode]
+version = "0.8"
+
+[features]
+default = ["std"]
+std = []
+heapsizeof = ["heapsize", "std"]
--- a/third_party/rust/smallvec/README.md
+++ b/third_party/rust/smallvec/README.md
@@ -1,6 +1,6 @@
 rust-smallvec
 =============
 
-[Documentation](http://doc.servo.org/smallvec/)
+[Documentation](http://docs.rs/smallvec/)
 
 "Small vector" optimization for Rust: store up to a small number of items on the stack
--- a/third_party/rust/smallvec/lib.rs
+++ b/third_party/rust/smallvec/lib.rs
@@ -1,30 +1,66 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //! Small vectors in various sizes. These store a certain number of elements inline, and fall back
 //! to the heap for larger allocations.  This can be a useful optimization for improving cache
 //! locality and reducing allocator traffic for workloads that fit within the inline buffer.
+//!
+//! ## no_std support
+//!
+//! By default, `smallvec` depends on `libstd`. However, it can be configured to use the unstable
+//! `liballoc` API instead, for use on platforms that have `liballoc` but not `libstd`.  This
+//! configuration is currently unstable and is not guaranteed to work on all versions of Rust.
+//!
+//! To depend on `smallvec` without `libstd`, use `default-features = false` in the `smallvec`
+//! section of Cargo.toml to disable its `"std"` feature.
+
+#![cfg_attr(not(feature = "std"), no_std)]
+#![cfg_attr(not(feature = "std"), feature(alloc))]
+
+
+#[cfg(not(feature = "std"))]
+#[cfg_attr(test, macro_use)]
+extern crate alloc;
+
+#[cfg(not(feature = "std"))]
+use alloc::Vec;
 
 #[cfg(feature="heapsizeof")]
 extern crate heapsize;
 
+#[cfg(feature = "serde")]
+extern crate serde;
+
+#[cfg(not(feature = "std"))]
+mod std {
+    pub use core::*;
+}
+
 use std::borrow::{Borrow, BorrowMut};
 use std::cmp;
 use std::fmt;
 use std::hash::{Hash, Hasher};
 use std::iter::{IntoIterator, FromIterator};
 use std::mem;
 use std::ops;
 use std::ptr;
 use std::slice;
+#[cfg(feature = "std")]
+use std::io;
 #[cfg(feature="heapsizeof")]
 use std::os::raw::c_void;
+#[cfg(feature = "serde")]
+use serde::ser::{Serialize, Serializer, SerializeSeq};
+#[cfg(feature = "serde")]
+use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
+#[cfg(feature = "serde")]
+use std::marker::PhantomData;
 
 #[cfg(feature="heapsizeof")]
 use heapsize::{HeapSizeOf, heap_size_of};
 use SmallVecData::{Inline, Heap};
 
 /// Common operations implemented by both `Vec` and `SmallVec`.
 ///
 /// This can be used to write generic code that works with both `Vec` and `SmallVec`.
@@ -66,16 +102,46 @@ pub trait VecLike<T>:
 
 impl<T> VecLike<T> for Vec<T> {
     #[inline]
     fn push(&mut self, value: T) {
         Vec::push(self, value);
     }
 }
 
+/// Trait to be implemented by a collection that can be extended from a slice
+///
+/// ## Example
+///
+/// ```rust
+/// use smallvec::{ExtendFromSlice, SmallVec8};
+///
+/// fn initialize<V: ExtendFromSlice<u8>>(v: &mut V) {
+///     v.extend_from_slice(b"Test!");
+/// }
+///
+/// let mut vec = Vec::new();
+/// initialize(&mut vec);
+/// assert_eq!(&vec, b"Test!");
+///
+/// let mut small_vec = SmallVec8::new();
+/// initialize(&mut small_vec);
+/// assert_eq!(&small_vec as &[_], b"Test!");
+/// ```
+pub trait ExtendFromSlice<T>: VecLike<T> {
+    /// Extends a collection from a slice of its element type
+    fn extend_from_slice(&mut self, other: &[T]);
+}
+
+impl<T: Clone> ExtendFromSlice<T> for Vec<T> {
+    fn extend_from_slice(&mut self, other: &[T]) {
+        Vec::extend_from_slice(self, other)
+    }
+}
+
 unsafe fn deallocate<T>(ptr: *mut T, capacity: usize) {
     let _vec: Vec<T> = Vec::from_raw_parts(ptr, 0, capacity);
     // Let it drop.
 }
 
 pub struct Drain<'a, T: 'a> {
     iter: slice::IterMut<'a,T>,
 }
@@ -227,16 +293,35 @@ impl<A: Array> SmallVec<A> {
             len: len,
             data: SmallVecData::Heap {
                 ptr: ptr,
                 capacity: cap
             }
         }
     }
 
+    /// Constructs a new `SmallVec` on the stack from an `A` without
+    /// copying elements.
+    ///
+    /// ```rust
+    /// use smallvec::SmallVec;
+    ///
+    /// let buf = [1, 2, 3, 4, 5];
+    /// let small_vec: SmallVec<_> = SmallVec::from_buf(buf);
+    ///
+    /// assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
+    /// ```
+    #[inline]
+    pub fn from_buf(buf: A) -> SmallVec<A> {
+        SmallVec {
+            len: A::size(),
+            data: SmallVecData::Inline { array: buf },
+        }
+    }
+
     /// Sets the length of a vector.
     ///
     /// This will explicitly set the size of the vector, without actually
     /// modifying its buffers, so it is up to the caller to ensure that the
     /// vector is actually the specified size.
     pub unsafe fn set_len(&mut self, new_len: usize) {
         self.len = new_len
     }
@@ -515,16 +600,34 @@ impl<A: Array> SmallVec<A> {
             Inline { .. } => self.into_iter().collect(),
             Heap { ptr, capacity } => unsafe {
                 let v = Vec::from_raw_parts(ptr, self.len, capacity);
                 mem::forget(self);
                 v
             }
         }
     }
+
+    /// Retains only the elements specified by the predicate.
+    ///
+    /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
+    /// This method operates in place and preserves the order of the retained
+    /// elements.
+    pub fn retain<F: FnMut(&A::Item) -> bool>(&mut self, mut f: F) {
+        let mut del = 0;
+        let len = self.len;
+        for i in 0..len {
+            if !f(&self[i]) {
+                del += 1;
+            } else if del > 0 {
+                self.swap(i - del, i);
+            }
+        }
+        self.truncate(len - del);
+    }
 }
 
 impl<A: Array> SmallVec<A> where A::Item: Copy {
     pub fn from_slice(slice: &[A::Item]) -> Self {
         let mut vec = Self::new();
         vec.extend_from_slice(slice);
         vec
     }
@@ -612,16 +715,83 @@ impl<A: Array> Borrow<[A::Item]> for Sma
 
 impl<A: Array> BorrowMut<[A::Item]> for SmallVec<A> {
     #[inline]
     fn borrow_mut(&mut self) -> &mut [A::Item] {
         self
     }
 }
 
+#[cfg(feature = "std")]
+impl<A: Array<Item = u8>> io::Write for SmallVec<A> {
+    #[inline]
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.extend_from_slice(buf);
+        Ok(buf.len())
+    }
+
+    #[inline]
+    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
+        self.extend_from_slice(buf);
+        Ok(())
+    }
+
+    #[inline]
+    fn flush(&mut self) -> io::Result<()> {
+        Ok(())
+    }
+}
+
+#[cfg(feature = "serde")]
+impl<A: Array> Serialize for SmallVec<A> where A::Item: Serialize {
+    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
+        let mut state = serializer.serialize_seq(Some(self.len()))?;
+        for item in self {
+            state.serialize_element(&item)?;
+        }
+        state.end()
+    }
+}
+
+#[cfg(feature = "serde")]
+impl<'de, A: Array> Deserialize<'de> for SmallVec<A> where A::Item: Deserialize<'de> {
+    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
+        deserializer.deserialize_seq(SmallVecVisitor{phantom: PhantomData})
+    }
+}
+
+#[cfg(feature = "serde")]
+struct SmallVecVisitor<A> {
+    phantom: PhantomData<A>
+}
+
+#[cfg(feature = "serde")]
+impl<'de, A: Array> Visitor<'de> for SmallVecVisitor<A>
+where A::Item: Deserialize<'de>,
+{
+    type Value = SmallVec<A>;
+
+    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        formatter.write_str("a sequence")
+    }
+
+    fn visit_seq<B>(self, mut seq: B) -> Result<Self::Value, B::Error>
+        where
+            B: SeqAccess<'de>,
+    {
+        let mut values = SmallVec::new();
+
+        while let Some(value) = seq.next_element()? {
+            values.push(value);
+        }
+
+        Ok(values)
+    }
+}
+
 impl<'a, A: Array> From<&'a [A::Item]> for SmallVec<A> where A::Item: Clone {
     #[inline]
     fn from(slice: &'a [A::Item]) -> SmallVec<A> {
         slice.into_iter().cloned().collect()
     }
 }
 
 macro_rules! impl_index {
@@ -644,16 +814,21 @@ macro_rules! impl_index {
 }
 
 impl_index!(usize, A::Item);
 impl_index!(ops::Range<usize>, [A::Item]);
 impl_index!(ops::RangeFrom<usize>, [A::Item]);
 impl_index!(ops::RangeTo<usize>, [A::Item]);
 impl_index!(ops::RangeFull, [A::Item]);
 
+impl<A: Array> ExtendFromSlice<A::Item> for SmallVec<A> where A::Item: Copy {
+    fn extend_from_slice(&mut self, other: &[A::Item]) {
+        SmallVec::extend_from_slice(self, other)
+    }
+}
 
 impl<A: Array> VecLike<A::Item> for SmallVec<A> {
     #[inline]
     fn push(&mut self, value: A::Item) {
         SmallVec::push(self, value);
     }
 }
 
@@ -890,18 +1065,31 @@ macro_rules! impl_array(
 
 impl_array!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 24, 32, 36,
             0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000,
             0x10000, 0x20000, 0x40000, 0x80000, 0x100000);
 
 #[cfg(test)]
 pub mod tests {
     use SmallVec;
+
+    use std::iter::FromIterator;
+
+    #[cfg(feature = "std")]
     use std::borrow::ToOwned;
-    use std::iter::FromIterator;
+    #[cfg(not(feature = "std"))]
+    use alloc::borrow::ToOwned;
+    #[cfg(feature = "std")]
+    use std::rc::Rc;
+    #[cfg(not(feature = "std"))]
+    use alloc::rc::Rc;
+    #[cfg(not(feature = "std"))]
+    use alloc::boxed::Box;
+    #[cfg(not(feature = "std"))]
+    use alloc::vec::Vec;
 
     #[cfg(feature="heapsizeof")]
     use heapsize::HeapSizeOf;
     #[cfg(feature="heapsizeof")]
     use std::mem::size_of;
 
     // We heap allocate all these strings so that double frees will show up under valgrind.
 
@@ -1234,16 +1422,17 @@ pub mod tests {
         c.push(2);
 
         assert!(a < b);
         assert!(b > a);
         assert!(b < c);
         assert!(c > b);
     }
 
+    #[cfg(feature = "std")]
     #[test]
     fn test_hash() {
         use std::hash::Hash;
         use std::collections::hash_map::DefaultHasher;
 
         {
             let mut a: SmallVec<[u32; 2]> = SmallVec::new();
             let b = [1, 2];
@@ -1416,9 +1605,82 @@ pub mod tests {
         assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
         drop(small_vec);
 
         let vec = vec![1, 2, 3, 4, 5];
         let small_vec: SmallVec<[u8; 1]> = SmallVec::from_vec(vec);
         assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
         drop(small_vec);
     }
+
+    #[test]
+    fn test_retain() {
+        // Test inline data storate
+        let mut sv: SmallVec<[i32; 5]> = SmallVec::from_slice(&[1, 2, 3, 3, 4]);
+        sv.retain(|&i| i != 3);
+        assert_eq!(sv.pop(), Some(4));
+        assert_eq!(sv.pop(), Some(2));
+        assert_eq!(sv.pop(), Some(1));
+        assert_eq!(sv.pop(), None);
+
+        // Test spilled data storage
+        let mut sv: SmallVec<[i32; 3]> = SmallVec::from_slice(&[1, 2, 3, 3, 4]);
+        sv.retain(|&i| i != 3);
+        assert_eq!(sv.pop(), Some(4));
+        assert_eq!(sv.pop(), Some(2));
+        assert_eq!(sv.pop(), Some(1));
+        assert_eq!(sv.pop(), None);
+
+        // Test that drop implementations are called for inline.
+        let one = Rc::new(1);
+        let mut sv: SmallVec<[Rc<i32>; 3]> = SmallVec::new();
+        sv.push(Rc::clone(&one));
+        assert_eq!(Rc::strong_count(&one), 2);
+        sv.retain(|_| false);
+        assert_eq!(Rc::strong_count(&one), 1);
+
+        // Test that drop implementations are called for spilled data.
+        let mut sv: SmallVec<[Rc<i32>; 1]> = SmallVec::new();
+        sv.push(Rc::clone(&one));
+        sv.push(Rc::new(2));
+        assert_eq!(Rc::strong_count(&one), 2);
+        sv.retain(|_| false);
+        assert_eq!(Rc::strong_count(&one), 1);
+    }
+
+    #[cfg(feature = "std")]
+    #[test]
+    fn test_write() {
+        use io::Write;
+
+        let data = [1, 2, 3, 4, 5];
+
+        let mut small_vec: SmallVec<[u8; 2]> = SmallVec::new();
+        let len = small_vec.write(&data[..]).unwrap();
+        assert_eq!(len, 5);
+        assert_eq!(small_vec.as_ref(), data.as_ref());
+
+        let mut small_vec: SmallVec<[u8; 2]> = SmallVec::new();
+        small_vec.write_all(&data[..]).unwrap();
+        assert_eq!(small_vec.as_ref(), data.as_ref());
+    }
+
+    extern crate bincode;
+
+    #[cfg(feature = "serde")]
+    #[test]
+    fn test_serde() {
+        use self::bincode::{serialize, deserialize, Bounded};
+        let mut small_vec: SmallVec<[i32; 2]> = SmallVec::new();
+        small_vec.push(1);
+        let encoded = serialize(&small_vec, Bounded(100)).unwrap();
+        let decoded: SmallVec<[i32; 2]> = deserialize(&encoded).unwrap();
+        assert_eq!(small_vec, decoded);
+        small_vec.push(2);
+        // Spill the vec
+        small_vec.push(3);
+        small_vec.push(4);
+        // Check again after spilling.
+        let encoded = serialize(&small_vec, Bounded(100)).unwrap();
+        let decoded: SmallVec<[i32; 2]> = deserialize(&encoded).unwrap();
+        assert_eq!(small_vec, decoded);
+    }
 }
--- a/toolkit/library/gtest/rust/Cargo.lock
+++ b/toolkit/library/gtest/rust/Cargo.lock
@@ -291,25 +291,26 @@ source = "registry+https://github.com/ru
 dependencies = [
  "core-foundation 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cssparser"
-version = "0.19.2"
+version = "0.19.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "dtoa-short 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "procedural-masquerade 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cssparser-macros"
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
@@ -541,17 +542,17 @@ dependencies = [
  "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "geckoservo"
 version = "0.0.1"
 dependencies = [
  "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cssparser 0.19.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "nsstring_vendor 0.1.0",
  "parking_lot 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.19.0",
  "servo_arc 0.0.1",
  "style 0.0.1",
@@ -874,29 +875,29 @@ dependencies = [
 ]
 
 [[package]]
 name = "parking_lot"
 version = "0.4.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "parking_lot_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot_core 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "parking_lot_core"
-version = "0.2.1"
+version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "smallvec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "pdqsort"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
@@ -1095,25 +1096,25 @@ name = "scopeguard"
 version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "selectors"
 version = "0.19.0"
 dependencies = [
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cssparser 0.19.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "precomputed-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "servo_arc 0.0.1",
- "smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "semver"
 version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1171,22 +1172,17 @@ source = "registry+https://github.com/ru
 
 [[package]]
 name = "slab"
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "smallvec"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "smallvec"
-version = "0.4.0"
+version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "stable_deref_trait"
 version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1202,17 +1198,17 @@ dependencies = [
  "arraydeque 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "arrayvec 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bindgen 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cssparser 0.19.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1224,17 +1220,17 @@ dependencies = [
  "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "pdqsort 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "precomputed-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.19.0",
  "servo_arc 0.0.1",
- "smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "style_derive 0.0.1",
  "style_traits 0.0.1",
  "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-bidi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1250,17 +1246,17 @@ dependencies = [
 ]
 
 [[package]]
 name = "style_traits"
 version = "0.0.1"
 dependencies = [
  "app_units 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cssparser 0.19.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.19.0",
 ]
 
 [[package]]
 name = "syn"
 version = "0.11.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1567,17 +1563,17 @@ dependencies = [
 "checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
 "checksum clang-sys 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "611ec2e3a7623afd8a8c0d027887b6b55759d894abbf5fe11b9dc11b50d5b49a"
 "checksum clap 2.24.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b8f69e518f967224e628896b54e41ff6acfb4dcfefc5076325c36525dac900f"
 "checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd"
 "checksum core-foundation 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f51ce3b8ebe311c56de14231eb57572c15abebd2d32b3bcb99bcdb9c101f5ac3"
 "checksum core-foundation-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "41115a6aa5d3e1e5ef98148373f25971d1fad53818553f216495f9e67e90a624"
 "checksum core-graphics 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a9f841e9637adec70838c537cae52cb4c751cc6514ad05669b51d107c2021c79"
 "checksum core-text 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16ce16d9ed00181016c11ff48e561314bec92bfbce9fe48f319366618d4e5de6"
-"checksum cssparser 0.19.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1f9442c00898020a56c9485d64c9c8f14ae30ba45be89d15846046593383467f"
+"checksum cssparser 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)" = "dc476dc0960774aa1cabfd0044de7d4585a8f2f8a3ef72e6d9d1e16c1e2492b1"
 "checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df"
 "checksum darling 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9861a8495606435477df581bc858ccf15a3469747edf175b94a4704fd9aaedac"
 "checksum darling_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1486a8b00b45062c997f767738178b43219133dd0c8c826cb811e60563810821"
 "checksum darling_macro 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a86ec160aa0c3dd492dd4a14ec8104ad8f1a9400a820624db857998cc1f80f9"
 "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850"
 "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
 "checksum dtoa-short 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fe6f727b406462fd57c95fed84d1b0dbfb5f0136fcac005adba9ea0367c05cc8"
 "checksum dwrote 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "36e3b27cd0b8a68e00f07e8d8e1e4f4d8a6b8b873290a734f63bd56d792d23e1"
@@ -1622,17 +1618,17 @@ dependencies = [
 "checksum nom 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b8c256fd9471521bcb84c3cdba98921497f1a331cbc15b8030fc63b82050ce"
 "checksum num-integer 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)" = "21e4df1098d1d797d27ef0c69c178c3fab64941559b290fcae198e0825c9c8b5"
 "checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99"
 "checksum num_cpus 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a225d1e2717567599c24f88e49f00856c6e825a12125181ee42c4257e3688d39"
 "checksum odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "c3df9b730298cea3a1c3faa90b7e2f9df3a9c400d0936d6015e6165734eefcba"
 "checksum ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "da12c96037889ae0be29dd2bdd260e5a62a7df24e6466d5a15bb8131c1c200a8"
 "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
 "checksum parking_lot 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "37f364e2ce5efa24c7d0b6646d5bb61145551a0112f107ffd7499f1a3e322fbd"
-"checksum parking_lot_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "56a19dcbb5d1e32b6cccb8a9aa1fc2a38418c8699652e735e2bf391a3dc0aa16"
+"checksum parking_lot_core 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a25dd36576d01cca115881dc920b1f0dd0037303ed8cfa0c5d0a4966151757f7"
 "checksum pdqsort 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ceca1642c89148ca05611cc775a0c383abef355fc4907c4e95f49f7b09d6287c"
 "checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
 "checksum percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de154f638187706bde41d9b4738748933d64e6b37bdbffc0b47a97d16a6ae356"
 "checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc"
 "checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f"
 "checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03"
 "checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2"
 "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
@@ -1655,18 +1651,17 @@ dependencies = [
 "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
 "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
 "checksum serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f530d36fb84ec48fb7146936881f026cdbf4892028835fd9398475f82c1bb4"
 "checksum serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "10552fad5500771f3902d0c5ba187c5881942b811b7ba0d8fbbfbf84d80806d3"
 "checksum serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37aee4e0da52d801acfbc0cc219eb1eda7142112339726e427926a6f6ee65d3a"
 "checksum simd 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a94d14a2ae1f1f110937de5fb69e494372560181c7e1739a097fcc2cee37ba0"
 "checksum siphasher 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ffc669b726f2bc9a3bcff66e5e23b56ba6bf70e22a34c3d7b6d0b3450b65b84"
 "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
-"checksum smallvec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4f8266519bc1d17d0b5b16f6c21295625d562841c708f6376f49028a43e9c11e"
-"checksum smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e40af10aafe98b4d8294ae8388d8a5cd0707c65d364872efe72d063ec44bee0"
+"checksum smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8fcd03faf178110ab0334d74ca9631d77f94c8c11cc77fcb59538abf0025695d"
 "checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
 "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
 "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
 "checksum synom 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "27e31aa4b09b9f4cb12dff3c30ba503e17b1a624413d764d32dab76e3920e5bc"
 "checksum synstructure 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cf318c34a2f8381a4f3d4db2c91b45bca2b1cd8cbe56caced900647be164800c"
 "checksum syntex 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a8f5e3aaa79319573d19938ea38d068056b826db9883a5d47f86c1cecc688f0e"
 "checksum syntex_errors 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)" = "867cc5c2d7140ae7eaad2ae9e8bf39cb18a67ca651b7834f88d46ca98faadb9c"
 "checksum syntex_pos 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13ad4762fe52abc9f4008e85c4fb1b1fe3aa91ccb99ff4826a439c7c598e1047"
--- a/toolkit/library/rust/Cargo.lock
+++ b/toolkit/library/rust/Cargo.lock
@@ -289,25 +289,26 @@ source = "registry+https://github.com/ru
 dependencies = [
  "core-foundation 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cssparser"
-version = "0.19.2"
+version = "0.19.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "dtoa-short 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "procedural-masquerade 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cssparser-macros"
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
@@ -539,17 +540,17 @@ dependencies = [
  "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "geckoservo"
 version = "0.0.1"
 dependencies = [
  "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cssparser 0.19.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "nsstring_vendor 0.1.0",
  "parking_lot 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.19.0",
  "servo_arc 0.0.1",
  "style 0.0.1",
@@ -861,29 +862,29 @@ dependencies = [
 ]
 
 [[package]]
 name = "parking_lot"
 version = "0.4.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "parking_lot_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot_core 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "parking_lot_core"
-version = "0.2.1"
+version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "smallvec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "pdqsort"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
@@ -1082,25 +1083,25 @@ name = "scopeguard"
 version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "selectors"
 version = "0.19.0"
 dependencies = [
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cssparser 0.19.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "precomputed-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "servo_arc 0.0.1",
- "smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "semver"
 version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1158,22 +1159,17 @@ source = "registry+https://github.com/ru
 
 [[package]]
 name = "slab"
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "smallvec"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "smallvec"
-version = "0.4.0"
+version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "stable_deref_trait"
 version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1189,17 +1185,17 @@ dependencies = [
  "arraydeque 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "arrayvec 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bindgen 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cssparser 0.19.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1211,17 +1207,17 @@ dependencies = [
  "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "pdqsort 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "precomputed-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.19.0",
  "servo_arc 0.0.1",
- "smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "style_derive 0.0.1",
  "style_traits 0.0.1",
  "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-bidi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1237,17 +1233,17 @@ dependencies = [
 ]
 
 [[package]]
 name = "style_traits"
 version = "0.0.1"
 dependencies = [
  "app_units 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cssparser 0.19.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.19.0",
 ]
 
 [[package]]
 name = "syn"
 version = "0.11.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1554,17 +1550,17 @@ dependencies = [
 "checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
 "checksum clang-sys 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "611ec2e3a7623afd8a8c0d027887b6b55759d894abbf5fe11b9dc11b50d5b49a"
 "checksum clap 2.24.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b8f69e518f967224e628896b54e41ff6acfb4dcfefc5076325c36525dac900f"
 "checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd"
 "checksum core-foundation 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f51ce3b8ebe311c56de14231eb57572c15abebd2d32b3bcb99bcdb9c101f5ac3"
 "checksum core-foundation-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "41115a6aa5d3e1e5ef98148373f25971d1fad53818553f216495f9e67e90a624"
 "checksum core-graphics 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a9f841e9637adec70838c537cae52cb4c751cc6514ad05669b51d107c2021c79"
 "checksum core-text 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16ce16d9ed00181016c11ff48e561314bec92bfbce9fe48f319366618d4e5de6"
-"checksum cssparser 0.19.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1f9442c00898020a56c9485d64c9c8f14ae30ba45be89d15846046593383467f"
+"checksum cssparser 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)" = "dc476dc0960774aa1cabfd0044de7d4585a8f2f8a3ef72e6d9d1e16c1e2492b1"
 "checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df"
 "checksum darling 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9861a8495606435477df581bc858ccf15a3469747edf175b94a4704fd9aaedac"
 "checksum darling_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1486a8b00b45062c997f767738178b43219133dd0c8c826cb811e60563810821"
 "checksum darling_macro 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a86ec160aa0c3dd492dd4a14ec8104ad8f1a9400a820624db857998cc1f80f9"
 "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850"
 "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
 "checksum dtoa-short 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fe6f727b406462fd57c95fed84d1b0dbfb5f0136fcac005adba9ea0367c05cc8"
 "checksum dwrote 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "36e3b27cd0b8a68e00f07e8d8e1e4f4d8a6b8b873290a734f63bd56d792d23e1"
@@ -1609,17 +1605,17 @@ dependencies = [
 "checksum nom 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b8c256fd9471521bcb84c3cdba98921497f1a331cbc15b8030fc63b82050ce"
 "checksum num-integer 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)" = "21e4df1098d1d797d27ef0c69c178c3fab64941559b290fcae198e0825c9c8b5"
 "checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99"
 "checksum num_cpus 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a225d1e2717567599c24f88e49f00856c6e825a12125181ee42c4257e3688d39"
 "checksum odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "c3df9b730298cea3a1c3faa90b7e2f9df3a9c400d0936d6015e6165734eefcba"
 "checksum ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "da12c96037889ae0be29dd2bdd260e5a62a7df24e6466d5a15bb8131c1c200a8"
 "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
 "checksum parking_lot 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "37f364e2ce5efa24c7d0b6646d5bb61145551a0112f107ffd7499f1a3e322fbd"
-"checksum parking_lot_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "56a19dcbb5d1e32b6cccb8a9aa1fc2a38418c8699652e735e2bf391a3dc0aa16"
+"checksum parking_lot_core 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a25dd36576d01cca115881dc920b1f0dd0037303ed8cfa0c5d0a4966151757f7"
 "checksum pdqsort 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ceca1642c89148ca05611cc775a0c383abef355fc4907c4e95f49f7b09d6287c"
 "checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
 "checksum percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de154f638187706bde41d9b4738748933d64e6b37bdbffc0b47a97d16a6ae356"
 "checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc"
 "checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f"
 "checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03"
 "checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2"
 "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
@@ -1642,18 +1638,17 @@ dependencies = [
 "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
 "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
 "checksum serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f530d36fb84ec48fb7146936881f026cdbf4892028835fd9398475f82c1bb4"
 "checksum serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "10552fad5500771f3902d0c5ba187c5881942b811b7ba0d8fbbfbf84d80806d3"
 "checksum serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37aee4e0da52d801acfbc0cc219eb1eda7142112339726e427926a6f6ee65d3a"
 "checksum simd 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a94d14a2ae1f1f110937de5fb69e494372560181c7e1739a097fcc2cee37ba0"
 "checksum siphasher 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ffc669b726f2bc9a3bcff66e5e23b56ba6bf70e22a34c3d7b6d0b3450b65b84"
 "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
-"checksum smallvec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4f8266519bc1d17d0b5b16f6c21295625d562841c708f6376f49028a43e9c11e"
-"checksum smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e40af10aafe98b4d8294ae8388d8a5cd0707c65d364872efe72d063ec44bee0"
+"checksum smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8fcd03faf178110ab0334d74ca9631d77f94c8c11cc77fcb59538abf0025695d"
 "checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
 "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
 "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
 "checksum synom 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "27e31aa4b09b9f4cb12dff3c30ba503e17b1a624413d764d32dab76e3920e5bc"
 "checksum synstructure 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cf318c34a2f8381a4f3d4db2c91b45bca2b1cd8cbe56caced900647be164800c"
 "checksum syntex 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a8f5e3aaa79319573d19938ea38d068056b826db9883a5d47f86c1cecc688f0e"
 "checksum syntex_errors 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)" = "867cc5c2d7140ae7eaad2ae9e8bf39cb18a67ca651b7834f88d46ca98faadb9c"
 "checksum syntex_pos 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13ad4762fe52abc9f4008e85c4fb1b1fe3aa91ccb99ff4826a439c7c598e1047"