No bug - Revendor rust dependencies
authorServo VCS Sync <servo-vcs-sync@mozilla.com>
Tue, 11 Jul 2017 02:17:43 +0000
changeset 368172 98c3565c595d21d0a715899e21ed47fdddaffabf
parent 368171 12ab8a102ba1715c3a0dbf1c9ca48bc1b49ae056
child 368173 28e303771cc05441ca0312ed951a80e19c8fd898
push id32158
push usercbook@mozilla.com
push dateTue, 11 Jul 2017 10:48:59 +0000
treeherdermozilla-central@5e2692f8a367 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
No bug - Revendor rust dependencies
third_party/rust/cssparser/.cargo-checksum.json
third_party/rust/cssparser/Cargo.toml
third_party/rust/cssparser/README.md
third_party/rust/cssparser/src/parser.rs
third_party/rust/cssparser/src/rules_and_declarations.rs
third_party/rust/cssparser/src/serializer.rs
third_party/rust/cssparser/src/tests.rs
third_party/rust/cssparser/src/tokenizer.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":"48c6ae2b34febe2e7287b10e46fd77e6a9c7bb0a7e7f55de551e8113c1abba70","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"9afe084d70a5d9396674a2624012d6ac749df35f81e322d2d75b042bf208f523","build.rs":"950bcc47a196f07f99f59637c28cc65e02a885130011f90a2b2608248b4724a2","build/match_byte.rs":"89e8b941af74df2c204abf808672d3ff278bdec75abc918c41a843260b924677","docs/.nojekyll":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","docs/404.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","docs/index.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","src/big-data-url.css":"04a8f6197ea1181123bca48bd1ebd016268e1da40f01b8f21055814e44bf62b8","src/color.rs":"4b7ab1cb0271340aee65bfd535dfa19ba9c56222fbf7165807aae7c67e321665","src/compact_cow_str.rs":"7f5abdae953febe5a833604e6868d6f60518f1b4ece8de6a8aa8d521f21b8daa","src/css-parsing-tests/An+B.json":"d24559c1dad55d3da9d1fca29383edefdfc6046988435d6388a9bc0f28850257","src/css-parsing-tests/LICENSE":"5f9019a92f4aa8917aadc8e035aa673c2c1bf08d5ca2e535a0564106599f44eb","src/css-parsing-tests/README.rst":"233ce4fdc3e7306db23787fed0b67b0eb81a4600281ec0f7ff22270f2679ca8e","src/css-parsing-tests/color3.json":"9db91fd04a0424dcbde2b1bf530d4dbaa7502c887978aaaca75a613fbee028e9","src/css-parsing-tests/color3_hsl.json":"61c3b7d8d5ae02f94769d64458e0dd29e4c22c5068e5ea44040d14b88f9616b0","src/css-parsing-tests/color3_keywords.json":"95609bf9fe762c316878a30f371fa375a2e51c21a6fda24fa188a95cd9118f5c","src/css-parsing-tests/component_value_list.json":"516f9495fe089fa669321660bc431d7884839da8fb73e45edcbcd98625cb09dc","src/css-parsing-tests/declaration_list.json":"0b85cc3f19e945f838432acbfb9edb003abea13debc4ea27bcdcef25d117eac5","src/css-parsing-tests/make_color3_hsl.py":"3df7dd908ee719f78fd097ab24622f75edd10fcb67514230c172cbfc842c8ab7","src/css-parsing-tests/make_color3_keywords.py":"66bccab3f1dea18698fcfd854be79b1fd1cd724dd487e25b1f057b522163aad2","src/css-parsing-tests/one_component_value.json":"8798017709002e14cf11e203c9d716f82d308ce6ba0f6e64ee4eea331b8485c6","src/css-parsing-tests/one_declaration.json":"a34c9da56edfff9e2e21615f059e141b0e878e90f794dc8fa58d65b47cd193ed","src/css-parsing-tests/one_rule.json":"88f7b1b6049be88e1e2827673b75fc9261986b216e8ee6bf09621fecbe274e3c","src/css-parsing-tests/rule_list.json":"97c45e80fb83abef149a4016c5625a74f053e7ad70a2ce5a95c02fce1c195686","src/css-parsing-tests/stylesheet.json":"05f1e10fc486bfbda2c059c313a74ff78c0063c0768b99737cab41969c0c87ce","src/css-parsing-tests/stylesheet_bytes.json":"890fd856a596e61f82cf7ed77920ffe95df89209fdb5ee0afe0b26bdfdb80a42","src/css-parsing-tests/urange.json":"62720b143ddf52508baad42921473dd69519aad6c1cd49f37f3f264dc29e1c13","src/from_bytes.rs":"331fe63af2123ae3675b61928a69461b5ac77799fff3ce9978c55cf2c558f4ff","src/lib.rs":"a612f377e1b8a4bf1830c4a1da5b4d52296e965fc59ef2d8f915a49fd8db3a37","src/macros.rs":"adb9773c157890381556ea83d7942dcc676f99eea71abbb6afeffee1e3f28960","src/nth.rs":"5304dc5056164c4c6fe4f9682114b0126a28a912fc7af5b63ee86ef4eb728225","src/parser.rs":"ec2d8a9e47ef0a33ea9f42fc575094ef00255424bfed7d12de9a7807c2eb5628","src/rules_and_declarations.rs":"2bf4e1dcbdedf99e08ca8ee1d83abda4471fd41dfac35a42c18b78408c70fdf8","src/serializer.rs":"c212770541ac73e0e7269576abec580e6a7dd73e01e1663870514ddfca3a15b2","src/size_of_tests.rs":"fdcc0a12e274cc86b057e607e099b9b3f6af842d0edf9b65e40c0fcdd76fbf17","src/tests.rs":"6435cbb95b0865b9bfc3ec36e107dc653fd65b779103fc99a60e2acf691f9c25","src/tokenizer.rs":"f63aa6b443ca710122e54c223925dfd21573ad560fa30dcf531b4619933b3af7","src/unicode_range.rs":"efd937ab97ab6a38e2cfe2e89a44e259c33d111ee73ba4a6c4388b8517607d2d"},"package":"2842253baded8e712e9d8d80ebfe5ea8e95c5b27071e6a6db6080ca1e81c07d1"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".travis.yml":"f1fb4b65964c81bc1240544267ea334f554ca38ae7a74d57066f4d47d2b5d568","Cargo.toml":"54e2f60d6d494286a1d7f3ad8cadcd374d343b2becf1955bc1faa7d91ea51e93","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/big-data-url.css":"04a8f6197ea1181123bca48bd1ebd016268e1da40f01b8f21055814e44bf62b8","src/color.rs":"4b7ab1cb0271340aee65bfd535dfa19ba9c56222fbf7165807aae7c67e321665","src/compact_cow_str.rs":"7f5abdae953febe5a833604e6868d6f60518f1b4ece8de6a8aa8d521f21b8daa","src/css-parsing-tests/An+B.json":"d24559c1dad55d3da9d1fca29383edefdfc6046988435d6388a9bc0f28850257","src/css-parsing-tests/LICENSE":"5f9019a92f4aa8917aadc8e035aa673c2c1bf08d5ca2e535a0564106599f44eb","src/css-parsing-tests/README.rst":"233ce4fdc3e7306db23787fed0b67b0eb81a4600281ec0f7ff22270f2679ca8e","src/css-parsing-tests/color3.json":"9db91fd04a0424dcbde2b1bf530d4dbaa7502c887978aaaca75a613fbee028e9","src/css-parsing-tests/color3_hsl.json":"61c3b7d8d5ae02f94769d64458e0dd29e4c22c5068e5ea44040d14b88f9616b0","src/css-parsing-tests/color3_keywords.json":"95609bf9fe762c316878a30f371fa375a2e51c21a6fda24fa188a95cd9118f5c","src/css-parsing-tests/component_value_list.json":"516f9495fe089fa669321660bc431d7884839da8fb73e45edcbcd98625cb09dc","src/css-parsing-tests/declaration_list.json":"0b85cc3f19e945f838432acbfb9edb003abea13debc4ea27bcdcef25d117eac5","src/css-parsing-tests/make_color3_hsl.py":"3df7dd908ee719f78fd097ab24622f75edd10fcb67514230c172cbfc842c8ab7","src/css-parsing-tests/make_color3_keywords.py":"66bccab3f1dea18698fcfd854be79b1fd1cd724dd487e25b1f057b522163aad2","src/css-parsing-tests/one_component_value.json":"8798017709002e14cf11e203c9d716f82d308ce6ba0f6e64ee4eea331b8485c6","src/css-parsing-tests/one_declaration.json":"a34c9da56edfff9e2e21615f059e141b0e878e90f794dc8fa58d65b47cd193ed","src/css-parsing-tests/one_rule.json":"88f7b1b6049be88e1e2827673b75fc9261986b216e8ee6bf09621fecbe274e3c","src/css-parsing-tests/rule_list.json":"97c45e80fb83abef149a4016c5625a74f053e7ad70a2ce5a95c02fce1c195686","src/css-parsing-tests/stylesheet.json":"05f1e10fc486bfbda2c059c313a74ff78c0063c0768b99737cab41969c0c87ce","src/css-parsing-tests/stylesheet_bytes.json":"890fd856a596e61f82cf7ed77920ffe95df89209fdb5ee0afe0b26bdfdb80a42","src/css-parsing-tests/urange.json":"62720b143ddf52508baad42921473dd69519aad6c1cd49f37f3f264dc29e1c13","src/from_bytes.rs":"331fe63af2123ae3675b61928a69461b5ac77799fff3ce9978c55cf2c558f4ff","src/lib.rs":"a612f377e1b8a4bf1830c4a1da5b4d52296e965fc59ef2d8f915a49fd8db3a37","src/macros.rs":"adb9773c157890381556ea83d7942dcc676f99eea71abbb6afeffee1e3f28960","src/nth.rs":"5304dc5056164c4c6fe4f9682114b0126a28a912fc7af5b63ee86ef4eb728225","src/parser.rs":"a5f8755d0f522ab54a5fce8bcc71b7269101025f7612892f0f0340ccc3300dee","src/rules_and_declarations.rs":"0e4d871d9d0f92f303e97ec6f1fa1d3b5a18edc24922b706d279f6ccebc0d6b5","src/serializer.rs":"c872921703dc029155a8019b51df0d23066b072c7e1f553422e448e66218fbdc","src/size_of_tests.rs":"fdcc0a12e274cc86b057e607e099b9b3f6af842d0edf9b65e40c0fcdd76fbf17","src/tests.rs":"35aff1f516da80fbeb72175b716a76d8c58dac0f3664d8ea8f56ac61c5768360","src/tokenizer.rs":"6498c8f1e14c0bd4e36e87651007f03eb37583d11dbcebd428afbdb81336d00e","src/unicode_range.rs":"efd937ab97ab6a38e2cfe2e89a44e259c33d111ee73ba4a6c4388b8517607d2d"},"package":"e7063452c60432cb306ed54d538178c20792d47fa960c240ce6c083239ee55ec"}
\ No newline at end of file
--- a/third_party/rust/cssparser/Cargo.toml
+++ b/third_party/rust/cssparser/Cargo.toml
@@ -1,39 +1,60 @@
+# 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 = "cssparser"
-version = "0.16.1"
-authors = [ "Simon Sapin <simon.sapin@exyr.org>" ]
-
+version = "0.17.0"
+authors = ["Simon Sapin <simon.sapin@exyr.org>"]
+build = "build.rs"
+exclude = ["src/css-parsing-tests"]
 description = "Rust implementation of CSS Syntax Level 3"
 documentation = "https://docs.rs/cssparser/"
