servo: Merge #12783 - Prefer length and percentage for word spacing (from Wafflespeanut:word_spacing); r=Manishearth
authorRavi Shankar <wafflespeanut@gmail.com>
Tue, 09 Aug 2016 10:13:30 -0500
changeset 339459 703c3bfa19f8a99a2d91e6bfedc0676c2beb7406
parent 339458 3113bc024ae00c102f48b4b49e4c15574dcbb1da
child 339460 8447964c3f698df5ddf0cdcc689702d7dfa3776e
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersManishearth
servo: Merge #12783 - Prefer length and percentage for word spacing (from Wafflespeanut:word_spacing); r=Manishearth <!-- Please describe your changes on the following line: --> The goal is to make use of `LengthOrPercentage` for word spacing in `ShapingOptions`, but since it makes use of `f32` which doesn't implement `Hash`, we're going for `NotNan<f32>` from [ordered-float](https://github.com/reem/rust-ordered-float/), which supports hashing. Instead of implementing `Hash` for `LengthOrPercentage` and thereby the inner types like `CSSFloat`, `CalcLengthOrPercentage`, etc., we convert it to `(Au, NotNan<f32>)`. --- <!-- 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 <!-- Either: --> - [ ] There are tests for these changes <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: https://github.com/servo/servo Source-Revision: 3b676bc85dc66ed0e80756204f347bf1842b01a0
servo/components/gfx/Cargo.toml
servo/components/gfx/font.rs
servo/components/gfx/lib.rs
servo/components/gfx/text/shaping/harfbuzz.rs
servo/components/layout/Cargo.toml
servo/components/layout/lib.rs
servo/components/layout/text.rs
servo/components/servo/Cargo.lock
servo/components/style/Cargo.toml
servo/components/style/lib.rs
servo/components/style/properties/longhand/inherited_text.mako.rs
servo/components/style/values/computed/mod.rs
servo/ports/cef/Cargo.lock
servo/ports/geckolib/Cargo.lock
servo/python/tidy/servo_tidy/tidy.py
--- a/servo/components/gfx/Cargo.toml
+++ b/servo/components/gfx/Cargo.toml
@@ -23,16 +23,17 @@ heapsize_plugin = "0.1.2"
 ipc-channel = "0.4.0"
 layers = {git = "https://github.com/servo/rust-layers", features = ["plugins"]}
 lazy_static = "0.2"
 libc = "0.2"
 log = "0.3.5"
 mime = "0.2"
 msg = {path = "../msg"}
 net_traits = {path = "../net_traits"}
+ordered-float = "0.2.2"
 plugins = {path = "../plugins"}
 profile_traits = {path = "../profile_traits"}
 rand = "0.3"
 range = {path = "../range"}
 rustc-serialize = "0.3"
 serde = "0.7.15"
 serde_macros = "0.7.15"
 smallvec = "0.1"
