--- 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
--- 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"