-repository = "https://github.com/servo/rust-cssparser"
 readme = "README.md"
 keywords = ["css", "syntax", "parser"]
 license = "MPL-2.0"
-build = "build.rs"
+repository = "https://github.com/servo/rust-cssparser"
+[dependencies.phf]
+version = "0.7"
 
-exclude = ["src/css-parsing-tests"]
+[dependencies.matches]
+version = "0.1"
 
-[dev-dependencies]
-rustc-serialize = "0.3"
-difference = "1.0"
-encoding_rs = "0.5"
+[dependencies.heapsize]
+version = ">= 0.3, < 0.5"
+optional = true
+
+[dependencies.cssparser-macros]
+version = "0.3"
+
+[dependencies.procedural-masquerade]
+version = "0.1"
 
-[dependencies]
-cssparser-macros = {path = "./macros", version = "0.3"}
-heapsize = {version = ">= 0.3, < 0.5", optional = true}
-matches = "0.1"
-phf = "0.7"
-procedural-masquerade = {path = "./procedural-masquerade", version = "0.1"}
-serde = {version = "1.0", optional = true}
+[dependencies.serde]
+version = "1.0"
+optional = true
+[dev-dependencies.encoding_rs]
+version = "0.5"
 
-[build-dependencies]
-syn = "0.11"
-quote = "0.3"
+[dev-dependencies.rustc-serialize]
+version = "0.3"
+
+[dev-dependencies.difference]
+version = "1.0"
+[build-dependencies.syn]
+version = "0.11"
+
+[build-dependencies.quote]
+version = "0.3"
 
 [features]