--- a/servo/components/gfx/font.rs
+++ b/servo/components/gfx/font.rs
@@ -1,15 +1,16 @@
 /* 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 app_units::Au;
 use euclid::{Point2D, Rect, Size2D};
 use font_template::FontTemplateDescriptor;
+use ordered_float::NotNaN;
 use platform::font::{FontHandle, FontTable};
 use platform::font_context::FontContextHandle;
 use platform::font_template::FontTemplateData;
 use smallvec::SmallVec;
 use std::ascii::AsciiExt;
 use std::borrow::ToOwned;
 use std::cell::RefCell;
 use std::collections::HashMap;
@@ -152,17 +153,17 @@ bitflags! {
 
 /// Various options that control text shaping.
 #[derive(Clone, Eq, PartialEq, Hash, Copy, Debug)]
 pub struct ShapingOptions {
     /// Spacing to add between each letter. Corresponds to the CSS 2.1 `letter-spacing` property.
     /// NB: You will probably want to set the `IGNORE_LIGATURES_SHAPING_FLAG` if this is non-null.
     pub letter_spacing: Option<Au>,
     /// Spacing to add between each word. Corresponds to the CSS 2.1 `word-spacing` property.
-    pub word_spacing: Au,
+    pub word_spacing: (Au, NotNaN<f32>),
     /// The Unicode script property of the characters in this run.
     pub script: Script,
     /// Various flags.
     pub flags: ShapingFlags,
 }
 
 /// An entry in the shape cache.
 #[derive(Clone, Eq, PartialEq, Hash, Debug)]
@@ -220,17 +221,19 @@ impl Font {
             let character = byte as char;
             let glyph_id = match self.glyph_index(character) {
                 Some(id) => id,
                 None => continue,
             };
 
             let mut advance = Au::from_f64_px(self.glyph_h_advance(glyph_id));
             if character == ' ' {
-                advance += options.word_spacing;
+                // https://drafts.csswg.org/css-text-3/#word-spacing-property
+                let (length, percent) = options.word_spacing;
+                advance = (advance + length) + Au((advance.0 as f32 * percent.into_inner()) as i32);
             }
             if let Some(letter_spacing) = options.letter_spacing {
                 advance += letter_spacing;
             }
             let offset = prev_glyph_id.map(|prev| {
                 let h_kerning = Au::from_f64_px(self.glyph_h_kerning(prev, glyph_id));
                 advance += h_kerning;
                 Point2D::new(h_kerning, Au(0))
--- a/servo/components/gfx/lib.rs
+++ b/servo/components/gfx/lib.rs
@@ -55,16 +55,17 @@ extern crate layers;
 #[macro_use]
 extern crate lazy_static;
 extern crate libc;
 #[macro_use]
 extern crate log;
 extern crate mime;
 extern crate msg;
 extern crate net_traits;
+extern crate ordered_float;
 #[macro_use]
 extern crate profile_traits;
 extern crate rand;
 #[macro_use]
 extern crate range;
 extern crate rustc_serialize;
 extern crate serde;
 
--- a/servo/components/gfx/text/shaping/harfbuzz.rs
+++ b/servo/components/gfx/text/shaping/harfbuzz.rs
@@ -398,17 +398,19 @@ impl Shaper {
             Some(letter_spacing) => advance = advance + letter_spacing,
         };
 
         // CSS 2.1 ยง 16.4 states that "word spacing affects each space (U+0020) and non-breaking
         // space (U+00A0) left in the text after the white space processing rules have been
         // applied. The effect of the property on other word-separator characters is undefined."
         // We elect to only space the two required code points.
         if character == ' ' || character == '\u{a0}' {
-            advance = advance + options.word_spacing
+            // https://drafts.csswg.org/css-text-3/#word-spacing-property
+            let (length, percent) = options.word_spacing;
+            advance = (advance + length) + Au((advance.0 as f32 * percent.into_inner()) as i32);
         }
 
         advance
     }
 }
 
 // Callbacks from Harfbuzz when font map and glyph advance lookup needed.
 lazy_static! {
--- a/servo/components/layout/Cargo.toml
+++ b/servo/components/layout/Cargo.toml
@@ -21,16 +21,17 @@ gfx = {path = "../gfx"}
 gfx_traits = {path = "../gfx_traits"}
 heapsize = "0.3.0"
 heapsize_plugin = "0.1.2"
 ipc-channel = "0.4.0"
 libc = "0.2"
 log = "0.3.5"
 msg = {path = "../msg"}
 net_traits = {path = "../net_traits"}
+ordered-float = "0.2.2"
 plugins = {path = "../plugins"}
 profile_traits = {path = "../profile_traits"}
 range = {path = "../range"}
 rustc-serialize = "0.3"
 script_layout_interface = {path = "../script_layout_interface"}
 script_traits = {path = "../script_traits"}
 selectors = {version = "0.7", features = ["heap_size"]}
 serde_macros = "0.7.15"
--- a/servo/components/layout/lib.rs
+++ b/servo/components/layout/lib.rs
@@ -30,16 +30,17 @@ extern crate gfx;
 extern crate gfx_traits;
 extern crate heapsize;
 extern crate ipc_channel;
 extern crate libc;
 #[macro_use]
 extern crate log;
 extern crate msg;
 extern crate net_traits;
+extern crate ordered_float;
 #[macro_use]
 #[no_link]
 extern crate plugins as servo_plugins;
 #[macro_use]
 extern crate profile_traits;
 #[macro_use]
 extern crate range;
 extern crate rustc_serialize;
--- a/servo/components/layout/text.rs
+++ b/servo/components/layout/text.rs
@@ -12,16 +12,17 @@ use fragment::{ScannedTextFragmentInfo, 
 use gfx::font::{DISABLE_KERNING_SHAPING_FLAG, FontMetrics, IGNORE_LIGATURES_SHAPING_FLAG};
 use gfx::font::{RTL_FLAG, RunMetrics, ShapingFlags, ShapingOptions};
 use gfx::font_context::FontContext;
 use gfx::text::glyph::ByteIndex;
 use gfx::text::text_run::TextRun;
 use gfx::text::util::{self, CompressionMode};
 use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFragments, LAST_FRAGMENT_OF_ELEMENT};
 use linked_list::split_off_head;
+use ordered_float::NotNaN;
 use range::Range;
 use std::borrow::ToOwned;
 use std::collections::LinkedList;
 use std::mem;
 use std::sync::Arc;
 use style::computed_values::white_space;
 use style::computed_values::{line_height, text_orientation, text_rendering, text_transform};
 use style::logical_geometry::{LogicalSize, WritingMode};
@@ -159,17 +160,19 @@ impl TextRunScanner {
                     white_space::T::normal |
                     white_space::T::nowrap => CompressionMode::CompressWhitespaceNewline,
                     white_space::T::pre |
                     white_space::T::pre_wrap => CompressionMode::CompressNone,
                     white_space::T::pre_line => CompressionMode::CompressWhitespace,
                 };
                 text_transform = inherited_text_style.text_transform;
                 letter_spacing = inherited_text_style.letter_spacing.0;
-                word_spacing = inherited_text_style.word_spacing.0.unwrap_or(Au(0));
+                word_spacing = inherited_text_style.word_spacing.0
+                               .map(|lop| lop.to_hash_key())
+                               .unwrap_or((Au(0), NotNaN::new(0.0).unwrap()));
                 text_rendering = inherited_text_style.text_rendering;
             }
 
             // First, transform/compress text of all the nodes.
             let (mut run_info_list, mut run_info) = (Vec::new(), RunInfo::new());
             let mut insertion_point = None;
 
             for (fragment_index, in_fragment) in self.clump.iter().enumerate() {
--- a/servo/components/servo/Cargo.lock
+++ b/servo/components/servo/Cargo.lock
@@ -761,16 +761,17 @@ dependencies = [
  "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "layers 0.2.6 (git+https://github.com/servo/rust-layers)",
  "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "mime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "msg 0.0.1",
  "net_traits 0.0.1",
+ "ordered-float 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "plugins 0.0.1",
  "profile_traits 0.0.1",
  "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "range 0.0.1",
  "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "servo-fontconfig 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1119,16 +1120,17 @@ dependencies = [
  "gfx_traits 0.0.1",
  "heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "msg 0.0.1",
  "net_traits 0.0.1",
+ "ordered-float 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "plugins 0.0.1",
  "profile_traits 0.0.1",
  "range 0.0.1",
  "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "script_layout_interface 0.0.1",
  "script_traits 0.0.1",
  "selectors 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1602,16 +1604,25 @@ dependencies = [
 name = "openssl-verify"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "openssl 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "ordered-float"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "num 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unreachable 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "osmesa-sys"
 version = "0.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "shared_library 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2188,16 +2199,17 @@ dependencies = [
  "heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.13 (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.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ordered-float 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "plugins 0.0.1",
  "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "string_cache 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2358,16 +2370,24 @@ name = "unicode-script"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "harfbuzz-sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "unreachable"
+version = "0.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "void 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "unreachable"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "url"
@@ -2450,16 +2470,21 @@ dependencies = [
  "gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "void"
+version = "0.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "void"
 version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "walkdir"
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
--- a/servo/components/style/Cargo.toml
+++ b/servo/components/style/Cargo.toml
@@ -29,16 +29,17 @@ euclid = "0.7.1"
 fnv = "1.0"
 gecko_bindings = {path = "../../ports/geckolib/gecko_bindings", optional = true}
 heapsize = {version = "0.3.0", optional = true}
 heapsize_plugin = {version = "0.1.2", optional = true}
 lazy_static = "0.2"
 log = "0.3.5"
 matches = "0.1"
 num-traits = "0.1.32"
+ordered-float = "0.2.2"
 rand = "0.3"
 rustc-serialize = "0.3"
 selectors = "0.7"
 serde = {version = "0.7.15", optional = true}
 serde_macros = {version = "0.7.15", optional = true}
 smallvec = "0.1"
 string_cache = "0.2.20"
 style_traits = {path = "../style_traits"}
--- a/servo/components/style/lib.rs
+++ b/servo/components/style/lib.rs
@@ -52,16 +52,17 @@ extern crate gecko_bindings;
 #[macro_use]
 extern crate lazy_static;
 #[macro_use]
 extern crate log;
 #[allow(unused_extern_crates)]
 #[macro_use]
 extern crate matches;
 extern crate num_traits;
+extern crate ordered_float;
 extern crate rand;
 extern crate rustc_serialize;
 extern crate selectors;
 #[cfg(feature = "servo")] extern crate serde;
 extern crate smallvec;
 #[macro_use(atom, ns)] extern crate string_cache;
 #[macro_use]
 extern crate style_traits;
--- a/servo/components/style/properties/longhand/inherited_text.mako.rs
+++ b/servo/components/style/properties/longhand/inherited_text.mako.rs
@@ -280,33 +280,33 @@
             }
         }
     }
 
     #[derive(Debug, Clone, Copy, PartialEq)]
     #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum SpecifiedValue {
         Normal,
-        Specified(specified::Length),  // FIXME(SimonSapin) support percentages
+        Specified(specified::LengthOrPercentage),
     }
 
     impl ToCss for SpecifiedValue {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             match *self {
                 SpecifiedValue::Normal => dest.write_str("normal"),
                 SpecifiedValue::Specified(l) => l.to_css(dest),
             }
         }
     }
 
     pub mod computed_value {
-        use app_units::Au;
+        use values::computed::LengthOrPercentage;
         #[derive(Debug, Clone, PartialEq)]
         #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
-        pub struct T(pub Option<Au>);
+        pub struct T(pub Option<LengthOrPercentage>);
     }
 
     impl ToCss for computed_value::T {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             match self.0 {
                 None => dest.write_str("normal"),
                 Some(l) => l.to_css(dest),
             }
@@ -321,26 +321,27 @@
     impl ToComputedValue for SpecifiedValue {
         type ComputedValue = computed_value::T;
 
         #[inline]
         fn to_computed_value(&self, context: &Context) -> computed_value::T {
             match *self {
                 SpecifiedValue::Normal => computed_value::T(None),
                 SpecifiedValue::Specified(l) =>
-                    computed_value::T(Some(l.to_computed_value(context)))
+                    computed_value::T(Some(l.to_computed_value(context))),
             }
         }
     }
 
     pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
         if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
             Ok(SpecifiedValue::Normal)
         } else {
-            specified::Length::parse_non_negative(input).map(SpecifiedValue::Specified)
+            specified::LengthOrPercentage::parse_non_negative(input)
+                                          .map(SpecifiedValue::Specified)
         }
     }
 </%helpers:longhand>
 
 ${helpers.predefined_type("text-indent",
                           "LengthOrPercentage",
                           "computed::LengthOrPercentage::Length(Au(0))",
                           animatable=True)}
--- a/servo/components/style/values/computed/mod.rs
+++ b/servo/components/style/values/computed/mod.rs
@@ -1,14 +1,15 @@
 /* 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 app_units::Au;
 use euclid::size::Size2D;
+use ordered_float::NotNaN;
 use properties::ComputedValues;
 use std::fmt;
 use super::LocalToCss;
 use super::specified::AngleOrCorner;
 use super::{CSSFloat, specified};
 use url::Url;
 pub use cssparser::Color as CSSColor;
 pub use super::specified::{Angle, BorderStyle, Time, UrlExtraData};
@@ -236,16 +237,25 @@ impl LengthOrPercentage {
     #[inline]
     pub fn is_definitely_zero(&self) -> bool {
         use self::LengthOrPercentage::*;
         match *self {
             Length(Au(0)) | Percentage(0.0) => true,
             Length(_) | Percentage(_) | Calc(_) => false
         }
     }
+
+    pub fn to_hash_key(&self) -> (Au, NotNaN<f32>) {
+        use self::LengthOrPercentage::*;
+        match *self {
+            Length(l) => (l, NotNaN::new(0.0).unwrap()),
+            Percentage(p) => (Au(0), NotNaN::new(p).unwrap()),
+            Calc(c) => (c.length(), NotNaN::new(c.percentage()).unwrap()),
+        }
+    }
 }
 
 impl fmt::Debug for LengthOrPercentage {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
             LengthOrPercentage::Length(length) => write!(f, "{:?}", length),
             LengthOrPercentage::Percentage(percentage) => write!(f, "{}%", percentage * 100.),
             LengthOrPercentage::Calc(calc) => write!(f, "{:?}", calc),
--- a/servo/ports/cef/Cargo.lock
+++ b/servo/ports/cef/Cargo.lock
@@ -679,16 +679,17 @@ dependencies = [
  "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "layers 0.2.6 (git+https://github.com/servo/rust-layers)",
  "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "mime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "msg 0.0.1",
  "net_traits 0.0.1",
+ "ordered-float 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "plugins 0.0.1",
  "profile_traits 0.0.1",
  "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "range 0.0.1",
  "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "servo-fontconfig 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1028,16 +1029,17 @@ dependencies = [
  "gfx_traits 0.0.1",
  "heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "msg 0.0.1",
  "net_traits 0.0.1",
+ "ordered-float 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "plugins 0.0.1",
  "profile_traits 0.0.1",
  "range 0.0.1",
  "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "script_layout_interface 0.0.1",
  "script_traits 0.0.1",
  "selectors 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1476,16 +1478,25 @@ dependencies = [
 name = "openssl-verify"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "openssl 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "ordered-float"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "num 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unreachable 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "osmesa-sys"
 version = "0.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "shared_library 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2073,16 +2084,17 @@ dependencies = [
  "heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.13 (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.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ordered-float 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "plugins 0.0.1",
  "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "string_cache 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2227,16 +2239,24 @@ name = "unicode-script"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "harfbuzz-sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "unreachable"
+version = "0.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "void 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "unreachable"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "url"
@@ -2312,16 +2332,21 @@ dependencies = [
  "gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "void"
+version = "0.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "void"
 version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "walkdir"
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
--- a/servo/ports/geckolib/Cargo.lock
+++ b/servo/ports/geckolib/Cargo.lock
@@ -210,29 +210,65 @@ source = "registry+https://github.com/ru
 name = "memchr"
 version = "0.1.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "num"
+version = "0.1.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-iter 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "num-integer"
+version = "0.1.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "num-iter"
+version = "0.1.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "num-traits"
 version = "0.1.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "num_cpus"
 version = "0.2.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "ordered-float"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "num 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unreachable 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "quickersort"
 version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
  "unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -320,16 +356,17 @@ dependencies = [
  "fnv 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "gecko_bindings 0.0.1",
  "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.13 (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.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ordered-float 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "string_cache 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
  "style_traits 0.0.1",
  "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -383,16 +420,24 @@ dependencies = [
 
 [[package]]
 name = "unicode-normalization"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "unreachable"
+version = "0.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "void 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "unreachable"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "url"
@@ -422,16 +467,21 @@ dependencies = [
  "num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "xdg 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "void"
+version = "0.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "void"
 version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "walkdir"
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
--- a/servo/python/tidy/servo_tidy/tidy.py
+++ b/servo/python/tidy/servo_tidy/tidy.py
@@ -256,17 +256,17 @@ def check_lock(file_name, contents):
             for dependency in package.get("dependencies", []):
                 if dependency.startswith(dependency_prefix):
                     yield package["name"]
 
     if not file_name.endswith(".lock"):
         raise StopIteration
 
     # package names to be neglected (as named by cargo)
-    exceptions = ["lazy_static"]
+    exceptions = ["lazy_static", "unreachable", "void"]
 
     import toml
     content = toml.loads(contents)
 
     packages = {}
     for package in content.get("package", []):
         packages.setdefault(package["name"], []).append(package["version"])