Auto merge of #16347 - tictakk:ticbranch, r=emilio

Removing recursion from ComplexSelector

<!-- Please describe your changes on the following line: -->
Using a smallvec instead of recursively calling to_css for ComplexSelector to handle running out of stack.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #16019  (github issue number if applicable).

<!-- Either: -->
- [X] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/16347)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-04-16 21:02:06 -05:00 committed by GitHub
commit fd89ddf4bb
4 changed files with 26 additions and 6 deletions

1
Cargo.lock generated
View file

@ -2395,6 +2395,7 @@ dependencies = [
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"precomputed-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]

View file

@ -21,3 +21,4 @@ matches = "0.1"
cssparser = "0.12.1"
fnv = "1.0"
precomputed-hash = "0.1"
smallvec = "0.3"

View file

@ -7,6 +7,7 @@
#[macro_use] extern crate matches;
extern crate fnv;
extern crate precomputed_hash;
extern crate smallvec;
pub mod bloom;
pub mod matching;

View file

@ -363,12 +363,29 @@ impl<Impl: SelectorImpl> ToCss for Selector<Impl> {
impl<Impl: SelectorImpl> ToCss for ComplexSelector<Impl> {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
if let Some((ref next, ref combinator)) = self.next {
next.to_css(dest)?;
combinator.to_css(dest)?;
}
for simple in &self.compound_selector {
simple.to_css(dest)?;
use smallvec::SmallVec;
let mut current = self;
let mut nodes = SmallVec::<[&Self;8]>::new();
nodes.push(current);
loop {
match current.next {
None => break,
Some((ref next, _)) => {
current = &**next;
nodes.push(next);
}
}
}
for selector in nodes.iter().rev() {
if let Some((_, ref combinator)) = selector.next {
combinator.to_css(dest)?;
}
for simple in &selector.compound_selector {
simple.to_css(dest)?;
}
}
Ok(())
}