+dummy_match_byte = []
 bench = []
-dummy_match_byte = []
-
-[workspace]
-members = [".", "./macros", "./procedural-masquerade"]
--- a/third_party/rust/cssparser/README.md
+++ b/third_party/rust/cssparser/README.md
@@ -50,15 +50,8 @@ Parsing CSS involves a series of steps:
   which depends a lot on what you want to do:
   which properties you want to support, what you want to do with selectors, etc.
 
   It does however provide some helper functions to parse [CSS colors](src/color.rs)
   and [An+B](src/nth.rs) (the argument to `:nth-child()` and related selectors.
 
   See [Servo’s `style` crate](https://github.com/mozilla/servo/tree/master/components/style)
   for an example of a parser based on rust-cssparser.
-
-
-TODO
-----
-
-* Figure out float and integer overflow in parsing. (Clamp instead?)
-* Make it fast! (Add a fast path in identifier tokenization?)
--- a/third_party/rust/cssparser/src/parser.rs
+++ b/third_party/rust/cssparser/src/parser.rs
@@ -20,22 +20,22 @@ pub struct SourcePosition {
     at_start_of: Option<BlockType>,
 }
 
 /// The funamental parsing errors that can be triggered by built-in parsing routines.
 #[derive(Clone, Debug, PartialEq)]
 pub enum BasicParseError<'a> {
     /// An unexpected token was encountered.
     UnexpectedToken(Token<'a>),
-    /// A particular token was expected but not found.
-    ExpectedToken(Token<'a>),
     /// The end of the input was encountered unexpectedly.
     EndOfInput,
     /// An `@` rule was encountered that was invalid.
-    AtRuleInvalid,
+    AtRuleInvalid(CompactCowStr<'a>),
+    /// The body of an '@' rule was invalid.
+    AtRuleBodyInvalid,
     /// A qualified rule was encountered that was invalid.
     QualifiedRuleInvalid,
 }
 
 impl<'a, T> From<BasicParseError<'a>> for ParseError<'a, T> {
     fn from(this: BasicParseError<'a>) -> ParseError<'a, T> {
         ParseError::Basic(this)
     }
@@ -183,16 +183,21 @@ impl<'i: 't, 't> Parser<'i, 't> {
     pub fn new(input: &'t mut ParserInput<'i>) -> Parser<'i, 't> {
         Parser {
             tokenizer: input,
             at_start_of: None,
             stop_before: Delimiter::None,
         }
     }
 
+    /// Return the current line that is being parsed.
+    pub fn current_line(&self) -> &'i str {
+        self.tokenizer.0.current_source_line()
+    }
+
     /// Check whether the input is exhausted. That is, if `.next()` would return a token.
     ///
     /// This ignores whitespace and comments.
     #[inline]
     pub fn is_exhausted(&mut self) -> bool {
         self.expect_exhausted().is_ok()
     }
 
@@ -352,19 +357,19 @@ impl<'i: 't, 't> Parser<'i, 't> {
 
     /// Have the given closure parse something, then check the the input is exhausted.
     /// The result is overridden to `Err(())` if some input remains.
     ///
     /// This can help tell e.g. `color: green;` from `color: green 4px;`
     #[inline]
     pub fn parse_entirely<F, T, E>(&mut self, parse: F) -> Result<T, ParseError<'i, E>>
     where F: FnOnce(&mut Parser<'i, 't>) -> Result<T, ParseError<'i, E>> {
-        let result = parse(self);
+        let result = parse(self)?;
         self.expect_exhausted()?;
-        result
+        Ok(result)
     }
 
     /// Parse a list of comma-separated values, all with the same syntax.
     ///
     /// The given closure is called repeatedly with a "delimited" parser
     /// (see the `Parser::parse_until_before` method)
     /// so that it can over consume the input past a comma at this block/function nesting level.
     ///
@@ -477,32 +482,31 @@ impl<'i: 't, 't> Parser<'i, 't> {
     }
 
     /// Parse a <url-token> and return the unescaped value.
     #[inline]
     pub fn expect_url(&mut self) -> Result<CompactCowStr<'i>, BasicParseError<'i>> {
         match self.next()? {
             Token::UnquotedUrl(value) => Ok(value),
             Token::Function(ref name) if name.eq_ignore_ascii_case("url") => {
-                self.parse_nested_block(|input| input.expect_string()
-                                        .map_err(|e| ParseError::Basic(e)))
+                self.parse_nested_block(|input| input.expect_string().map_err(ParseError::Basic))
                     .map_err(ParseError::<()>::basic)
             },
             t => Err(BasicParseError::UnexpectedToken(t))
         }
     }
 
     /// Parse either a <url-token> or a <string-token>, and return the unescaped value.
     #[inline]
     pub fn expect_url_or_string(&mut self) -> Result<CompactCowStr<'i>, BasicParseError<'i>> {
         match self.next()? {
             Token::UnquotedUrl(value) => Ok(value),
             Token::QuotedString(value) => Ok(value),
             Token::Function(ref name) if name.eq_ignore_ascii_case("url") => {
-                self.parse_nested_block(|input| input.expect_string().map_err(|e| ParseError::Basic(e)))
+                self.parse_nested_block(|input| input.expect_string().map_err(ParseError::Basic))
                     .map_err(ParseError::<()>::basic)
             },
             t => Err(BasicParseError::UnexpectedToken(t))
         }
     }
 
     /// Parse a <number-token> and return the integer value.
     #[inline]
--- a/third_party/rust/cssparser/src/rules_and_declarations.rs
+++ b/third_party/rust/cssparser/src/rules_and_declarations.rs
@@ -111,32 +111,32 @@ pub trait AtRuleParser<'i> {
     ///
     /// The given `input` is a "delimited" parser
     /// that ends wherever the prelude should end.
     /// (Before the next semicolon, the next `{`, or the end of the current block.)
     fn parse_prelude<'t>(&mut self, name: CompactCowStr<'i>, input: &mut Parser<'i, 't>)
                      -> Result<AtRuleType<Self::Prelude, Self::AtRule>, ParseError<'i, Self::Error>> {
         let _ = name;
         let _ = input;
-        Err(ParseError::Basic(BasicParseError::AtRuleInvalid))
+        Err(ParseError::Basic(BasicParseError::AtRuleInvalid(name)))
     }
 
     /// Parse the content of a `{ /* ... */ }` block for the body of the at-rule.
     ///
     /// Return the finished representation of the at-rule
     /// as returned by `RuleListParser::next` or `DeclarationListParser::next`,
     /// or `Err(())` to ignore the entire at-rule as invalid.
     ///
     /// This is only called when `parse_prelude` returned `WithBlock` or `OptionalBlock`,
     /// and a block was indeed found following the prelude.
     fn parse_block<'t>(&mut self, prelude: Self::Prelude, input: &mut Parser<'i, 't>)
                        -> Result<Self::AtRule, ParseError<'i, Self::Error>> {
         let _ = prelude;
         let _ = input;
-        Err(ParseError::Basic(BasicParseError::AtRuleInvalid))
+        Err(ParseError::Basic(BasicParseError::AtRuleBodyInvalid))
     }
 
     /// An `OptionalBlock` prelude was followed by `;`.
     ///
     /// Convert the prelude into the finished representation of the at-rule
     /// as returned by `RuleListParser::next` or `DeclarationListParser::next`.
     fn rule_without_block(&mut self, prelude: Self::Prelude) -> Self::AtRule {
         let _ = prelude;
@@ -252,19 +252,19 @@ where P: DeclarationParser<'i, Declarati
                     }.map_err(|e| PreciseParseError {
                         error: e,
                         span: start_position..self.input.position()
                     }))
                 }
                 Ok(Token::AtKeyword(name)) => {
                     return Some(parse_at_rule(start_position, name, self.input, &mut self.parser))
                 }
-                Ok(_) => {
+                Ok(t) => {
                     return Some(self.input.parse_until_after(Delimiter::Semicolon,
-                                                             |_| Err(ParseError::Basic(BasicParseError::ExpectedToken(Token::Semicolon))))
+                                                             |_| Err(ParseError::Basic(BasicParseError::UnexpectedToken(t))))
                                 .map_err(|e| PreciseParseError {
                                     error: e,
                                     span: start_position..self.input.position()
                                 }))
                 }
                 Err(_) => return None,
             }
         }
@@ -457,26 +457,24 @@ fn parse_at_rule<'i: 't, 't, P, E>(start
                         .map_err(|e| PreciseParseError {
                             error: e,
                             span: start_position..input.position(),
                         })
                 }
                 _ => unreachable!()
             }
         }
-        Err(_) => {
+        Err(error) => {
             let end_position = input.position();
-            let error = match input.next() {
-                Ok(Token::CurlyBracketBlock) => BasicParseError::UnexpectedToken(Token::CurlyBracketBlock),
-                Ok(Token::Semicolon) => BasicParseError::UnexpectedToken(Token::Semicolon),
-                Err(e) => e,
+            match input.next() {
+                Ok(Token::CurlyBracketBlock) | Ok(Token::Semicolon) | Err(_) => {},
                 _ => unreachable!()
             };
             Err(PreciseParseError {
-                error: ParseError::Basic(error),
+                error: error,
                 span: start_position..end_position,
             })
         }
     }
 }
 
 
 fn parse_qualified_rule<'i, 't, P, E>(input: &mut Parser<'i, 't>, parser: &mut P)
--- a/third_party/rust/cssparser/src/serializer.rs
+++ b/third_party/rust/cssparser/src/serializer.rs
@@ -124,18 +124,18 @@ impl<'a> ToCss for Token<'a> {
             Token::Function(ref name) => {
                 serialize_identifier(&**name, dest)?;
                 dest.write_str("(")?;
             },
             Token::ParenthesisBlock => dest.write_str("(")?,
             Token::SquareBracketBlock => dest.write_str("[")?,
             Token::CurlyBracketBlock => dest.write_str("{")?,
 
-            Token::BadUrl => dest.write_str("url(<bad url>)")?,
-            Token::BadString => dest.write_str("\"<bad string>\n")?,
+            Token::BadUrl(_) => dest.write_str("url(<bad url>)")?,
+            Token::BadString(_) => dest.write_str("\"<bad string>\n")?,
             Token::CloseParenthesis => dest.write_str(")")?,
             Token::CloseSquareBracket => dest.write_str("]")?,
             Token::CloseCurlyBracket => dest.write_str("}")?,
         }
         Ok(())
     }
 }
 
@@ -371,17 +371,17 @@ impl<'a> Token<'a> {
     /// between two tokens when serialized next to each other without whitespace in between.
     ///
     /// See the `TokenSerializationType::needs_separator_when_before` method.
     pub fn serialization_type(&self) -> TokenSerializationType {
         use self::TokenSerializationTypeVariants::*;
         TokenSerializationType(match *self {
             Token::Ident(_) => Ident,
             Token::AtKeyword(_) | Token::Hash(_) | Token::IDHash(_) => AtKeywordOrHash,
-            Token::UnquotedUrl(_) | Token::BadUrl => UrlOrBadUrl,
+            Token::UnquotedUrl(_) | Token::BadUrl(_) => UrlOrBadUrl,
             Token::Delim('#') => DelimHash,
             Token::Delim('@') => DelimAt,
             Token::Delim('.') | Token::Delim('+') => DelimDotOrPlus,
             Token::Delim('-') => DelimMinus,
             Token::Delim('?') => DelimQuestion,
             Token::Delim('$') | Token::Delim('^') | Token::Delim('~') => DelimAssorted,
             Token::Delim('=') => DelimEquals,
             Token::Delim('|') => DelimBar,
@@ -395,15 +395,15 @@ impl<'a> Token<'a> {
             Token::DashMatch => DashMatch,
             Token::SubstringMatch => SubstringMatch,
             Token::Column => DelimBar,
             Token::CDC => CDC,
             Token::Function(_) => Function,
             Token::ParenthesisBlock => OpenParen,
             Token::SquareBracketBlock | Token::CurlyBracketBlock |
             Token::CloseParenthesis | Token::CloseSquareBracket | Token::CloseCurlyBracket |
-            Token::QuotedString(_) | Token::BadString |
+            Token::QuotedString(_) | Token::BadString(_) |
             Token::Delim(_) | Token::Colon | Token::Semicolon | Token::Comma | Token::CDO |
             Token::IncludeMatch | Token::PrefixMatch | Token::SuffixMatch
             => Other,
         })
     }
 }
--- a/third_party/rust/cssparser/src/tests.rs
+++ b/third_party/rust/cssparser/src/tests.rs
@@ -446,36 +446,36 @@ fn serialize_rgba_two_digit_float_if_rou
     let c = Color::RGBA(RGBA::from_floats(0., 0., 0., 0.5));
     assert_eq!(c.to_css_string(), "rgba(0, 0, 0, 0.5)");
 }
 
 #[test]
 fn line_numbers() {
     let mut input = ParserInput::new("foo bar\nbaz\r\n\n\"a\\\r\nb\"");
     let mut input = Parser::new(&mut input);
-    assert_eq!(input.current_source_location(), SourceLocation { line: 1, column: 1 });
+    assert_eq!(input.current_source_location(), SourceLocation { line: 0, column: 0 });
     assert_eq!(input.next_including_whitespace(), Ok(Token::Ident("foo".into())));
-    assert_eq!(input.current_source_location(), SourceLocation { line: 1, column: 4 });
+    assert_eq!(input.current_source_location(), SourceLocation { line: 0, column: 3 });
     assert_eq!(input.next_including_whitespace(), Ok(Token::WhiteSpace(" ")));
-    assert_eq!(input.current_source_location(), SourceLocation { line: 1, column: 5 });
+    assert_eq!(input.current_source_location(), SourceLocation { line: 0, column: 4 });
     assert_eq!(input.next_including_whitespace(), Ok(Token::Ident("bar".into())));
-    assert_eq!(input.current_source_location(), SourceLocation { line: 1, column: 8 });
+    assert_eq!(input.current_source_location(), SourceLocation { line: 0, column: 7 });
     assert_eq!(input.next_including_whitespace(), Ok(Token::WhiteSpace("\n")));
-    assert_eq!(input.current_source_location(), SourceLocation { line: 2, column: 1 });
+    assert_eq!(input.current_source_location(), SourceLocation { line: 1, column: 0 });
     assert_eq!(input.next_including_whitespace(), Ok(Token::Ident("baz".into())));
-    assert_eq!(input.current_source_location(), SourceLocation { line: 2, column: 4 });
+    assert_eq!(input.current_source_location(), SourceLocation { line: 1, column: 3 });
     let position = input.position();
 
     assert_eq!(input.next_including_whitespace(), Ok(Token::WhiteSpace("\r\n\n")));
-    assert_eq!(input.current_source_location(), SourceLocation { line: 4, column: 1 });
+    assert_eq!(input.current_source_location(), SourceLocation { line: 3, column: 0 });
 
-    assert_eq!(input.source_location(position), SourceLocation { line: 2, column: 4 });
+    assert_eq!(input.source_location(position), SourceLocation { line: 1, column: 3 });
 
     assert_eq!(input.next_including_whitespace(), Ok(Token::QuotedString("ab".into())));
-    assert_eq!(input.current_source_location(), SourceLocation { line: 5, column: 3 });
+    assert_eq!(input.current_source_location(), SourceLocation { line: 4, column: 2 });
     assert!(input.next_including_whitespace().is_err());
 }
 
 #[test]
 fn overflow() {
     use std::iter::repeat;
     use std::f32;
 
@@ -843,18 +843,18 @@ fn one_component_value_to_json(token: To
             v.extend(nested(input));
             v
         }),
         Token::CurlyBracketBlock => Json::Array({
             let mut v = vec!["{}".to_json()];
             v.extend(nested(input));
             v
         }),
-        Token::BadUrl => JArray!["error", "bad-url"],
-        Token::BadString => JArray!["error", "bad-string"],
+        Token::BadUrl(_) => JArray!["error", "bad-url"],
+        Token::BadString(_) => JArray!["error", "bad-string"],
         Token::CloseParenthesis => JArray!["error", ")"],
         Token::CloseSquareBracket => JArray!["error", "]"],
         Token::CloseCurlyBracket => JArray!["error", "}"],
     }
 }
 
 /// A previous version of procedural-masquerade had a bug where it
 /// would normalize consecutive whitespace to a single space,
@@ -915,8 +915,37 @@ fn parse_until_before_stops_at_delimiter
                         }
                         Ok(())
                     })
                 });
             }
         }
     }
 }
+
+#[test]
+fn parser_maintains_current_line() {
+    let mut input = ParserInput::new("ident ident;\nident ident ident;\nident");
+    let mut parser = Parser::new(&mut input);
+    assert_eq!(parser.current_line(), "ident ident;");
+    assert_eq!(parser.next(), Ok(Token::Ident("ident".into())));
+    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 ident ident;");
+    assert_eq!(parser.next(), Ok(Token::Ident("ident".into())));
+    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 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
@@ -152,22 +152,22 @@ pub enum Token<'a> {
     SquareBracketBlock,
 
     /// A `<{-token>`
     CurlyBracketBlock,
 
     /// A `<bad-url-token>`
     ///
     /// This token always indicates a parse error.
-    BadUrl,
+    BadUrl(CompactCowStr<'a>),
 
     /// A `<bad-string-token>`
     ///
     /// This token always indicates a parse error.
-    BadString,
+    BadString(CompactCowStr<'a>),
 
     /// A `<)-token>`
     ///
     /// When obtained from one of the `Parser::next*` methods,
     /// this token is always unmatched and indicates a parse error.
     CloseParenthesis,
 
     /// A `<]-token>`
@@ -189,17 +189,17 @@ impl<'a> Token<'a> {
     ///
     /// `BadUrl` and `BadString` are tokenizer-level parse errors.
     ///
     /// `CloseParenthesis`, `CloseSquareBracket`, and `CloseCurlyBracket` are *unmatched*
     /// and therefore parse errors when returned by one of the `Parser::next*` methods.
     pub fn is_parse_error(&self) -> bool {
         matches!(
             *self,
-            BadUrl | BadString | CloseParenthesis | CloseSquareBracket | CloseCurlyBracket
+            BadUrl(_) | BadString(_) | CloseParenthesis | CloseSquareBracket | CloseCurlyBracket
         )
     }
 }
 
 
 #[derive(Clone)]
 pub struct Tokenizer<'a> {
     input: &'a str,
@@ -221,17 +221,17 @@ enum SeenStatus {
 
 impl<'a> Tokenizer<'a> {
     #[inline]
     pub fn new(input: &str) -> Tokenizer {
         Tokenizer {
             input: input,
             position: 0,
             last_known_source_location: Cell::new((SourcePosition(0),
-                                                   SourceLocation { line: 1, column: 1 })),
+                                                   SourceLocation { line: 0, column: 0 })),
             var_functions: SeenStatus::DontCare,
             viewport_percentages: SeenStatus::DontCare,
         }
     }
 
     #[inline]
     pub fn look_for_var_functions(&mut self) {
         self.var_functions = SeenStatus::LookingForThem;
@@ -282,40 +282,51 @@ impl<'a> Tokenizer<'a> {
     }
 
     #[inline]
     pub fn current_source_location(&self) -> SourceLocation {
         let position = SourcePosition(self.position);
         self.source_location(position)
     }
 
+    pub fn current_source_line(&self) -> &'a str {
+        let current = self.position;
+        let start = self.input[0..current]
+            .rfind(|c| matches!(c, '\r' | '\n' | '\x0C'))
+            .map_or(0, |start| start + 1);
+        let end = self.input[current..]
+            .find(|c| matches!(c, '\r' | '\n' | '\x0C'))
+            .map_or(self.input.len(), |end| current + end);
+        &self.input[start..end]
+    }
+
     pub fn source_location(&self, position: SourcePosition) -> SourceLocation {
         let target = position.0;
         let mut location;
         let mut position;
         let (SourcePosition(last_known_position), last_known_location) =
             self.last_known_source_location.get();
         if target >= last_known_position {
             position = last_known_position;
             location = last_known_location;
         } else {
             // For now we’re only traversing the source *forwards* to count newlines.
             // So if the requested position is before the last known one,
             // start over from the beginning.
             position = 0;
-            location = SourceLocation { line: 1, column: 1 };
+            location = SourceLocation { line: 0, column: 0 };
         }
         let mut source = &self.input[position..target];
         while let Some(newline_position) = source.find(|c| matches!(c, '\n' | '\r' | '\x0C')) {
             let offset = newline_position +
                 if source[newline_position..].starts_with("\r\n") { 2 } else { 1 };
             source = &source[offset..];
             position += offset;
             location.line += 1;
-            location.column = 1;
+            location.column = 0;
         }
         debug_assert!(position <= target);
         location.column += (target - position) as u32;
         self.last_known_source_location.set((SourcePosition(target), location));
         location
     }
 
     #[inline]
@@ -381,20 +392,20 @@ impl<'a> Tokenizer<'a> {
 
 #[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)]
 pub struct SourcePosition(usize);
 
 
 /// The line and column number for a given position within the input.
 #[derive(PartialEq, Eq, Debug, Clone, Copy)]
 pub struct SourceLocation {
-    /// The line number, starting at 1 for the first line.
+    /// The line number, starting at 0 for the first line.
     pub line: u32,
 
-    /// The column number within a line, starting at 1 for first the character of the line.
+    /// The column number within a line, starting at 0 for first the character of the line.
     pub column: u32,
 }
 
 
 fn next_token<'a>(tokenizer: &mut Tokenizer<'a>) -> Result<Token<'a>, ()> {
     if tokenizer.is_eof() {
         return Err(())
     }
@@ -551,24 +562,24 @@ fn next_token<'a>(tokenizer: &mut Tokeni
     };
     Ok(token)
 }
 
 
 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(()) => BadString
+        Err(value) => BadString(value)
     }
 }
 
 
 /// Return `Err(())` on syntax error (ie. unescaped newline)
 fn consume_quoted_string<'a>(tokenizer: &mut Tokenizer<'a>, single_quote: bool)
-                             -> Result<CompactCowStr<'a>, ()> {
+                             -> Result<CompactCowStr<'a>, CompactCowStr<'a>> {
     tokenizer.advance(1);  // Skip the initial quote
     // start_pos is at code point boundary, after " or '
     let start_pos = tokenizer.position();
     let mut string_bytes;
     loop {
         if tokenizer.is_eof() {
             return Ok(tokenizer.slice_from(start_pos).into())
         }
@@ -591,25 +602,32 @@ fn consume_quoted_string<'a>(tokenizer: 
                 // * The tokenizer’s input is UTF-8 since it’s `&str`.
                 // * start_pos is at a code point boundary
                 // * so is the current position (which is before '\\' or '\0'
                 //
                 // So `string_bytes` is well-formed UTF-8.
                 string_bytes = tokenizer.slice_from(start_pos).as_bytes().to_owned();
                 break
             }
-            b'\n' | b'\r' | b'\x0C' => { return Err(()) },
+            b'\n' | b'\r' | b'\x0C' => {
+                return Err(tokenizer.slice_from(start_pos).into())
+            },
             _ => {}
         }
         tokenizer.consume_byte();
     }
 
     while !tokenizer.is_eof() {
         if matches!(tokenizer.next_byte_unchecked(), b'\n' | b'\r' | b'\x0C') {
-            return Err(());
+            return Err(
+                // string_bytes is well-formed UTF-8, see other comments.
+                unsafe {
+                    from_utf8_release_unchecked(string_bytes)
+                }.into()
+            );
         }
         let b = tokenizer.consume_byte();
         match_byte! { b,
             b'"' => {
                 if !single_quote {
                     break;
                 }
             }
@@ -1008,27 +1026,28 @@ fn consume_unquoted_url<'a>(tokenizer: &
                     return consume_bad_url(tokenizer);
                 }
             }
         }
         UnquotedUrl(string)
     }
 
     fn consume_bad_url<'a>(tokenizer: &mut Tokenizer<'a>) -> Token<'a> {
+        let start_pos = tokenizer.position();
         // Consume up to the closing )
         while !tokenizer.is_eof() {
             match_byte! { tokenizer.consume_byte(),
                 b')' => { break },
                 b'\\' => {
                     tokenizer.advance(1); // Skip an escaped ')' or '\'
                 }
                 _ => {},
             }
         }
-        BadUrl
+        BadUrl(tokenizer.slice_from(start_pos).into())
     }
 }
 
 // (value, number of digits up to 6)
 fn consume_hex_digits<'a>(tokenizer: &mut Tokenizer<'a>) -> (u32, u32) {
     let mut value = 0;
     let mut digits = 0;
     while digits < 6 && !tokenizer.is_eof() {
--- a/toolkit/library/gtest/rust/Cargo.lock
+++ b/toolkit/library/gtest/rust/Cargo.lock
@@ -227,17 +227,17 @@ 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.16.1"
+version = "0.17.0"
 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)",
  "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.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -371,17 +371,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.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.17.0 (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.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.19.0",
  "style 0.0.1",
  "style_traits 0.0.1",
@@ -821,17 +821,17 @@ 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.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.17.0 (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)",
@@ -917,17 +917,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.26.1 (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.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.17.0 (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)",
  "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.2 (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)",
  "nsstring_vendor 0.1.0",
@@ -962,17 +962,17 @@ dependencies = [
 ]
 
 [[package]]
 name = "style_traits"
 version = "0.0.1"
 dependencies = [
  "app_units 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cssparser 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.17.0 (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"
@@ -1267,17 +1267,17 @@ dependencies = [
 "checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
 "checksum clang-sys 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff7c2d1502c65748c7221f43ce670b3ba5c697acebfeb85a580827daca6975fc"
 "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.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2842253baded8e712e9d8d80ebfe5ea8e95c5b27071e6a6db6080ca1e81c07d1"
+"checksum cssparser 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e7063452c60432cb306ed54d538178c20792d47fa960c240ce6c083239ee55ec"
 "checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df"
 "checksum dwrote 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "36e3b27cd0b8a68e00f07e8d8e1e4f4d8a6b8b873290a734f63bd56d792d23e1"
 "checksum either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18785c1ba806c258137c937e44ada9ee7e69a37e3c72077542cd2f069d78562a"
 "checksum encoding_c 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1e563195f16d7439103c49281b8b00bd0f223c16e19f0d500448239a27712570"
 "checksum encoding_rs 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e00a1b1e95eb46988805ceee6f34cd95c46a6753e290cb3ff0486931989d4a4c"
 "checksum env_logger 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ed39959122ea027670b704fb70539f4286ddf4a49eefede23bf0b4b2a069ec03"
 "checksum euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7be9fcb1ce77782eb620253eb02bc1f000545f3c360841a26cda572f10fad4ff"
 "checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
--- a/toolkit/library/rust/Cargo.lock
+++ b/toolkit/library/rust/Cargo.lock
@@ -225,17 +225,17 @@ 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.16.1"
+version = "0.17.0"
 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)",
  "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.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -369,17 +369,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.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.17.0 (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.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.19.0",
  "style 0.0.1",
  "style_traits 0.0.1",
@@ -808,17 +808,17 @@ 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.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.17.0 (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)",
@@ -904,17 +904,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.26.1 (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.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.17.0 (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)",
  "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.2 (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)",
  "nsstring_vendor 0.1.0",
@@ -949,17 +949,17 @@ dependencies = [
 ]
 
 [[package]]
 name = "style_traits"
 version = "0.0.1"
 dependencies = [
  "app_units 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cssparser 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.17.0 (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"
@@ -1254,17 +1254,17 @@ dependencies = [
 "checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
 "checksum clang-sys 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff7c2d1502c65748c7221f43ce670b3ba5c697acebfeb85a580827daca6975fc"
 "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.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2842253baded8e712e9d8d80ebfe5ea8e95c5b27071e6a6db6080ca1e81c07d1"
+"checksum cssparser 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e7063452c60432cb306ed54d538178c20792d47fa960c240ce6c083239ee55ec"
 "checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df"
 "checksum dwrote 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "36e3b27cd0b8a68e00f07e8d8e1e4f4d8a6b8b873290a734f63bd56d792d23e1"
 "checksum either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18785c1ba806c258137c937e44ada9ee7e69a37e3c72077542cd2f069d78562a"
 "checksum encoding_c 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1e563195f16d7439103c49281b8b00bd0f223c16e19f0d500448239a27712570"
 "checksum encoding_rs 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e00a1b1e95eb46988805ceee6f34cd95c46a6753e290cb3ff0486931989d4a4c"
 "checksum env_logger 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ed39959122ea027670b704fb70539f4286ddf4a49eefede23bf0b4b2a069ec03"
 "checksum euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7be9fcb1ce77782eb620253eb02bc1f000545f3c360841a26cda572f10fad4ff"
 "checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"