servo: Merge #11816 - Make the style crate (almost) build with a stable compiler (from servo:stable-style); r=nox
authorSimon Sapin <simon.sapin@exyr.org>
Wed, 22 Jun 2016 09:43:20 -0500
changeset 339113 7b98ed8ad6fe71e2d2c77d193a2d5f362bcde447
parent 339112 b3fa9ac83b5cf2a7407e75deb76b93bbd2e43887
child 339114 2ce1b591d94635ba6fdcefa604066dde60d0493c
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)
reviewersnox
servo: Merge #11816 - Make the style crate (almost) build with a stable compiler (from servo:stable-style); r=nox <!-- Please describe your changes on the following line: --> The bulk of this is adding cargo features to make derived implementations of `heapsize` and `serde` traits optional. "Almost" because `std::intrinsics::discriminant_value` is currently unstable and doesn’t have any stable replacement that I know of. For now, this PR conditionally replaces it with `unimplemented!()`. r? @nox --- <!-- 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 <s>fix</s> are part of #11815 (github issue number if applicable). <!-- Either: --> - [ ] There are tests for these changes OR - [x] These changes do not <s>require tests</s> *have tests yet* because that requires https://github.com/servo/servo/issues/11806, but I still want to land this before it bitrots. (Tests should check that the build succeeds with a stable compiler.) <!-- 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: 0fb5d634a007f3d0424f95569ac3f83d500d054c
servo/components/gfx/Cargo.toml
servo/components/gfx/display_list/mod.rs
servo/components/msg/Cargo.toml
servo/components/profile/Cargo.toml
servo/components/script_traits/Cargo.toml
servo/components/servo/Cargo.lock
servo/components/servo/Cargo.toml
servo/components/style/Cargo.toml
servo/components/style/attr.rs
servo/components/style/custom_properties.rs
servo/components/style/data.rs
servo/components/style/dom.rs
servo/components/style/element_state.rs
servo/components/style/error_reporting.rs
servo/components/style/font_face.rs
servo/components/style/lib.rs
servo/components/style/logical_geometry.rs
servo/components/style/media_queries.rs
servo/components/style/parallel.rs
servo/components/style/properties/longhand/background.mako.rs
servo/components/style/properties/longhand/border.mako.rs
servo/components/style/properties/longhand/box.mako.rs
servo/components/style/properties/longhand/column.mako.rs
servo/components/style/properties/longhand/counters.mako.rs
servo/components/style/properties/longhand/effects.mako.rs
servo/components/style/properties/longhand/font.mako.rs
servo/components/style/properties/longhand/inherited_box.mako.rs
servo/components/style/properties/longhand/inherited_table.mako.rs
servo/components/style/properties/longhand/inherited_text.mako.rs
servo/components/style/properties/longhand/list.mako.rs
servo/components/style/properties/longhand/outline.mako.rs
servo/components/style/properties/longhand/pointing.mako.rs
servo/components/style/properties/longhand/position.mako.rs
servo/components/style/properties/longhand/text.mako.rs
servo/components/style/properties/properties.mako.rs
servo/components/style/restyle_hints.rs
servo/components/style/selector_impl.rs
servo/components/style/selector_matching.rs
servo/components/style/stylesheets.rs
servo/components/style/traversal.rs
servo/components/style/values.rs
servo/components/style/viewport.rs
servo/components/style_traits/Cargo.toml
servo/components/style_traits/cursor.rs
servo/components/style_traits/lib.rs
servo/components/style_traits/values.rs
servo/components/style_traits/viewport.rs
servo/components/util/Cargo.toml
servo/components/util/geometry.rs
servo/components/util/lib.rs
servo/components/util/opts.rs
servo/components/util/prefs.rs
servo/components/util/thread.rs
servo/components/util/vec.rs
servo/ports/cef/Cargo.lock
servo/ports/geckolib/Cargo.lock
servo/ports/geckolib/Cargo.toml
servo/ports/geckolib/gecko_bindings/lib.rs
servo/ports/geckolib/gecko_bindings/ptr.rs
servo/ports/geckolib/lib.rs
servo/ports/geckolib/properties.mako.rs
servo/ports/geckolib/selector_impl.rs
servo/ports/geckolib/wrapper.rs
--- a/servo/components/gfx/Cargo.toml
+++ b/servo/components/gfx/Cargo.toml
@@ -8,17 +8,17 @@ publish = false
 [lib]
 name = "gfx"
 path = "lib.rs"
 
 [dependencies]
 app_units = {version = "0.2.3", features = ["plugins"]}
 azure = {git = "https://github.com/servo/rust-azure", features = ["plugins"]}
 bitflags = "0.7"
-euclid = {version = "0.6.4", features = ["plugins"]}
+euclid = {version = "0.6.4", features = ["plugins", "unstable"]}
 fnv = "1.0"
 gfx_traits = {path = "../gfx_traits"}
 harfbuzz-sys = "0.1"
 heapsize = "0.3.0"
 heapsize_plugin = "0.1.2"
 ipc-channel = {git = "https://github.com/servo/ipc-channel"}
 layers = {git = "https://github.com/servo/rust-layers", features = ["plugins"]}
 lazy_static = "0.2"
--- a/servo/components/gfx/display_list/mod.rs
+++ b/servo/components/gfx/display_list/mod.rs
@@ -15,17 +15,18 @@
 //! low-level drawing primitives.
 
 use app_units::Au;
 use azure::azure::AzFloat;
 use azure::azure_hl::Color;
 use euclid::approxeq::ApproxEq;
 use euclid::num::Zero;
 use euclid::rect::TypedRect;
-use euclid::{Matrix2D, Matrix4D, Point2D, Rect, SideOffsets2D, Size2D};
+use euclid::side_offsets::SideOffsets2D;
+use euclid::{Matrix2D, Matrix4D, Point2D, Rect, Size2D};
 use fnv::FnvHasher;
 use gfx_traits::{LayerId, ScrollPolicy, StackingContextId};
 use ipc_channel::ipc::IpcSharedMemory;
 use msg::constellation_msg::PipelineId;
 use net_traits::image::base::{Image, PixelFormat};
 use paint_context::PaintContext;
 use range::Range;
 use serde::de::{self, Deserialize, Deserializer, MapVisitor, Visitor};
--- a/servo/components/msg/Cargo.toml
+++ b/servo/components/msg/Cargo.toml
@@ -16,11 +16,11 @@ heapsize = "0.3.0"
 heapsize_plugin = "0.1.2"
 hyper = {version = "0.9", features = ["serde-serialization"]}
 ipc-channel = {git = "https://github.com/servo/ipc-channel"}
 layers = {git = "https://github.com/servo/rust-layers", features = ["plugins"]}
 plugins = {path = "../plugins"}
 rustc-serialize = "0.3.4"
 serde = "0.7"
 serde_macros = "0.7"
-url = {version = "1.0.0", features = ["heap_size"]}
-util = {path = "../util"}
+url = {version = "1.0.0", features = ["heap_size", "serde"]}
+util = {path = "../util", features = ["servo"]}
 webrender_traits = {git = "https://github.com/servo/webrender_traits"}
--- a/servo/components/profile/Cargo.toml
+++ b/servo/components/profile/Cargo.toml
@@ -6,17 +6,17 @@ publish = false
 
 [lib]
 name = "profile"
 path = "lib.rs"
 
 [dependencies]
 profile_traits = {path = "../profile_traits"}
 plugins = {path = "../plugins"}
-util = {path = "../util"}
+util = {path = "../util", features = ["servo"]}
 ipc-channel = {git = "https://github.com/servo/ipc-channel"}
 heartbeats-simple = "0.3"
 log = "0.3.5"
 serde = "0.7"
 serde_json = "0.7"
 serde_macros = "0.7"
 time = "0.1.12"
 
--- a/servo/components/script_traits/Cargo.toml
+++ b/servo/components/script_traits/Cargo.toml
@@ -10,17 +10,17 @@ path = "lib.rs"
 
 [dependencies]
 canvas_traits = {path = "../canvas_traits"}
 gfx_traits = {path = "../gfx_traits"}
 msg = {path = "../msg"}
 net_traits = {path = "../net_traits"}
 plugins = {path = "../plugins"}
 profile_traits = {path = "../profile_traits"}
-style_traits = {path = "../style_traits"}
+style_traits = {path = "../style_traits", features = ["servo"]}
 util = {path = "../util"}
 devtools_traits = {path = "../devtools_traits"}
 ipc-channel = {git = "https://github.com/servo/ipc-channel"}
 app_units = {version = "0.2.3", features = ["plugins"]}
 euclid = {version = "0.6.4", features = ["plugins"]}
 heapsize = "0.3.0"
 heapsize_plugin = "0.1.2"
 libc = "0.2"
--- a/servo/components/servo/Cargo.lock
+++ b/servo/components/servo/Cargo.lock
@@ -2210,17 +2210,16 @@ dependencies = [
  "euclid 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "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)",
  "lazy_static 0.2.1 (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)",
- "plugins 0.0.1",
  "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_macros 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.1.7 (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)",
@@ -2248,17 +2247,16 @@ dependencies = [
 [[package]]
 name = "style_traits"
 version = "0.0.1"
 dependencies = [
  "cssparser 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "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)",
- "plugins 0.0.1",
  "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_macros 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "util 0.0.1",
 ]
 
 [[package]]
 name = "task_info"
@@ -2433,25 +2431,23 @@ version = "0.0.1"
 dependencies = [
  "app_units 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "backtrace 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "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.2.3 (git+https://github.com/servo/ipc-channel)",
  "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.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 0.2.12 (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)",
  "serde 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_macros 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.1.7 (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)",
 ]
--- a/servo/components/servo/Cargo.toml
+++ b/servo/components/servo/Cargo.toml
@@ -54,17 +54,17 @@ msg = {path = "../msg"}
 profile = {path = "../profile"}
 profile_traits = {path = "../profile_traits"}
 util = {path = "../util"}
 script = {path = "../script"}
 script_traits = {path = "../script_traits"}
 layout = {path = "../layout"}
 layout_thread = {path = "../layout_thread"}
 gfx = {path = "../gfx"}
-style = {path = "../style"}
+style = {path = "../style", features = ["servo"]}
 canvas = {path = "../canvas"}
 canvas_traits = {path = "../canvas_traits"}
 devtools = {path = "../devtools"}
 webdriver_server = {path = "../webdriver_server", optional = true}
 devtools_traits = {path = "../devtools_traits"}
 glutin_app = {path = "../../ports/glutin"}
 ipc-channel = {git = "https://github.com/servo/ipc-channel"}
 gleam = "0.2"
--- a/servo/components/style/Cargo.toml
+++ b/servo/components/style/Cargo.toml
@@ -7,37 +7,41 @@ publish = false
 build = "build.rs"
 
 [lib]
 name = "style"
 path = "lib.rs"
 
 [features]
 gecko = ["gecko_bindings"]
+servo = ["serde", "serde/nightly", "serde_macros", "heapsize", "heapsize_plugin",
+         "style_traits/servo", "app_units/plugins", "euclid/plugins",
+         "cssparser/heap_size", "cssparser/serde-serialization",
+         "selectors/heap_size", "selectors/unstable", "string_cache/heap_size",
+         "url/heap_size"]
 
 [dependencies]
-app_units = {version = "0.2.3", features = ["plugins"]}
+app_units = "0.2.3"
 bitflags = "0.7"
-cssparser = {version = "0.5.5", features = ["heap_size", "serde-serialization"]}
+cssparser = "0.5.5"
 encoding = "0.2"
-euclid = {version = "0.6.4", features = ["plugins"]}
+euclid = "0.6.4"
 fnv = "1.0"
 gecko_bindings = {path = "../../ports/geckolib/gecko_bindings", optional = true}
-heapsize = "0.3.0"
-heapsize_plugin = "0.1.2"
+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"
-plugins = {path = "../plugins"}
 rustc-serialize = "0.3"
-selectors = {version = "0.6", features = ["heap_size", "unstable"]}
-serde = {version = "0.7", features = ["nightly"]}
-serde_macros = "0.7"
+selectors = "0.6"
+serde = {version = "0.7", optional = true}
+serde_macros = {version = "0.7", optional = true}
 smallvec = "0.1"
-string_cache = {version = "0.2.20", features = ["heap_size"]}
+string_cache = "0.2.20"
 style_traits = {path = "../style_traits"}
 time = "0.1"
-url = {version = "1.0.0", features = ["heap_size"]}
+url = "1.0.0"
 util = {path = "../util"}
 
 [build-dependencies]
 walkdir = "0.1"
--- a/servo/components/style/attr.rs
+++ b/servo/components/style/attr.rs
@@ -12,24 +12,26 @@ use string_cache::{Atom, Namespace};
 use url::Url;
 use util::str::{HTML_SPACE_CHARACTERS, read_exponent, read_fraction};
 use util::str::{read_numbers, split_commas, split_html_space_chars};
 use values::specified::Length;
 
 // Duplicated from script::dom::values.
 const UNSIGNED_LONG_MAX: u32 = 2147483647;
 
-#[derive(Clone, Copy, Debug, HeapSizeOf, PartialEq)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub enum LengthOrPercentageOrAuto {
     Auto,
     Percentage(f32),
     Length(Au),
 }
 
-#[derive(PartialEq, Clone, HeapSizeOf)]
+#[derive(PartialEq, Clone)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub enum AttrValue {
     String(String),
     TokenList(String, Vec<Atom>),
     UInt(String, u32),
     Int(String, i32),
     Double(String, f64),
     Atom(Atom),
     Length(String, Option<Length>),
@@ -533,15 +535,16 @@ pub fn parse_length(mut value: &str) -> 
     }
 
     match FromStr::from_str(value) {
         Ok(number) => LengthOrPercentageOrAuto::Length(Au::from_f64_px(number)),
         Err(_) => LengthOrPercentageOrAuto::Auto,
     }
 }
 
-#[derive(Clone, HeapSizeOf, Debug)]
+#[derive(Clone, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub struct AttrIdentifier {
     pub local_name: Atom,
     pub name: Atom,
     pub namespace: Namespace,
     pub prefix: Option<Atom>,
 }
--- a/servo/components/style/custom_properties.rs
+++ b/servo/components/style/custom_properties.rs
@@ -18,17 +18,18 @@ pub type Name = Atom;
 pub fn parse_name(s: &str) -> Result<&str, ()> {
     if s.starts_with("--") {
         Ok(&s[2..])
     } else {
         Err(())
     }
 }
 
-#[derive(Clone, PartialEq, Debug, HeapSizeOf)]
+#[derive(Clone, PartialEq, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub struct SpecifiedValue {
     css: String,
 
     first_token_type: TokenSerializationType,
     last_token_type: TokenSerializationType,
 
     /// Custom property names in var() functions.
     references: HashSet<Name>,
@@ -36,17 +37,18 @@ pub struct SpecifiedValue {
 
 pub struct BorrowedSpecifiedValue<'a> {
     css: &'a str,
     first_token_type: TokenSerializationType,
     last_token_type: TokenSerializationType,
     references: Option<&'a HashSet<Name>>,
 }
 
-#[derive(Clone, HeapSizeOf, Debug)]
+#[derive(Clone, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub struct ComputedValue {
     css: String,
     first_token_type: TokenSerializationType,
     last_token_type: TokenSerializationType,
 }
 
 impl ToCss for SpecifiedValue {
     fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
--- a/servo/components/style/data.rs
+++ b/servo/components/style/data.rs
@@ -28,17 +28,17 @@ impl<Impl, ConcreteComputedValues> Priva
             style: None,
             per_pseudo: HashMap::with_hasher(Default::default()),
             parallel: DomParallelInfo::new(),
         }
     }
 }
 
 /// Information that we need stored in each DOM node.
-#[derive(HeapSizeOf)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub struct DomParallelInfo {
     /// The number of children that still need work done.
     pub children_count: AtomicIsize,
 }
 
 impl DomParallelInfo {
     pub fn new() -> DomParallelInfo {
         DomParallelInfo {
--- a/servo/components/style/dom.rs
+++ b/servo/components/style/dom.rs
@@ -26,17 +26,18 @@ pub type UnsafeNode = (usize, usize);
 /// back into a non-opaque representation. The only safe operation that can be
 /// performed on this node is to compare it to another opaque handle or to another
 /// OpaqueNode.
 ///
 /// Layout and Graphics use this to safely represent nodes for comparison purposes.
 /// Because the script task's GC does not trace layout, node data cannot be safely stored in layout
 /// data structures. Also, layout code tends to be faster when the DOM is not being accessed, for
 /// locality reasons. Using `OpaqueNode` enforces this invariant.
-#[derive(Clone, PartialEq, Copy, Debug, HeapSizeOf, Hash, Eq, Deserialize, Serialize)]
+#[derive(Clone, PartialEq, Copy, Debug, Hash, Eq)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
 pub struct OpaqueNode(pub usize);
 
 impl OpaqueNode {
     /// Returns the address of this node, for debugging purposes.
     #[inline]
     pub fn id(&self) -> usize {
         self.0
     }
--- a/servo/components/style/element_state.rs
+++ b/servo/components/style/element_state.rs
@@ -1,15 +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/. */
 
 bitflags! {
     #[doc = "Event-based element states."]
-    #[derive(HeapSizeOf)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub flags ElementState: u16 {
         #[doc = "The mouse is down on this element. \
                  https://html.spec.whatwg.org/multipage/#selector-active \
                  FIXME(#7333): set/unset this when appropriate"]
         const IN_ACTIVE_STATE = 0x01,
         #[doc = "This element has focus. \
                  https://html.spec.whatwg.org/multipage/#selector-focus"]
         const IN_FOCUS_STATE = 0x02,
--- a/servo/components/style/error_reporting.rs
+++ b/servo/components/style/error_reporting.rs
@@ -15,11 +15,11 @@ impl ParseErrorReporter for StdoutErrorR
     fn report_error(&self, input: &mut Parser, position: SourcePosition, message: &str) {
          if log_enabled!(log::LogLevel::Info) {
              let location = input.source_location(position);
              info!("{}:{} {}", location.line, location.column, message)
          }
     }
 
     fn clone(&self) -> Box<ParseErrorReporter + Send + Sync> {
-        box StdoutErrorReporter
+        Box::new(StdoutErrorReporter)
     }
 }
--- a/servo/components/style/font_face.rs
+++ b/servo/components/style/font_face.rs
@@ -4,29 +4,32 @@
 
 use computed_values::font_family::FontFamily;
 use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser};
 use parser::{ParserContext, log_css_error};
 use properties::longhands::font_family::parse_one_family;
 use std::iter;
 use url::Url;
 
-#[derive(Clone, Debug, HeapSizeOf, PartialEq, Eq, Deserialize, Serialize)]
+#[derive(Clone, Debug, PartialEq, Eq)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
 pub enum Source {
     Url(UrlSource),
     Local(FontFamily),
 }
 
-#[derive(Clone, Debug, HeapSizeOf, PartialEq, Eq, Deserialize, Serialize)]
+#[derive(Clone, Debug, PartialEq, Eq)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
 pub struct UrlSource {
     pub url: Url,
     pub format_hints: Vec<String>,
 }
 
-#[derive(Debug, HeapSizeOf, PartialEq, Eq)]
+#[derive(Debug, PartialEq, Eq)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub struct FontFaceRule {
     pub family: FontFamily,
     pub sources: Vec<Source>,
 }
 
 pub fn parse_font_face_block(context: &ParserContext, input: &mut Parser)
                              -> Result<FontFaceRule, ()> {
     let mut family = None;
@@ -54,17 +57,18 @@ pub fn parse_font_face_block(context: &P
                 family: family,
                 sources: src,
             })
         }
         _ => Err(())
     }
 }
 
-#[derive(Clone, Debug, Deserialize, Serialize)]
+#[derive(Clone, Debug)]
+#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
 pub struct EffectiveSources(Vec<Source>);
 
 impl FontFaceRule {
     /// Returns the list of effective sources for that font-face, that is the
     /// sources which don't list any format hint, or the ones which list at
     /// least "truetype" or "opentype".
     pub fn effective_sources(&self) -> EffectiveSources {
         EffectiveSources(self.sources.iter().rev().filter(|source| {
--- a/servo/components/style/lib.rs
+++ b/servo/components/style/lib.rs
@@ -1,23 +1,20 @@
 /* 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/. */
 
-#![feature(box_syntax)]
-#![feature(box_patterns)]
-#![feature(concat_idents)]
+// FIXME: replace discriminant_value with per-enum methods that use `match`?
 #![feature(core_intrinsics)]
-#![feature(custom_attribute)]
-#![feature(custom_derive)]
-#![feature(plugin)]
 
-#![plugin(heapsize_plugin)]
-#![plugin(plugins)]
-#![plugin(serde_macros)]
+#![cfg_attr(feature = "servo", feature(custom_attribute))]
+#![cfg_attr(feature = "servo", feature(custom_derive))]
+#![cfg_attr(feature = "servo", feature(plugin))]
+#![cfg_attr(feature = "servo", plugin(heapsize_plugin))]
+#![cfg_attr(feature = "servo", plugin(serde_macros))]
 
 #![deny(unsafe_code)]
 
 #![recursion_limit = "500"]  // For match_ignore_ascii_case in PropertyDeclaration::parse
 
 extern crate app_units;
 #[allow(unused_extern_crates)]
 #[macro_use]
@@ -25,29 +22,29 @@ extern crate bitflags;
 extern crate core;
 #[macro_use]
 extern crate cssparser;
 extern crate encoding;
 extern crate euclid;
 extern crate fnv;
 #[cfg(feature = "gecko")]
 extern crate gecko_bindings;
-extern crate heapsize;
+#[cfg(feature = "servo")] extern crate heapsize;
 #[allow(unused_extern_crates)]
 #[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 rustc_serialize;
 extern crate selectors;
-extern crate serde;
+#[cfg(feature = "servo")] extern crate serde;
 extern crate smallvec;
 #[macro_use(atom, ns)] extern crate string_cache;
 #[macro_use]
 extern crate style_traits;
 extern crate time;
 extern crate url;
 extern crate util;
 
--- a/servo/components/style/logical_geometry.rs
+++ b/servo/components/style/logical_geometry.rs
@@ -1,33 +1,35 @@
 /* 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/. */
 
 //! Geometry in flow-relative space.
 
 use euclid::num::Zero;
-use euclid::{Point2D, Rect, SideOffsets2D, Size2D};
+use euclid::side_offsets::SideOffsets2D;
+use euclid::{Point2D, Rect, Size2D};
 use std::cmp::{max, min};
 use std::fmt::{self, Debug, Error, Formatter};
 use std::ops::{Add, Sub};
 
 pub enum BlockFlowDirection {
     TopToBottom,
     RightToLeft,
     LeftToRight
 }
 
 pub enum InlineBaseDirection {
     LeftToRight,
     RightToLeft
 }
 
 bitflags!(
-    #[derive(HeapSizeOf, RustcEncodable)]
+    #[derive(RustcEncodable)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub flags WritingMode: u8 {
         const FLAG_RTL = 1 << 0,
         const FLAG_VERTICAL = 1 << 1,
         const FLAG_VERTICAL_LR = 1 << 2,
         const FLAG_SIDEWAYS_LEFT = 1 << 3
     }
 );
 
--- a/servo/components/style/media_queries.rs
+++ b/servo/components/style/media_queries.rs
@@ -5,22 +5,24 @@
 use app_units::Au;
 use cssparser::{Delimiter, Parser, Token};
 use euclid::size::{Size2D, TypedSize2D};
 use properties::longhands;
 use util::geometry::ViewportPx;
 use values::specified;
 
 
-#[derive(Debug, HeapSizeOf, PartialEq)]
+#[derive(Debug, PartialEq)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub struct MediaQueryList {
     pub media_queries: Vec<MediaQuery>
 }
 
-#[derive(PartialEq, Eq, Copy, Clone, Debug, HeapSizeOf)]
+#[derive(PartialEq, Eq, Copy, Clone, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub enum Range<T> {
     Min(T),
     Max(T),
     //Eq(T),    // FIXME: Implement parsing support for equality then re-enable this.
 }
 
 impl Range<specified::Length> {
     fn to_computed_range(&self, viewport_size: Size2D<Au>) -> Range<Au> {
@@ -53,30 +55,33 @@ impl<T: Ord> Range<T> {
             Range::Min(ref width) => { value >= *width },
             Range::Max(ref width) => { value <= *width },
             //Range::Eq(ref width) => { value == *width },
         }
     }
 }
 
 /// http://dev.w3.org/csswg/mediaqueries-3/#media1
-#[derive(PartialEq, Copy, Clone, Debug, HeapSizeOf)]
+#[derive(PartialEq, Copy, Clone, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub enum Expression {
     /// http://dev.w3.org/csswg/mediaqueries-3/#width
     Width(Range<specified::Length>),
 }
 
 /// http://dev.w3.org/csswg/mediaqueries-3/#media0
-#[derive(PartialEq, Eq, Copy, Clone, Debug, HeapSizeOf)]
+#[derive(PartialEq, Eq, Copy, Clone, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub enum Qualifier {
     Only,
     Not,
 }
 
-#[derive(Debug, HeapSizeOf, PartialEq)]
+#[derive(Debug, PartialEq)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub struct MediaQuery {
     pub qualifier: Option<Qualifier>,
     pub media_type: MediaQueryType,
     pub expressions: Vec<Expression>,
 }
 
 impl MediaQuery {
     pub fn new(qualifier: Option<Qualifier>, media_type: MediaQueryType,
@@ -85,30 +90,33 @@ impl MediaQuery {
             qualifier: qualifier,
             media_type: media_type,
             expressions: expressions,
         }
     }
 }
 
 /// http://dev.w3.org/csswg/mediaqueries-3/#media0
-#[derive(PartialEq, Eq, Copy, Clone, Debug, HeapSizeOf)]
+#[derive(PartialEq, Eq, Copy, Clone, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub enum MediaQueryType {
     All,  // Always true
     MediaType(MediaType),
 }
 
-#[derive(PartialEq, Eq, Copy, Clone, Debug, HeapSizeOf)]
+#[derive(PartialEq, Eq, Copy, Clone, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub enum MediaType {
     Screen,
     Print,
     Unknown,
 }
 
-#[derive(Debug, HeapSizeOf)]
+#[derive(Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub struct Device {
     pub media_type: MediaType,
     pub viewport_size: TypedSize2D<ViewportPx, f32>,
 }
 
 impl Device {
     pub fn new(media_type: MediaType, viewport_size: TypedSize2D<ViewportPx, f32>) -> Device {
         Device {
--- a/servo/components/style/parallel.rs
+++ b/servo/components/style/parallel.rs
@@ -12,17 +12,17 @@ use dom::{OpaqueNode, TNode, UnsafeNode}
 use std::mem;
 use std::sync::atomic::Ordering;
 use traversal::DomTraversalContext;
 use util::workqueue::{WorkQueue, WorkUnit, WorkerProxy};
 
 #[allow(dead_code)]
 fn static_assertion(node: UnsafeNode) {
     unsafe {
-        let _: UnsafeNodeList = ::std::intrinsics::transmute(node);
+        let _: UnsafeNodeList = mem::transmute(node);
     }
 }
 
 pub type UnsafeNodeList = (Box<Vec<UnsafeNode>>, OpaqueNode);
 
 pub const CHUNK_SIZE: usize = 64;
 
 pub struct WorkQueueData(usize, usize);
@@ -41,17 +41,17 @@ pub fn run_queue_with_custom_work_data_t
 
 pub fn traverse_dom<N, C>(root: N,
                           queue_data: &C::SharedContext,
                           queue: &mut WorkQueue<C::SharedContext, WorkQueueData>)
                           where N: TNode, C: DomTraversalContext<N> {
     run_queue_with_custom_work_data_type(queue, |queue| {
         queue.push(WorkUnit {
             fun:  top_down_dom::<N, C>,
-            data: (box vec![root.to_unsafe()], root.opaque()),
+            data: (Box::new(vec![root.to_unsafe()]), root.opaque()),
         });
     }, queue_data);
 }
 
 /// A parallel top-down DOM traversal.
 #[inline(always)]
 fn top_down_dom<N, C>(unsafe_nodes: UnsafeNodeList,
                       proxy: &mut WorkerProxy<C::SharedContext, UnsafeNodeList>)
@@ -84,17 +84,17 @@ fn top_down_dom<N, C>(unsafe_nodes: Unsa
             // If there were no more children, start walking back up.
             bottom_up_dom::<N, C>(unsafe_nodes.1, unsafe_node, proxy)
         }
     }
 
     for chunk in discovered_child_nodes.chunks(CHUNK_SIZE) {
         proxy.push(WorkUnit {
             fun:  top_down_dom::<N, C>,
-            data: (box chunk.iter().cloned().collect(), unsafe_nodes.1),
+            data: (Box::new(chunk.iter().cloned().collect()), unsafe_nodes.1),
         });
     }
 }
 
 /// Process current node and potentially traverse its ancestors.
 ///
 /// If we are the last child that finished processing, recursively process
 /// our parent. Else, stop. Also, stop at the root.
--- a/servo/components/style/properties/longhand/background.mako.rs
+++ b/servo/components/style/properties/longhand/background.mako.rs
@@ -12,32 +12,34 @@
 <%helpers:longhand name="background-image">
     use cssparser::ToCss;
     use std::fmt;
     use values::specified::Image;
     use values::LocalToCss;
 
     pub mod computed_value {
         use values::computed;
-        #[derive(Debug, Clone, PartialEq, HeapSizeOf)]
+        #[derive(Debug, Clone, PartialEq)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct T(pub Option<computed::Image>);
     }
 
     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("none"),
                 Some(computed::Image::Url(ref url)) => url.to_css(dest),
                 Some(computed::Image::LinearGradient(ref gradient)) =>
                     gradient.to_css(dest)
             }
         }
     }
 
-    #[derive(Debug, Clone, PartialEq, HeapSizeOf)]
+    #[derive(Debug, Clone, PartialEq)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct SpecifiedValue(pub Option<Image>);
 
     impl ToCss for SpecifiedValue {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             match *self {
                 SpecifiedValue(Some(ref image)) => image.to_css(dest),
                 SpecifiedValue(None) => dest.write_str("none"),
             }
@@ -72,24 +74,26 @@
 <%helpers:longhand name="background-position">
         use cssparser::ToCss;
         use std::fmt;
         use values::AuExtensionMethods;
 
         pub mod computed_value {
             use values::computed::LengthOrPercentage;
 
-            #[derive(PartialEq, Copy, Clone, Debug, HeapSizeOf)]
+            #[derive(PartialEq, Copy, Clone, Debug)]
+            #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
             pub struct T {
                 pub horizontal: LengthOrPercentage,
                 pub vertical: LengthOrPercentage,
             }
         }
 
-        #[derive(Debug, Clone, PartialEq, Copy, HeapSizeOf)]
+        #[derive(Debug, Clone, PartialEq, Copy)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct SpecifiedValue {
             pub horizontal: specified::LengthOrPercentage,
             pub vertical: specified::LengthOrPercentage,
         }
 
         impl ToCss for SpecifiedValue {
             fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
                 try!(self.horizontal.to_css(dest));
@@ -193,23 +197,25 @@
 <%helpers:longhand name="background-size">
     use cssparser::{ToCss, Token};
     use std::ascii::AsciiExt;
     use std::fmt;
 
     pub mod computed_value {
         use values::computed::LengthOrPercentageOrAuto;
 
-        #[derive(PartialEq, Clone, Debug, HeapSizeOf)]
+        #[derive(PartialEq, Clone, Debug)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct ExplicitSize {
             pub width: LengthOrPercentageOrAuto,
             pub height: LengthOrPercentageOrAuto,
         }
 
-        #[derive(PartialEq, Clone, Debug, HeapSizeOf)]
+        #[derive(PartialEq, Clone, Debug)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub enum T {
             Explicit(ExplicitSize),
             Cover,
             Contain,
         }
     }
 
     impl ToCss for computed_value::T {
@@ -217,17 +223,18 @@
             match *self {
                 computed_value::T::Explicit(ref size) => size.to_css(dest),
                 computed_value::T::Cover => dest.write_str("cover"),
                 computed_value::T::Contain => dest.write_str("contain"),
             }
         }
     }
 
-    #[derive(Clone, PartialEq, Debug, HeapSizeOf)]
+    #[derive(Clone, PartialEq, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct SpecifiedExplicitSize {
         pub width: specified::LengthOrPercentageOrAuto,
         pub height: specified::LengthOrPercentageOrAuto,
     }
 
     impl ToCss for SpecifiedExplicitSize {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             try!(self.width.to_css(dest));
@@ -240,17 +247,18 @@
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             try!(self.width.to_css(dest));
             try!(dest.write_str(" "));
             self.height.to_css(dest)
         }
     }
 
 
-    #[derive(Clone, PartialEq, Debug, HeapSizeOf)]
+    #[derive(Clone, PartialEq, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum SpecifiedValue {
         Explicit(SpecifiedExplicitSize),
         Cover,
         Contain,
     }
 
     impl ToCss for SpecifiedValue {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
--- a/servo/components/style/properties/longhand/border.mako.rs
+++ b/servo/components/style/properties/longhand/border.mako.rs
@@ -29,17 +29,18 @@
             }
         }
 
         #[inline]
         pub fn parse(_context: &ParserContext, input: &mut Parser)
                                -> Result<SpecifiedValue, ()> {
             specified::parse_border_width(input).map(SpecifiedValue)
         }
-        #[derive(Debug, Clone, PartialEq, HeapSizeOf)]
+        #[derive(Debug, Clone, PartialEq)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct SpecifiedValue(pub specified::Length);
         pub mod computed_value {
             use app_units::Au;
             pub type T = Au;
         }
         #[inline] pub fn get_initial_value() -> computed_value::T {
             Au::from_px(3)  // medium
         }
--- a/servo/components/style/properties/longhand/box.mako.rs
+++ b/servo/components/style/properties/longhand/box.mako.rs
@@ -23,18 +23,18 @@
             values += "-moz-box -moz-inline-box".split()
         experimental_values = set("flex".split())
     %>
     pub use self::computed_value::T as SpecifiedValue;
     use values::computed::{Context, ComputedValueAsSpecified};
 
     pub mod computed_value {
         #[allow(non_camel_case_types)]
-        #[derive(Clone, Eq, PartialEq, Copy, Hash, RustcEncodable, Debug, HeapSizeOf)]
-        #[derive(Deserialize, Serialize)]
+        #[derive(Clone, Eq, PartialEq, Copy, Hash, RustcEncodable, Debug)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
         pub enum T {
             % for value in values:
                 ${to_rust_ident(value)},
             % endfor
         }
 
         impl ::cssparser::ToCss for T {
             fn to_css<W>(&self, dest: &mut W) -> ::std::fmt::Result
@@ -131,17 +131,18 @@
 
   <% vertical_align = data.longhands_by_name["vertical-align"] %>
   <% vertical_align.keyword = Keyword("vertical-align",
                                       "baseline sub super top text-top middle bottom text-bottom",
                                       extra_gecko_values="middle-with-baseline") %>
   <% vertical_align_keywords = vertical_align.keyword.values_for(product) %>
 
   #[allow(non_camel_case_types)]
-  #[derive(Debug, Clone, PartialEq, Copy, HeapSizeOf)]
+  #[derive(Debug, Clone, PartialEq, Copy)]
+  #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
   pub enum SpecifiedValue {
       % for keyword in vertical_align_keywords:
           ${to_rust_ident(keyword)},
       % endfor
       LengthOrPercentage(specified::LengthOrPercentage),
   }
 
   impl ToCss for SpecifiedValue {
@@ -169,17 +170,18 @@
       })
   }
   pub mod computed_value {
       use app_units::Au;
       use std::fmt;
       use values::AuExtensionMethods;
       use values::{CSSFloat, computed};
       #[allow(non_camel_case_types)]
-      #[derive(PartialEq, Copy, Clone, HeapSizeOf, Debug)]
+      #[derive(PartialEq, Copy, Clone, Debug)]
+      #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
       pub enum T {
           % for keyword in vertical_align_keywords:
               ${to_rust_ident(keyword)},
           % endfor
           LengthOrPercentage(computed::LengthOrPercentage),
       }
       impl ::cssparser::ToCss for T {
           fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
@@ -238,17 +240,18 @@
 
   impl ToCss for SpecifiedValue {
       fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
           self.0.to_css(dest)
       }
   }
 
   pub mod computed_value {
-      #[derive(Debug, Clone, Copy, PartialEq, HeapSizeOf)]
+      #[derive(Debug, Clone, Copy, PartialEq)]
+      #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
       pub struct T(pub super::super::overflow_x::computed_value::T);
   }
 
   impl ToComputedValue for SpecifiedValue {
       type ComputedValue = computed_value::T;
 
       #[inline]
       fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
@@ -274,17 +277,18 @@
 
     pub mod computed_value {
         use cssparser::ToCss;
         use std::fmt;
         use values::computed::{TContext, ToComputedValue};
 
         pub use values::computed::Time as SingleComputedValue;
 
-        #[derive(Debug, Clone, PartialEq, HeapSizeOf)]
+        #[derive(Debug, Clone, PartialEq)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct T(pub Vec<SingleComputedValue>);
 
         impl ToComputedValue for T {
             type ComputedValue = T;
 
             #[inline]
             fn to_computed_value<Cx: TContext>(&self, _: &Cx) -> T {
                 (*self).clone()
@@ -380,17 +384,18 @@
 
     pub mod computed_value {
         use cssparser::ToCss;
         use euclid::point::Point2D;
         use std::fmt;
 
         pub use self::TransitionTimingFunction as SingleComputedValue;
 
-        #[derive(Copy, Clone, Debug, PartialEq, HeapSizeOf)]
+        #[derive(Copy, Clone, Debug, PartialEq)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub enum TransitionTimingFunction {
             CubicBezier(Point2D<f32>, Point2D<f32>),
             Steps(u32, StartEnd),
         }
 
         impl ToCss for TransitionTimingFunction {
             fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
                 match *self {
@@ -411,32 +416,34 @@
                         try!(dest.write_str(", "));
                         try!(start_end.to_css(dest));
                         dest.write_str(")")
                     }
                 }
             }
         }
 
-        #[derive(Copy, Clone, Debug, PartialEq, HeapSizeOf)]
+        #[derive(Copy, Clone, Debug, PartialEq)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub enum StartEnd {
             Start,
             End,
         }
 
         impl ToCss for StartEnd {
             fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
                 match *self {
                     StartEnd::Start => dest.write_str("start"),
                     StartEnd::End => dest.write_str("end"),
                 }
             }
         }
 
-        #[derive(Clone, Debug, PartialEq, HeapSizeOf)]
+        #[derive(Clone, Debug, PartialEq)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct T(pub Vec<TransitionTimingFunction>);
 
         impl ToCss for T {
             fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
                 if self.0.is_empty() {
                     return dest.write_str("none")
                 }
                 for (i, value) in self.0.iter().enumerate() {
@@ -532,17 +539,18 @@
     pub use self::computed_value::T as SpecifiedValue;
 
     pub mod computed_value {
         use cssparser::ToCss;
         use std::fmt;
 
         pub use self::TransitionProperty as SingleComputedValue;
 
-        #[derive(Copy, Clone, Debug, PartialEq, HeapSizeOf)]
+        #[derive(Copy, Clone, Debug, PartialEq)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub enum TransitionProperty {
             All,
             BackgroundColor,
             BackgroundPosition,
             BorderBottomColor,
             BorderBottomWidth,
             BorderLeftColor,
             BorderLeftWidth,
@@ -683,17 +691,18 @@
                     TransitionProperty::Visibility => dest.write_str("visibility"),
                     TransitionProperty::Width => dest.write_str("width"),
                     TransitionProperty::WordSpacing => dest.write_str("word-spacing"),
                     TransitionProperty::ZIndex => dest.write_str("z-index"),
                 }
             }
         }
 
-        #[derive(Clone, Debug, PartialEq, HeapSizeOf)]
+        #[derive(Clone, Debug, PartialEq)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct T(pub Vec<SingleComputedValue>);
 
         impl ToCss for T {
             fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
                 if self.0.is_empty() {
                     return dest.write_str("none")
                 }
                 for (i, value) in self.0.iter().enumerate() {
@@ -858,24 +867,26 @@
 // Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-binding
 <%helpers:longhand name="-moz-binding" products="gecko">
     use cssparser::{CssStringWriter, ToCss};
     use gecko_bindings::ptr::{GeckoArcPrincipal, GeckoArcURI};
     use std::fmt::{self, Write};
     use url::Url;
     use values::computed::ComputedValueAsSpecified;
 
-    #[derive(PartialEq, Clone, Debug, HeapSizeOf)]
+    #[derive(PartialEq, Clone, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct UrlExtraData {
         pub base: GeckoArcURI,
         pub referrer: GeckoArcURI,
         pub principal: GeckoArcPrincipal,
     }
 
-    #[derive(PartialEq, Clone, Debug, HeapSizeOf)]
+    #[derive(PartialEq, Clone, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum SpecifiedValue {
         Url(Url, UrlExtraData),
         None,
     }
 
     impl ComputedValueAsSpecified for SpecifiedValue {}
 
     impl ToCss for SpecifiedValue {
--- a/servo/components/style/properties/longhand/column.mako.rs
+++ b/servo/components/style/properties/longhand/column.mako.rs
@@ -6,34 +6,36 @@
 
 <% data.new_style_struct("Column", inherited=False) %>
 
 <%helpers:longhand name="column-width" experimental="True">
     use cssparser::ToCss;
     use std::fmt;
     use values::AuExtensionMethods;
 
-    #[derive(Debug, Clone, Copy, PartialEq, HeapSizeOf)]
+    #[derive(Debug, Clone, Copy, PartialEq)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum SpecifiedValue {
         Auto,
         Specified(specified::Length),
     }
 
     impl ToCss for SpecifiedValue {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             match *self {
                 SpecifiedValue::Auto => dest.write_str("auto"),
                 SpecifiedValue::Specified(l) => l.to_css(dest),
             }
         }
     }
 
     pub mod computed_value {
         use app_units::Au;
-        #[derive(Debug, Clone, PartialEq, HeapSizeOf)]
+        #[derive(Debug, Clone, PartialEq)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct T(pub Option<Au>);
     }
 
     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("auto"),
                 Some(l) => l.to_css(dest),
@@ -67,33 +69,35 @@
         }
     }
 </%helpers:longhand>
 
 <%helpers:longhand name="column-count" experimental="True">
     use cssparser::ToCss;
     use std::fmt;
 
-    #[derive(Debug, Clone, Copy, PartialEq, HeapSizeOf)]
+    #[derive(Debug, Clone, Copy, PartialEq)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum SpecifiedValue {
         Auto,
         Specified(u32),
     }
 
     impl ToCss for SpecifiedValue {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             match *self {
                 SpecifiedValue::Auto => dest.write_str("auto"),
                 SpecifiedValue::Specified(count) => write!(dest, "{}", count),
             }
         }
     }
 
     pub mod computed_value {
-        #[derive(Debug, Clone, PartialEq, HeapSizeOf)]
+        #[derive(Debug, Clone, PartialEq)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct T(pub Option<u32>);
     }
 
     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("auto"),
                 Some(count) => write!(dest, "{}", count),
@@ -133,34 +137,36 @@
     }
 </%helpers:longhand>
 
 <%helpers:longhand name="column-gap" experimental="True">
     use cssparser::ToCss;
     use std::fmt;
     use values::AuExtensionMethods;
 
-    #[derive(Debug, Clone, Copy, PartialEq, HeapSizeOf)]
+    #[derive(Debug, Clone, Copy, PartialEq)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum SpecifiedValue {
         Normal,
         Specified(specified::Length),
     }
 
     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;
-        #[derive(Debug, Clone, PartialEq, HeapSizeOf)]
+        #[derive(Debug, Clone, PartialEq)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct T(pub Option<Au>);
     }
 
     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),
--- a/servo/components/style/properties/longhand/counters.mako.rs
+++ b/servo/components/style/properties/longhand/counters.mako.rs
@@ -19,17 +19,18 @@
     impl ComputedValueAsSpecified for SpecifiedValue {}
 
     pub mod computed_value {
         use super::super::list_style_type;
 
         use cssparser::{self, ToCss};
         use std::fmt;
 
-        #[derive(Debug, PartialEq, Eq, Clone, HeapSizeOf)]
+        #[derive(Debug, PartialEq, Eq, Clone)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub enum ContentItem {
             /// Literal string content.
             String(String),
             /// `counter(name, style)`.
             Counter(String, list_style_type::computed_value::T),
             /// `counters(name, separator, style)`.
             Counters(String, String, list_style_type::computed_value::T),
             /// `open-quote`.
@@ -68,17 +69,18 @@
                     ContentItem::CloseQuote => dest.write_str("close-quote"),
                     ContentItem::NoOpenQuote => dest.write_str("no-open-quote"),
                     ContentItem::NoCloseQuote => dest.write_str("no-close-quote"),
                 }
             }
         }
 
         #[allow(non_camel_case_types)]
-        #[derive(Debug, PartialEq, Eq, Clone, HeapSizeOf)]
+        #[derive(Debug, PartialEq, Eq, Clone)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub enum T {
             normal,
             none,
             Content(Vec<ContentItem>),
         }
 
         impl ToCss for T {
             fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
@@ -175,17 +177,18 @@
     use values::computed::ComputedValueAsSpecified;
 
     use cssparser::{ToCss, Token, serialize_identifier};
     use std::borrow::{Cow, ToOwned};
 
     pub use self::computed_value::T as SpecifiedValue;
 
     pub mod computed_value {
-        #[derive(Debug, Clone, PartialEq, HeapSizeOf)]
+        #[derive(Debug, Clone, PartialEq)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct T(pub Vec<(String,i32)>);
     }
 
     #[inline]
     pub fn get_initial_value() -> computed_value::T {
         computed_value::T(Vec::new())
     }
 
--- a/servo/components/style/properties/longhand/effects.mako.rs
+++ b/servo/components/style/properties/longhand/effects.mako.rs
@@ -11,20 +11,22 @@
                           "Opacity",
                           "1.0")}
 
 <%helpers:longhand name="box-shadow">
     use cssparser::{self, ToCss};
     use std::fmt;
     use values::AuExtensionMethods;
 
-    #[derive(Debug, Clone, PartialEq, HeapSizeOf)]
+    #[derive(Debug, Clone, PartialEq)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct SpecifiedValue(Vec<SpecifiedBoxShadow>);
 
-    #[derive(Debug, Clone, PartialEq, HeapSizeOf)]
+    #[derive(Debug, Clone, PartialEq)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct SpecifiedBoxShadow {
         pub offset_x: specified::Length,
         pub offset_y: specified::Length,
         pub blur_radius: specified::Length,
         pub spread_radius: specified::Length,
         pub color: Option<specified::CSSColor>,
         pub inset: bool,
     }
@@ -67,20 +69,22 @@
         }
     }
 
     pub mod computed_value {
         use app_units::Au;
         use std::fmt;
         use values::computed;
 
-        #[derive(Clone, PartialEq, HeapSizeOf, Debug)]
+        #[derive(Clone, PartialEq, Debug)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct T(pub Vec<BoxShadow>);
 
-        #[derive(Clone, PartialEq, Copy, HeapSizeOf, Debug)]
+        #[derive(Clone, PartialEq, Copy, Debug)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct BoxShadow {
             pub offset_x: Au,
             pub offset_y: Au,
             pub blur_radius: Au,
             pub spread_radius: Au,
             pub color: computed::CSSColor,
             pub inset: bool,
         }
@@ -224,25 +228,27 @@
     use std::fmt;
     use values::AuExtensionMethods;
 
     // NB: `top` and `left` are 0 if `auto` per CSS 2.1 11.1.2.
 
     pub mod computed_value {
         use app_units::Au;
 
-        #[derive(Clone, PartialEq, Eq, Copy, Debug, HeapSizeOf)]
+        #[derive(Clone, PartialEq, Eq, Copy, Debug)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct ClipRect {
             pub top: Au,
             pub right: Option<Au>,
             pub bottom: Option<Au>,
             pub left: Au,
         }
 
-        #[derive(Debug, Clone, PartialEq, HeapSizeOf)]
+        #[derive(Debug, Clone, PartialEq)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct T(pub Option<ClipRect>);
     }
 
     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("auto"),
                 Some(rect) => {
@@ -266,25 +272,27 @@
                     try!(rect.left.to_css(dest));
                     try!(dest.write_str(")"));
                     Ok(())
                 }
             }
         }
     }
 
-    #[derive(Clone, Debug, PartialEq, Copy, HeapSizeOf)]
+    #[derive(Clone, Debug, PartialEq, Copy)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct SpecifiedClipRect {
         pub top: specified::Length,
         pub right: Option<specified::Length>,
         pub bottom: Option<specified::Length>,
         pub left: specified::Length,
     }
 
-    #[derive(Clone, Debug, PartialEq, Copy, HeapSizeOf)]
+    #[derive(Clone, Debug, PartialEq, Copy)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct SpecifiedValue(Option<SpecifiedClipRect>);
 
     impl ToCss for SpecifiedClipRect {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             try!(dest.write_str("rect("));
 
             try!(self.top.to_css(dest));
             try!(dest.write_str(", "));
@@ -389,21 +397,23 @@
 <%helpers:longhand name="filter">
     //pub use self::computed_value::T as SpecifiedValue;
     use cssparser::ToCss;
     use std::fmt;
     use values::AuExtensionMethods;
     use values::CSSFloat;
     use values::specified::{Angle, Length};
 
-    #[derive(Debug, Clone, PartialEq, HeapSizeOf)]
+    #[derive(Debug, Clone, PartialEq)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct SpecifiedValue(Vec<SpecifiedFilter>);
 
     // TODO(pcwalton): `drop-shadow`
-    #[derive(Clone, PartialEq, Debug, HeapSizeOf)]
+    #[derive(Clone, PartialEq, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum SpecifiedFilter {
         Blur(Length),
         Brightness(CSSFloat),
         Contrast(CSSFloat),
         Grayscale(CSSFloat),
         HueRotate(Angle),
         Invert(CSSFloat),
         Opacity(CSSFloat),
@@ -411,30 +421,32 @@
         Sepia(CSSFloat),
     }
 
     pub mod computed_value {
         use app_units::Au;
         use values::CSSFloat;
         use values::specified::{Angle};
 
-        #[derive(Clone, PartialEq, Debug, HeapSizeOf, Deserialize, Serialize)]
+        #[derive(Clone, PartialEq, Debug)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
         pub enum Filter {
             Blur(Au),
             Brightness(CSSFloat),
             Contrast(CSSFloat),
             Grayscale(CSSFloat),
             HueRotate(Angle),
             Invert(CSSFloat),
             Opacity(CSSFloat),
             Saturate(CSSFloat),
             Sepia(CSSFloat),
         }
 
-        #[derive(Clone, PartialEq, Debug, HeapSizeOf, Deserialize, Serialize)]
+        #[derive(Clone, PartialEq, Debug)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
         pub struct T { pub filters: Vec<Filter> }
 
         impl T {
             /// Creates a new filter pipeline.
             #[inline]
             pub fn new(filters: Vec<Filter>) -> T {
                 T
                 {
@@ -624,17 +636,18 @@
 
     use cssparser::ToCss;
     use std::fmt;
 
     pub mod computed_value {
         use values::CSSFloat;
         use values::computed;
 
-        #[derive(Clone, Copy, Debug, PartialEq, HeapSizeOf)]
+        #[derive(Clone, Copy, Debug, PartialEq)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct ComputedMatrix {
             pub m11: CSSFloat, pub m12: CSSFloat, pub m13: CSSFloat, pub m14: CSSFloat,
             pub m21: CSSFloat, pub m22: CSSFloat, pub m23: CSSFloat, pub m24: CSSFloat,
             pub m31: CSSFloat, pub m32: CSSFloat, pub m33: CSSFloat, pub m34: CSSFloat,
             pub m41: CSSFloat, pub m42: CSSFloat, pub m43: CSSFloat, pub m44: CSSFloat,
         }
 
         impl ComputedMatrix {
@@ -643,29 +656,31 @@
                     m11: 1.0, m12: 0.0, m13: 0.0, m14: 0.0,
                     m21: 0.0, m22: 1.0, m23: 0.0, m24: 0.0,
                     m31: 0.0, m32: 0.0, m33: 1.0, m34: 0.0,
                     m41: 0.0, m42: 0.0, m43: 0.0, m44: 1.0
                 }
             }
         }
 
-        #[derive(Clone, Debug, PartialEq, HeapSizeOf)]
+        #[derive(Clone, Debug, PartialEq)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub enum ComputedOperation {
             Matrix(ComputedMatrix),
             Skew(computed::Angle, computed::Angle),
             Translate(computed::LengthOrPercentage,
                       computed::LengthOrPercentage,
                       computed::Length),
             Scale(CSSFloat, CSSFloat, CSSFloat),
             Rotate(CSSFloat, CSSFloat, CSSFloat, computed::Angle),
             Perspective(computed::Length),
         }
 
-        #[derive(Clone, Debug, PartialEq, HeapSizeOf)]
+        #[derive(Clone, Debug, PartialEq)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct T(pub Option<Vec<ComputedOperation>>);
     }
 
     pub use self::computed_value::ComputedMatrix as SpecifiedMatrix;
 
     fn parse_two_lengths_or_percentages(input: &mut Parser)
                                         -> Result<(specified::LengthOrPercentage,
                                                    specified::LengthOrPercentage),()> {
@@ -690,26 +705,28 @@
         let first = try!(specified::Angle::parse(input));
         let second = input.try(|input| {
             try!(input.expect_comma());
             specified::Angle::parse(input)
         }).unwrap_or(specified::Angle(0.0));
         Ok((first, second))
     }
 
-    #[derive(Copy, Clone, Debug, PartialEq, HeapSizeOf)]
+    #[derive(Copy, Clone, Debug, PartialEq)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     enum TranslateKind {
         Translate,
         TranslateX,
         TranslateY,
         TranslateZ,
         Translate3D,
     }
 
-    #[derive(Clone, Debug, PartialEq, HeapSizeOf)]
+    #[derive(Clone, Debug, PartialEq)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     enum SpecifiedOperation {
         Matrix(SpecifiedMatrix),
         Skew(specified::Angle, specified::Angle),
         Translate(TranslateKind,
                   specified::LengthOrPercentage,
                   specified::LengthOrPercentage,
                   specified::Length),
         Scale(CSSFloat, CSSFloat, CSSFloat),
@@ -778,17 +795,18 @@
                 }
                 SpecifiedOperation::Perspective(_p) => {
                     Ok(())
                 }
             }
         }
     }
 
-    #[derive(Clone, Debug, PartialEq, HeapSizeOf)]
+    #[derive(Clone, Debug, PartialEq)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct SpecifiedValue(Vec<SpecifiedOperation>);
 
     impl ToCss for SpecifiedValue {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             let mut first = true;
             for operation in &self.0 {
                 if !first {
                     try!(dest.write_str(" "));
@@ -1168,25 +1186,27 @@ pub fn parse_origin(_: &ParserContext, i
     use values::specified::{Length, LengthOrPercentage, Percentage};
 
     use cssparser::ToCss;
     use std::fmt;
 
     pub mod computed_value {
         use values::computed::{Length, LengthOrPercentage};
 
-        #[derive(Clone, Copy, Debug, PartialEq, HeapSizeOf)]
+        #[derive(Clone, Copy, Debug, PartialEq)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct T {
             pub horizontal: LengthOrPercentage,
             pub vertical: LengthOrPercentage,
             pub depth: Length,
         }
     }
 
-    #[derive(Clone, Copy, Debug, PartialEq, HeapSizeOf)]
+    #[derive(Clone, Copy, Debug, PartialEq)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct SpecifiedValue {
         horizontal: LengthOrPercentage,
         vertical: LengthOrPercentage,
         depth: Length,
     }
 
     impl ToCss for computed_value::T {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
@@ -1248,32 +1268,34 @@ pub fn parse_origin(_: &ParserContext, i
     use values::specified::{LengthOrPercentage, Percentage};
 
     use cssparser::ToCss;
     use std::fmt;
 
     pub mod computed_value {
         use values::computed::LengthOrPercentage;
 
-        #[derive(Clone, Copy, Debug, PartialEq, HeapSizeOf)]
+        #[derive(Clone, Copy, Debug, PartialEq)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct T {
             pub horizontal: LengthOrPercentage,
             pub vertical: LengthOrPercentage,
         }
     }
 
     impl ToCss for computed_value::T {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             try!(self.horizontal.to_css(dest));
             try!(dest.write_str(" "));
             self.vertical.to_css(dest)
         }
     }
 
-    #[derive(Clone, Copy, Debug, PartialEq, HeapSizeOf)]
+    #[derive(Clone, Copy, Debug, PartialEq)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct SpecifiedValue {
         horizontal: LengthOrPercentage,
         vertical: LengthOrPercentage,
     }
 
     impl ToCss for SpecifiedValue {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             try!(self.horizontal.to_css(dest));
--- a/servo/components/style/properties/longhand/font.mako.rs
+++ b/servo/components/style/properties/longhand/font.mako.rs
@@ -14,17 +14,18 @@
     pub use self::computed_value::T as SpecifiedValue;
 
     impl ComputedValueAsSpecified for SpecifiedValue {}
     pub mod computed_value {
         use cssparser::ToCss;
         use std::fmt;
         use string_cache::Atom;
 
-        #[derive(Debug, PartialEq, Eq, Clone, Hash, HeapSizeOf, Deserialize, Serialize)]
+        #[derive(Debug, PartialEq, Eq, Clone, Hash)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
         pub enum FontFamily {
             FamilyName(Atom),
             Generic(Atom),
         }
         impl FontFamily {
 
             #[inline]
             pub fn atom(&self) -> &Atom {
@@ -68,17 +69,18 @@
                 try!(iter.next().unwrap().to_css(dest));
                 for family in iter {
                     try!(dest.write_str(", "));
                     try!(family.to_css(dest));
                 }
                 Ok(())
             }
         }
-        #[derive(Debug, Clone, PartialEq, Eq, Hash, HeapSizeOf)]
+        #[derive(Debug, Clone, PartialEq, Eq, Hash)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct T(pub Vec<FontFamily>);
     }
 
     #[inline]
     pub fn get_initial_value() -> computed_value::T {
         computed_value::T(vec![FontFamily::Generic(atom!("serif"))])
     }
     /// <family-name>#
@@ -117,17 +119,18 @@
 
 ${helpers.single_keyword("font-style", "normal italic oblique", gecko_constant_prefix="NS_FONT_STYLE")}
 ${helpers.single_keyword("font-variant", "normal small-caps")}
 
 <%helpers:longhand name="font-weight" need_clone="True">
     use cssparser::ToCss;
     use std::fmt;
 
-    #[derive(Debug, Clone, PartialEq, Eq, Copy, HeapSizeOf)]
+    #[derive(Debug, Clone, PartialEq, Eq, Copy)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum SpecifiedValue {
         Bolder,
         Lighter,
         % for weight in range(100, 901, 100):
             Weight${weight},
         % endfor
     }
 
@@ -164,17 +167,18 @@
                 800 => Ok(SpecifiedValue::Weight800),
                 900 => Ok(SpecifiedValue::Weight900),
                 _ => Err(())
             }
         })
     }
     pub mod computed_value {
         use std::fmt;
-        #[derive(PartialEq, Eq, Copy, Clone, Hash, Deserialize, Serialize, HeapSizeOf, Debug)]
+        #[derive(PartialEq, Eq, Copy, Clone, Hash, Debug)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
         #[repr(u16)]
         pub enum T {
             % for weight in range(100, 901, 100):
                 Weight${weight} = ${weight},
             % endfor
         }
         impl T {
             #[inline]
@@ -245,17 +249,18 @@
     use values::specified::{LengthOrPercentage, Length, Percentage};
 
     impl ToCss for SpecifiedValue {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             self.0.to_css(dest)
         }
     }
 
-    #[derive(Debug, Clone, PartialEq, HeapSizeOf)]
+    #[derive(Debug, Clone, PartialEq)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct SpecifiedValue(pub specified::LengthOrPercentage);
     pub mod computed_value {
         use app_units::Au;
         pub type T = Au;
     }
     #[inline] pub fn get_initial_value() -> computed_value::T {
         Au::from_px(FONT_MEDIUM_PX)
     }
--- a/servo/components/style/properties/longhand/inherited_box.mako.rs
+++ b/servo/components/style/properties/longhand/inherited_box.mako.rs
@@ -35,17 +35,18 @@
 // https://drafts.csswg.org/css-color/
 ${helpers.single_keyword("color-adjust", "economy exact", products="gecko")}
 
 <%helpers:longhand name="image-rendering">
     pub mod computed_value {
         use cssparser::ToCss;
         use std::fmt;
 
-        #[derive(Copy, Clone, Debug, PartialEq, HeapSizeOf, Deserialize, Serialize)]
+        #[derive(Copy, Clone, Debug, PartialEq)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
         pub enum T {
             Auto,
             CrispEdges,
             Pixelated,
         }
 
         impl ToCss for T {
             fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
@@ -91,17 +92,18 @@
 
 // Used in the bottom-up flow construction traversal to avoid constructing flows for
 // descendants of nodes with `display: none`.
 <%helpers:longhand name="-servo-under-display-none" derived_from="display" products="servo">
     use cssparser::ToCss;
     use std::fmt;
     use values::computed::ComputedValueAsSpecified;
 
-    #[derive(Copy, Clone, Debug, Eq, PartialEq, HeapSizeOf, Serialize, Deserialize)]
+    #[derive(Copy, Clone, Debug, Eq, PartialEq)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
     pub struct SpecifiedValue(pub bool);
 
     pub mod computed_value {
         pub type T = super::SpecifiedValue;
     }
     impl ComputedValueAsSpecified for SpecifiedValue {}
 
     pub fn get_initial_value() -> computed_value::T {
--- a/servo/components/style/properties/longhand/inherited_table.mako.rs
+++ b/servo/components/style/properties/longhand/inherited_table.mako.rs
@@ -15,24 +15,26 @@
     use values::AuExtensionMethods;
 
     use cssparser::ToCss;
     use std::fmt;
 
     pub mod computed_value {
         use app_units::Au;
 
-        #[derive(Clone, Copy, Debug, PartialEq, RustcEncodable, HeapSizeOf)]
+        #[derive(Clone, Copy, Debug, PartialEq, RustcEncodable)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct T {
             pub horizontal: Au,
             pub vertical: Au,
         }
     }
 
-    #[derive(Clone, Debug, PartialEq, HeapSizeOf)]
+    #[derive(Clone, Debug, PartialEq)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct SpecifiedValue {
         pub horizontal: specified::Length,
         pub vertical: specified::Length,
     }
 
     #[inline]
     pub fn get_initial_value() -> computed_value::T {
         computed_value::T {
--- a/servo/components/style/properties/longhand/inherited_text.mako.rs
+++ b/servo/components/style/properties/longhand/inherited_text.mako.rs
@@ -7,17 +7,18 @@
 <% data.new_style_struct("InheritedText", inherited=True, gecko_name="Text") %>
 
 <%helpers:longhand name="line-height">
     use cssparser::ToCss;
     use std::fmt;
     use values::AuExtensionMethods;
     use values::CSSFloat;
 
-    #[derive(Debug, Clone, PartialEq, Copy, HeapSizeOf)]
+    #[derive(Debug, Clone, PartialEq, Copy)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum SpecifiedValue {
         Normal,
         % if product == "gecko":
             MozBlockHeight,
         % endif
         Number(CSSFloat),
         LengthOrPercentage(specified::LengthOrPercentage),
     }
@@ -56,17 +57,18 @@
                 _ => Err(()),
             }
         })
     }
     pub mod computed_value {
         use app_units::Au;
         use std::fmt;
         use values::CSSFloat;
-        #[derive(PartialEq, Copy, Clone, HeapSizeOf, Debug)]
+        #[derive(PartialEq, Copy, Clone, Debug)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub enum T {
             Normal,
             % if product == "gecko":
                 MozBlockHeight,
             % endif
             Length(Au),
             Number(CSSFloat),
         }
@@ -177,34 +179,36 @@
     }
 </%helpers:longhand>
 
 <%helpers:longhand name="letter-spacing">
     use cssparser::ToCss;
     use std::fmt;
     use values::AuExtensionMethods;
 
-    #[derive(Debug, Clone, Copy, PartialEq, HeapSizeOf)]
+    #[derive(Debug, Clone, Copy, PartialEq)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum SpecifiedValue {
         Normal,
         Specified(specified::Length),
     }
 
     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;
-        #[derive(Debug, Clone, PartialEq, HeapSizeOf)]
+        #[derive(Debug, Clone, PartialEq)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct T(pub Option<Au>);
     }
 
     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),
@@ -239,34 +243,36 @@
     }
 </%helpers:longhand>
 
 <%helpers:longhand name="word-spacing">
     use cssparser::ToCss;
     use std::fmt;
     use values::AuExtensionMethods;
 
-    #[derive(Debug, Clone, Copy, PartialEq, HeapSizeOf)]
+    #[derive(Debug, Clone, Copy, PartialEq)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum SpecifiedValue {
         Normal,
         Specified(specified::Length),  // FIXME(SimonSapin) support percentages
     }
 
     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;
-        #[derive(Debug, Clone, PartialEq, HeapSizeOf)]
+        #[derive(Debug, Clone, PartialEq)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct T(pub Option<Au>);
     }
 
     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),
@@ -327,17 +333,18 @@
     use cssparser::{RGBA, ToCss};
     use std::fmt;
 
     use values::computed::ComputedValueAsSpecified;
     use properties::style_struct_traits::{Box, Color, Text};
 
     impl ComputedValueAsSpecified for SpecifiedValue {}
 
-    #[derive(Clone, PartialEq, Copy, Debug, HeapSizeOf)]
+    #[derive(Clone, PartialEq, Copy, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct SpecifiedValue {
         pub underline: Option<RGBA>,
         pub overline: Option<RGBA>,
         pub line_through: Option<RGBA>,
     }
 
     pub mod computed_value {
         pub type T = super::SpecifiedValue;
@@ -441,35 +448,39 @@
     }
 </%helpers:single_keyword_computed>
 
 <%helpers:longhand name="text-shadow">
     use cssparser::{self, ToCss};
     use std::fmt;
     use values::AuExtensionMethods;
 
-    #[derive(Clone, PartialEq, Debug, HeapSizeOf)]
+    #[derive(Clone, PartialEq, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct SpecifiedValue(Vec<SpecifiedTextShadow>);
 
-    #[derive(Clone, PartialEq, Debug, HeapSizeOf)]
+    #[derive(Clone, PartialEq, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct SpecifiedTextShadow {
         pub offset_x: specified::Length,
         pub offset_y: specified::Length,
         pub blur_radius: specified::Length,
         pub color: Option<specified::CSSColor>,
     }
 
     pub mod computed_value {
         use app_units::Au;
         use cssparser::Color;
 
-        #[derive(Clone, PartialEq, Debug, HeapSizeOf)]
+        #[derive(Clone, PartialEq, Debug)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct T(pub Vec<TextShadow>);
 
-        #[derive(Clone, PartialEq, Debug, HeapSizeOf)]
+        #[derive(Clone, PartialEq, Debug)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct TextShadow {
             pub offset_x: Au,
             pub offset_y: Au,
             pub blur_radius: Au,
             pub color: Color,
         }
     }
 
--- a/servo/components/style/properties/longhand/list.mako.rs
+++ b/servo/components/style/properties/longhand/list.mako.rs
@@ -26,17 +26,18 @@
     gecko_constant_prefix="NS_STYLE_LIST_STYLE")}
 
 <%helpers:longhand name="list-style-image">
     use cssparser::{ToCss, Token};
     use std::fmt;
     use url::Url;
     use values::LocalToCss;
 
-    #[derive(Debug, Clone, PartialEq, Eq, HeapSizeOf)]
+    #[derive(Debug, Clone, PartialEq, Eq)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum SpecifiedValue {
         None,
         Url(Url),
     }
 
     impl ToCss for SpecifiedValue {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             match *self {
@@ -47,17 +48,18 @@
     }
 
     pub mod computed_value {
         use cssparser::{ToCss, Token};
         use std::fmt;
         use url::Url;
         use values::LocalToCss;
 
-        #[derive(Debug, Clone, PartialEq, HeapSizeOf)]
+        #[derive(Debug, Clone, PartialEq)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct T(pub Option<Url>);
 
         impl ToCss for T {
             fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
                 match self.0 {
                     None => dest.write_str("none"),
                     Some(ref url) => url.to_css(dest),
                 }
@@ -95,17 +97,18 @@
     use std::fmt;
     use values::computed::ComputedValueAsSpecified;
 
     use cssparser::{ToCss, Token};
 
     pub use self::computed_value::T as SpecifiedValue;
 
     pub mod computed_value {
-        #[derive(Debug, Clone, PartialEq, HeapSizeOf)]
+        #[derive(Debug, Clone, PartialEq)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub struct T(pub Vec<(String,String)>);
     }
 
     impl ComputedValueAsSpecified for SpecifiedValue {}
 
     impl ToCss for SpecifiedValue {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             let mut first = true;
--- a/servo/components/style/properties/longhand/outline.mako.rs
+++ b/servo/components/style/properties/longhand/outline.mako.rs
@@ -36,17 +36,18 @@
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             self.0.to_css(dest)
         }
     }
 
     pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
         specified::parse_border_width(input).map(SpecifiedValue)
     }
-    #[derive(Debug, Clone, PartialEq, HeapSizeOf)]
+    #[derive(Debug, Clone, PartialEq)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct SpecifiedValue(pub specified::Length);
     pub mod computed_value {
         use app_units::Au;
         pub type T = Au;
     }
     pub use super::border_top_width::get_initial_value;
     impl ToComputedValue for SpecifiedValue {
         type ComputedValue = computed_value::T;
--- a/servo/components/style/properties/longhand/pointing.mako.rs
+++ b/servo/components/style/properties/longhand/pointing.mako.rs
@@ -12,17 +12,18 @@
 
     impl ComputedValueAsSpecified for SpecifiedValue {}
 
     pub mod computed_value {
         use cssparser::ToCss;
         use std::fmt;
         use style_traits::cursor::Cursor;
 
-        #[derive(Clone, PartialEq, Eq, Copy, Debug, HeapSizeOf)]
+        #[derive(Clone, PartialEq, Eq, Copy, Debug)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub enum T {
             AutoCursor,
             SpecifiedCursor(Cursor),
         }
 
         impl ToCss for T {
             fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
                 match *self {
--- a/servo/components/style/properties/longhand/position.mako.rs
+++ b/servo/components/style/properties/longhand/position.mako.rs
@@ -15,17 +15,18 @@
     use values::computed::ComputedValueAsSpecified;
 
     impl ComputedValueAsSpecified for SpecifiedValue {}
     pub type SpecifiedValue = computed_value::T;
     pub mod computed_value {
         use cssparser::ToCss;
         use std::fmt;
 
-        #[derive(PartialEq, Clone, Eq, Copy, Debug, HeapSizeOf)]
+        #[derive(PartialEq, Clone, Eq, Copy, Debug)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         pub enum T {
             Auto,
             Number(i32),
         }
 
         impl ToCss for T {
             fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
                 match *self {
--- a/servo/components/style/properties/longhand/text.mako.rs
+++ b/servo/components/style/properties/longhand/text.mako.rs
@@ -19,17 +19,18 @@
 <%helpers:longhand name="${'text-decoration' if product == 'servo' else 'text-decoration-line'}"
                    custom_cascade="${product == 'servo'}">
     use cssparser::ToCss;
     use std::fmt;
     use values::computed::ComputedValueAsSpecified;
 
     impl ComputedValueAsSpecified for SpecifiedValue {}
 
-    #[derive(PartialEq, Eq, Copy, Clone, Debug, HeapSizeOf)]
+    #[derive(PartialEq, Eq, Copy, Clone, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct SpecifiedValue {
         pub underline: bool,
         pub overline: bool,
         pub line_through: bool,
         // 'blink' is accepted in the parser but ignored.
         // Just not blinking the text is a conforming implementation per CSS 2.1.
     }
 
--- a/servo/components/style/properties/properties.mako.rs
+++ b/servo/components/style/properties/properties.mako.rs
@@ -20,17 +20,17 @@ use std::mem;
 use std::sync::Arc;
 
 use app_units::Au;
 use cssparser::Color as CSSParserColor;
 use cssparser::{Parser, RGBA, AtRuleParser, DeclarationParser, Delimiter,
                 DeclarationListParser, parse_important, ToCss, TokenSerializationType};
 use error_reporting::ParseErrorReporter;
 use url::Url;
-use euclid::SideOffsets2D;
+use euclid::side_offsets::SideOffsets2D;
 use euclid::size::Size2D;
 use string_cache::Atom;
 use computed_values;
 use logical_geometry::{LogicalMargin, PhysicalSide, WritingMode};
 use parser::{ParserContext, ParserContextExtraData, log_css_error};
 use selectors::matching::DeclarationBlock;
 use stylesheets::Origin;
 use values::AuExtensionMethods;
@@ -256,21 +256,22 @@ mod property_bit_field {
 % endfor
 
 
 use std::iter::{Iterator, Chain, Zip, Rev, Repeat, repeat};
 use std::slice;
 /// Overridden declarations are skipped.
 
 // FIXME (https://github.com/servo/servo/issues/3426)
-#[derive(Debug, PartialEq, HeapSizeOf)]
+#[derive(Debug, PartialEq)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub struct PropertyDeclarationBlock {
-    #[ignore_heap_size_of = "#7038"]
+    #[cfg_attr(feature = "servo", ignore_heap_size_of = "#7038")]
     pub important: Arc<Vec<PropertyDeclaration>>,
-    #[ignore_heap_size_of = "#7038"]
+    #[cfg_attr(feature = "servo", ignore_heap_size_of = "#7038")]
     pub normal: Arc<Vec<PropertyDeclaration>>,
 }
 
 impl PropertyDeclarationBlock {
     /// Provides an iterator of all declarations, with indication of !important value
     pub fn declarations(&self) -> Chain<
         Zip<Rev<slice::Iter<PropertyDeclaration>>, Repeat<bool>>,
         Zip<Rev<slice::Iter<PropertyDeclaration>>, Repeat<bool>>
@@ -611,17 +612,18 @@ impl CSSWideKeyword {
             "initial" => Ok(CSSWideKeyword::InitialKeyword),
             "inherit" => Ok(CSSWideKeyword::InheritKeyword),
             "unset" => Ok(CSSWideKeyword::UnsetKeyword),
             _ => Err(())
         }
     }
 }
 
-#[derive(Clone, Copy, Eq, PartialEq, Debug, HeapSizeOf)]
+#[derive(Clone, Copy, Eq, PartialEq, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub enum Shorthand {
     % for property in data.shorthands:
         ${property.camel_case},
     % endfor
 }
 
 impl Shorthand {
     pub fn from_name(name: &str) -> Option<Shorthand> {
@@ -717,17 +719,18 @@ impl Shorthand {
                 // "as appropriate according to the grammar of shorthand "
                 // https://drafts.csswg.org/cssom/#serialize-a-css-value
             }
 
             None
     }
 }
 
-#[derive(Clone, PartialEq, Eq, Debug, HeapSizeOf)]
+#[derive(Clone, PartialEq, Eq, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub enum DeclaredValue<T> {
     Value(T),
     WithVariables {
         css: String,
         first_token_type: TokenSerializationType,
         base_url: Url,
         from_shorthand: Option<Shorthand>,
     },
@@ -748,17 +751,18 @@ impl<T: ToCss> ToCss for DeclaredValue<T
             // https://drafts.csswg.org/css-variables/#variables-in-shorthands
             DeclaredValue::WithVariables { .. } => Ok(()),
             DeclaredValue::Initial => dest.write_str("initial"),
             DeclaredValue::Inherit => dest.write_str("inherit"),
         }
     }
 }
 
-#[derive(PartialEq, Clone, Debug, HeapSizeOf)]
+#[derive(PartialEq, Clone, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub enum PropertyDeclaration {
     % for property in data.longhands:
         ${property.camel_case}(DeclaredValue<longhands::${property.ident}::SpecifiedValue>),
     % endfor
     Custom(::custom_properties::Name, DeclaredValue<::custom_properties::SpecifiedValue>),
 }
 
 
@@ -1059,19 +1063,21 @@ pub mod style_struct_traits {
 
 pub mod style_structs {
     use fnv::FnvHasher;
     use super::longhands;
     use std::hash::{Hash, Hasher};
 
     % for style_struct in data.active_style_structs():
         % if style_struct.trait_name == "Font":
-        #[derive(Clone, HeapSizeOf, Debug)]
+        #[derive(Clone, Debug)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         % else:
-        #[derive(PartialEq, Clone, HeapSizeOf)]
+        #[derive(PartialEq, Clone)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
         % endif
         pub struct ${style_struct.servo_struct_name} {
             % for longhand in style_struct.longhands:
                 pub ${longhand.ident}: longhands::${longhand.ident}::computed_value::T,
             % endfor
             % if style_struct.trait_name == "Font":
                 pub hash: u64,
             % endif
@@ -1228,17 +1234,18 @@ pub trait ComputedValues : Clone + Send 
 
     fn custom_properties(&self) -> Option<Arc<::custom_properties::ComputedValuesMap>>;
     fn root_font_size(&self) -> Au;
     fn set_root_font_size(&mut self, size: Au);
     fn set_writing_mode(&mut self, mode: WritingMode);
     fn is_multicol(&self) -> bool;
 }
 
-#[derive(Clone, HeapSizeOf)]
+#[derive(Clone)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub struct ServoComputedValues {
     % for style_struct in data.active_style_structs():
         ${style_struct.ident}: Arc<style_structs::${style_struct.servo_struct_name}>,
     % endfor
     custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
     shareable: bool,
     pub writing_mode: WritingMode,
     pub root_font_size: Au,
@@ -1687,17 +1694,17 @@ pub type CascadePropertyFn<C /*: Compute
                      error_reporter: &mut StdBox<ParseErrorReporter + Send>);
 
 pub fn make_cascade_vec<C: ComputedValues>() -> Vec<Option<CascadePropertyFn<C>>> {
     let mut result: Vec<Option<CascadePropertyFn<C>>> = Vec::new();
     % for style_struct in data.active_style_structs():
         % for property in style_struct.longhands:
             let discriminant;
             unsafe {
-                let variant = PropertyDeclaration::${property.camel_case}(intrinsics::uninit());
+                let variant = PropertyDeclaration::${property.camel_case}(mem::uninitialized());
                 discriminant = intrinsics::discriminant_value(&variant) as usize;
                 mem::forget(variant);
             }
             while result.len() < discriminant + 1 {
                 result.push(None)
             }
             result[discriminant] = Some(longhands::${property.ident}::cascade_property);
         % endfor
--- a/servo/components/style/restyle_hints.rs
+++ b/servo/components/style/restyle_hints.rs
@@ -45,17 +45,18 @@ bitflags! {
 /// Gecko does this differently for element states, and passes a mask called mStateMask, which
 /// indicates the states that need to be ignored during selector matching. This saves an ElementWrapper
 /// allocation and an additional selector match call at the expense of additional complexity inside
 /// the selector matching logic. This only works for boolean states though, so we still need to
 /// take the ElementWrapper approach for attribute-dependent style. So we do it the same both ways for
 /// now to reduce complexity, but it's worth measuring the performance impact (if any) of the
 /// mStateMask approach.
 
-#[derive(HeapSizeOf, Clone)]
+#[derive(Clone)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub struct ElementSnapshot {
     pub state: Option<ElementState>,
     pub attrs: Option<Vec<(AttrIdentifier, AttrValue)>>,
 }
 
 impl ElementSnapshot {
     pub fn new() -> ElementSnapshot {
         EMPTY_SNAPSHOT.clone()
@@ -220,17 +221,18 @@ fn combinator_to_restyle_hint(combinator
             Combinator::Child => RESTYLE_DESCENDANTS,
             Combinator::Descendant => RESTYLE_DESCENDANTS,
             Combinator::NextSibling => RESTYLE_LATER_SIBLINGS,
             Combinator::LaterSibling => RESTYLE_LATER_SIBLINGS,
         }
     }
 }
 
-#[derive(Debug, HeapSizeOf)]
+#[derive(Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 struct Sensitivities {
     pub states: ElementState,
     pub attrs: bool,
 }
 
 impl Sensitivities {
     fn is_empty(&self) -> bool {
         self.states.is_empty() && !self.attrs
@@ -257,24 +259,26 @@ impl Sensitivities {
 //   * |a|, |c|, and |e| are arbitrary simple selectors that do not depend on
 //     state or attributes.
 //
 // We generate a Dependency for both |a _ b:X _| and |a _ b:X _ c _ d:Y _|, even
 // though those selectors may not appear on their own in any stylesheet. This allows
 // us to quickly scan through the dependency sites of all style rules and determine the
 // maximum effect that a given state or attribute change may have on the style of
 // elements in the document.
-#[derive(Debug, HeapSizeOf)]
+#[derive(Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 struct Dependency<Impl: SelectorImplExt> {
     selector: Arc<CompoundSelector<Impl>>,
     combinator: Option<Combinator>,
     sensitivities: Sensitivities,
 }
 
-#[derive(Debug, HeapSizeOf)]
+#[derive(Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub struct DependencySet<Impl: SelectorImplExt> {
     deps: Vec<Dependency<Impl>>,
 }
 
 impl<Impl: SelectorImplExt> DependencySet<Impl> {
     pub fn new() -> DependencySet<Impl> {
         DependencySet { deps: Vec::new() }
     }
--- a/servo/components/style/selector_impl.rs
+++ b/servo/components/style/selector_impl.rs
@@ -90,17 +90,18 @@ pub trait SelectorImplExt : SelectorImpl
 
     fn pseudo_class_state_flag(pc: &Self::NonTSPseudoClass) -> ElementState;
 
     fn get_user_or_user_agent_stylesheets() -> &'static [Stylesheet<Self>];
 
     fn get_quirks_mode_stylesheet() -> Option<&'static Stylesheet<Self>>;
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, HeapSizeOf, Hash)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub enum PseudoElement {
     Before,
     After,
     Selection,
     DetailsSummary,
     DetailsContent,
 }
 
@@ -112,17 +113,18 @@ impl PseudoElement {
             PseudoElement::After |
             PseudoElement::Selection => PseudoElementCascadeType::Eager,
             PseudoElement::DetailsSummary => PseudoElementCascadeType::Lazy,
             PseudoElement::DetailsContent => PseudoElementCascadeType::Precomputed,
         }
     }
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, HeapSizeOf, Hash)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub enum NonTSPseudoClass {
     AnyLink,
     Link,
     Visited,
     Active,
     Focus,
     Hover,
     Enabled,
@@ -153,17 +155,18 @@ impl NonTSPseudoClass {
             AnyLink |
             Link |
             Visited |
             ServoNonZeroBorder => ElementState::empty(),
         }
     }
 }
 
-#[derive(Clone, Debug, PartialEq, HeapSizeOf)]
+#[derive(Clone, Debug, PartialEq)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub struct ServoSelectorImpl;
 
 impl SelectorImpl for ServoSelectorImpl {
     type PseudoElement = PseudoElement;
     type NonTSPseudoClass = NonTSPseudoClass;
 
     fn parse_non_ts_pseudo_class(context: &ParserContext,
                                  name: &str) -> Result<NonTSPseudoClass, ()> {
--- a/servo/components/style/selector_matching.rs
+++ b/servo/components/style/selector_matching.rs
@@ -39,46 +39,46 @@ lazy_static! {
             match read_resource_file(filename) {
                 Ok(res) => {
                     let ua_stylesheet = Stylesheet::from_bytes(
                         &res,
                         Url::parse(&format!("chrome://resources/{:?}", filename)).unwrap(),
                         None,
                         None,
                         Origin::UserAgent,
-                        box StdoutErrorReporter,
+                        Box::new(StdoutErrorReporter),
                         ParserContextExtraData::default());
                     stylesheets.push(ua_stylesheet);
                 }
                 Err(..) => {
                     error!("Failed to load UA stylesheet {}!", filename);
                     process::exit(1);
                 }
             }
         }
         for &(ref contents, ref url) in &opts::get().user_stylesheets {
             stylesheets.push(Stylesheet::from_bytes(
-                &contents, url.clone(), None, None, Origin::User, box StdoutErrorReporter,
+                &contents, url.clone(), None, None, Origin::User, Box::new(StdoutErrorReporter),
                 ParserContextExtraData::default()));
         }
         stylesheets
     };
 }
 
 lazy_static! {
     pub static ref QUIRKS_MODE_STYLESHEET: Stylesheet<ServoSelectorImpl> = {
         match read_resource_file("quirks-mode.css") {
             Ok(res) => {
                 Stylesheet::from_bytes(
                     &res,
                     Url::parse("chrome://resources/quirks-mode.css").unwrap(),
                     None,
                     None,
                     Origin::UserAgent,
-                    box StdoutErrorReporter,
+                    Box::new(StdoutErrorReporter),
                     ParserContextExtraData::default())
             },
             Err(..) => {
                 error!("Stylist failed to load 'quirks-mode.css'!");
                 process::exit(1);
             }
         }
     };
@@ -95,17 +95,17 @@ lazy_static! {
 /// LayoutThread corresponding to that pipeline.
 ///
 /// The stylist is parameterized on `SelectorImplExt`, a trait that extends
 /// `selectors::parser::SelectorImpl`, and that allows to customise what
 /// pseudo-classes and pseudo-elements are parsed. This is actually either
 /// `ServoSelectorImpl`, the implementation used by Servo's layout system in
 /// regular builds, or `GeckoSelectorImpl`, the implementation used in the
 /// geckolib port.
-#[derive(HeapSizeOf)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub struct Stylist<Impl: SelectorImplExt> {
     /// Device that the stylist is currently evaluating against.
     pub device: Device,
 
     /// Viewport constraints based on the current device.
     viewport_constraints: Option<ViewportConstraints>,
 
     /// If true, the quirks-mode stylesheet is applied.
@@ -264,17 +264,17 @@ impl<Impl: SelectorImplExt> Stylist<Impl
                                          parent: Option<&Arc<Impl::ComputedValues>>)
                                          -> Option<Arc<Impl::ComputedValues>> {
         debug_assert!(Impl::pseudo_element_cascade_type(pseudo).is_precomputed());
         if let Some(declarations) = self.precomputed_pseudo_element_decls.get(pseudo) {
             let (computed, _) =
                 properties::cascade(self.device.au_viewport_size(),
                                     &declarations, false,
                                     parent.map(|p| &**p), None,
-                                    box StdoutErrorReporter);
+                                    Box::new(StdoutErrorReporter));
             Some(Arc::new(computed))
         } else {
             parent.map(|p| p.clone())
         }
     }
 
     pub fn lazily_compute_pseudo_element_style<E>(&self,
                                                   element: &E,
@@ -297,17 +297,17 @@ impl<Impl: SelectorImplExt> Stylist<Impl
                                           None,
                                           Some(pseudo),
                                           &mut declarations);
 
         let (computed, _) =
             properties::cascade(self.device.au_viewport_size(),
                                 &declarations, false,
                                 Some(&**parent), None,
-                                box StdoutErrorReporter);
+                                Box::new(StdoutErrorReporter));
         Some(Arc::new(computed))
     }
 
     pub fn compute_restyle_hint<E>(&self, element: &E,
                                    snapshot: &ElementSnapshot,
                                    // NB: We need to pass current_state as an argument because
                                    // selectors::Element doesn't provide access to ElementState
                                    // directly, and computing it from the ElementState would be
@@ -433,17 +433,17 @@ impl<Impl: SelectorImplExt> Stylist<Impl
 
     #[inline]
     pub fn is_device_dirty(&self) -> bool {
         self.is_device_dirty
     }
 }
 
 /// Map that contains the CSS rules for a given origin.
-#[derive(HeapSizeOf)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 struct PerOriginSelectorMap<Impl: SelectorImpl> {
     /// Rules that contains at least one property declararion with
     /// normal importance.
     normal: SelectorMap<Vec<PropertyDeclaration>, Impl>,
     /// Rules that contains at least one property declararion with
     /// !important.
     important: SelectorMap<Vec<PropertyDeclaration>, Impl>,
 }
@@ -455,17 +455,17 @@ impl<Impl: SelectorImpl> PerOriginSelect
             normal: SelectorMap::new(),
             important: SelectorMap::new(),
         }
     }
 }
 
 /// Map that contains the CSS rules for a specific PseudoElement
 /// (or lack of PseudoElement).
-#[derive(HeapSizeOf)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 struct PerPseudoElementSelectorMap<Impl: SelectorImpl> {
     /// Rules from user agent stylesheets
     user_agent: PerOriginSelectorMap<Impl>,
     /// Rules from author stylesheets
     author: PerOriginSelectorMap<Impl>,
     /// Rules from user stylesheets
     user: PerOriginSelectorMap<Impl>,
 }
--- a/servo/components/style/stylesheets.rs
+++ b/servo/components/style/stylesheets.rs
@@ -19,65 +19,70 @@ use std::slice;
 use string_cache::{Atom, Namespace};
 use url::Url;
 use viewport::ViewportRule;
 
 
 /// Each style rule has an origin, which determines where it enters the cascade.
 ///
 /// http://dev.w3.org/csswg/css-cascade/#cascading-origins
-#[derive(Clone, PartialEq, Eq, Copy, Debug, HeapSizeOf)]
+#[derive(Clone, PartialEq, Eq, Copy, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub enum Origin {
     /// http://dev.w3.org/csswg/css-cascade/#cascade-origin-ua
     UserAgent,
 
     /// http://dev.w3.org/csswg/css-cascade/#cascade-origin-author
     Author,
 
     /// http://dev.w3.org/csswg/css-cascade/#cascade-origin-user
     User,
 }
 
 
-#[derive(Debug, HeapSizeOf, PartialEq)]
+#[derive(Debug, PartialEq)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub struct Stylesheet<Impl: SelectorImpl> {
     /// List of rules in the order they were found (important for
     /// cascading order)
     pub rules: Vec<CSSRule<Impl>>,
     /// List of media associated with the Stylesheet, if any.
     pub media: Option<MediaQueryList>,
     pub origin: Origin,
     pub dirty_on_viewport_size_change: bool,
 }
 
 
-#[derive(Debug, HeapSizeOf, PartialEq)]
+#[derive(Debug, PartialEq)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub enum CSSRule<Impl: SelectorImpl> {
     Charset(String),
     Namespace(Option<String>, Namespace),
     Style(StyleRule<Impl>),
     Media(MediaRule<Impl>),
     FontFace(FontFaceRule),
     Viewport(ViewportRule),
 }
 
-#[derive(Debug, HeapSizeOf, PartialEq)]
+#[derive(Debug, PartialEq)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub struct MediaRule<Impl: SelectorImpl> {
     pub media_queries: MediaQueryList,
     pub rules: Vec<CSSRule<Impl>>,
 }
 
 impl<Impl: SelectorImpl> MediaRule<Impl> {
     #[inline]
     pub fn evaluate(&self, device: &Device) -> bool {
         self.media_queries.evaluate(device)
     }
 }
 
-#[derive(Debug, HeapSizeOf, PartialEq)]
+#[derive(Debug, PartialEq)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub struct StyleRule<Impl: SelectorImpl> {
     pub selectors: Vec<Selector<Impl>>,
     pub declarations: PropertyDeclarationBlock,
 }
 
 
 impl<Impl: SelectorImpl> Stylesheet<Impl> {
     pub fn from_bytes_iter<I: Iterator<Item=Vec<u8>>>(
--- a/servo/components/style/traversal.rs
+++ b/servo/components/style/traversal.rs
@@ -48,21 +48,21 @@ fn take_thread_local_bloom_filter<N, Imp
                                                             context: &SharedStyleContext<Impl>)
                                                             -> Box<BloomFilter>
                                                             where N: TNode {
     STYLE_BLOOM.with(|style_bloom| {
         match (parent_node, style_bloom.borrow_mut().take()) {
             // Root node. Needs new bloom filter.
             (None,     _  ) => {
                 debug!("[{}] No parent, but new bloom filter!", tid());
-                box BloomFilter::new()
+                Box::new(BloomFilter::new())
             }
             // No bloom filter for this thread yet.
             (Some(parent), None) => {
-                let mut bloom_filter = box BloomFilter::new();
+                let mut bloom_filter = Box::new(BloomFilter::new());
                 insert_ancestors_into_bloom_filter(&mut bloom_filter, parent, root);
                 bloom_filter
             }
             // Found cached bloom filter.
             (Some(parent), Some((mut bloom_filter, old_node, old_generation))) => {
                 if old_node == parent.to_unsafe() &&
                     old_generation == context.generation {
                     // Hey, the cached parent is our parent! We can reuse the bloom filter.
--- a/servo/components/style/values.rs
+++ b/servo/components/style/values.rs
@@ -36,18 +36,18 @@ impl AuExtensionMethods for Au {
 }
 
 macro_rules! define_numbered_css_keyword_enum {
     ($name: ident: $( $css: expr => $variant: ident = $value: expr ),+,) => {
         define_numbered_css_keyword_enum!($name: $( $css => $variant = $value ),+);
     };
     ($name: ident: $( $css: expr => $variant: ident = $value: expr ),+) => {
         #[allow(non_camel_case_types)]
-        #[derive(Clone, Eq, PartialEq, PartialOrd, Ord, Copy, RustcEncodable, Debug, HeapSizeOf)]
-        #[derive(Deserialize, Serialize)]
+        #[derive(Clone, Eq, PartialEq, PartialOrd, Ord, Copy, RustcEncodable, Debug)]
+        #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
         pub enum $name {
             $( $variant = $value ),+
         }
 
         impl $name {
             pub fn parse(input: &mut ::cssparser::Parser) -> Result<$name, ()> {
                 match_ignore_ascii_case! { try!(input.expect_ident()),
                     $( $css => Ok($name::$variant), )+
@@ -99,17 +99,18 @@ pub mod specified {
     use std::fmt;
     use std::ops::Mul;
     use style_traits::values::specified::AllowedNumericType;
     use super::AuExtensionMethods;
     use super::computed::{TContext, ToComputedValue};
     use super::{CSSFloat, FONT_MEDIUM_PX};
     use url::Url;
 
-    #[derive(Clone, PartialEq, Debug, HeapSizeOf)]
+    #[derive(Clone, PartialEq, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct CSSColor {
         pub parsed: cssparser::Color,
         pub authored: Option<String>,
     }
     impl CSSColor {
         pub fn parse(input: &mut Parser) -> Result<CSSColor, ()> {
             let start_position = input.position();
             let authored = match input.next() {
@@ -128,32 +129,34 @@ pub mod specified {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             match self.authored {
                 Some(ref s) => dest.write_str(s),
                 None => self.parsed.to_css(dest),
             }
         }
     }
 
-    #[derive(Clone, PartialEq, Debug, HeapSizeOf)]
+    #[derive(Clone, PartialEq, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct CSSRGBA {
         pub parsed: cssparser::RGBA,
         pub authored: Option<String>,
     }
 
     impl ToCss for CSSRGBA {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             match self.authored {
                 Some(ref s) => dest.write_str(s),
                 None => self.parsed.to_css(dest),
             }
         }
     }
 
-    #[derive(Clone, PartialEq, Copy, Debug, HeapSizeOf)]
+    #[derive(Clone, PartialEq, Copy, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum FontRelativeLength {
         Em(CSSFloat),
         Ex(CSSFloat),
         Ch(CSSFloat),
         Rem(CSSFloat)
     }
 
     impl ToCss for FontRelativeLength {
@@ -180,17 +183,18 @@ pub mod specified {
                     let em_factor = 0.5;
                     reference_font_size.scale_by(length * em_factor)
                 },
                 FontRelativeLength::Rem(length) => root_font_size.scale_by(length)
             }
         }
     }
 
-    #[derive(Clone, PartialEq, Copy, Debug, HeapSizeOf)]
+    #[derive(Clone, PartialEq, Copy, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum ViewportPercentageLength {
         Vw(CSSFloat),
         Vh(CSSFloat),
         Vmin(CSSFloat),
         Vmax(CSSFloat)
     }
 
     impl ToCss for ViewportPercentageLength {
@@ -221,32 +225,34 @@ pub mod specified {
                     length * to_unit!(cmp::min(viewport_size.width, viewport_size.height)),
                 ViewportPercentageLength::Vmax(length) =>
                     length * to_unit!(cmp::max(viewport_size.width, viewport_size.height)),
             };
             Au::from_f32_px(value)
         }
     }
 
-    #[derive(Clone, PartialEq, Copy, Debug, HeapSizeOf)]
+    #[derive(Clone, PartialEq, Copy, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct CharacterWidth(pub i32);
 
     impl CharacterWidth {
         pub fn to_computed_value(&self, reference_font_size: Au) -> Au {
             // This applies the *converting a character width to pixels* algorithm as specified
             // in HTML5 § 14.5.4.
             //
             // TODO(pcwalton): Find these from the font.
             let average_advance = reference_font_size.scale_by(0.5);
             let max_advance = reference_font_size;
             average_advance.scale_by(self.0 as CSSFloat - 1.0) + max_advance
         }
     }
 
-    #[derive(Clone, PartialEq, Copy, Debug, HeapSizeOf)]
+    #[derive(Clone, PartialEq, Copy, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum Length {
         Absolute(Au),  // application units
         FontRelative(FontRelativeLength),
         ViewportPercentage(ViewportPercentageLength),
 
         /// HTML5 "character width", as defined in HTML5 § 14.5.4.
         ///
         /// This cannot be specified by the user directly and is only generated by
@@ -434,19 +440,19 @@ pub mod specified {
         #[inline]
         fn mul(self, scalar: CSSFloat) -> SimplifiedValueNode {
             match *self {
                 SimplifiedValueNode::Length(l) => SimplifiedValueNode::Length(l * scalar),
                 SimplifiedValueNode::Percentage(p) => SimplifiedValueNode::Percentage(p * scalar),
                 SimplifiedValueNode::Angle(Angle(a)) => SimplifiedValueNode::Angle(Angle(a * scalar)),
                 SimplifiedValueNode::Time(Time(t)) => SimplifiedValueNode::Time(Time(t * scalar)),
                 SimplifiedValueNode::Number(n) => SimplifiedValueNode::Number(n * scalar),
-                SimplifiedValueNode::Sum(box ref s) => {
-                    let sum = s * scalar;
-                    SimplifiedValueNode::Sum(box sum)
+                SimplifiedValueNode::Sum(ref s) => {
+                    let sum = &**s * scalar;
+                    SimplifiedValueNode::Sum(Box::new(sum))
                 }
             }
         }
     }
 
     pub fn parse_integer(input: &mut Parser) -> Result<i32, ()> {
         match try!(input.next()) {
             Token::Number(ref value) => value.int_value.ok_or(()),
@@ -502,17 +508,18 @@ pub mod specified {
         Number,
         Integer,
         Length,
         LengthOrPercentage,
         Angle,
         Time,
     }
 
-    #[derive(Clone, PartialEq, Copy, Debug, HeapSizeOf)]
+    #[derive(Clone, PartialEq, Copy, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct CalcLengthOrPercentage {
         pub absolute: Option<Au>,
         pub vw: Option<ViewportPercentageLength>,
         pub vh: Option<ViewportPercentageLength>,
         pub vmin: Option<ViewportPercentageLength>,
         pub vmax: Option<ViewportPercentageLength>,
         pub em: Option<FontRelativeLength>,
         pub ex: Option<FontRelativeLength>,
@@ -584,26 +591,26 @@ pub mod specified {
                 }
                 (Token::Dimension(ref value, ref unit), CalcUnit::Time) => {
                     Time::parse_dimension(value.value, unit).map(CalcValueNode::Time)
                 }
                 (Token::Percentage(ref value), CalcUnit::LengthOrPercentage) =>
                     Ok(CalcValueNode::Percentage(value.unit_value)),
                 (Token::ParenthesisBlock, _) => {
                     input.parse_nested_block(|i| CalcLengthOrPercentage::parse_sum(i, expected_unit))
-                         .map(|result| CalcValueNode::Sum(box result))
+                         .map(|result| CalcValueNode::Sum(Box::new(result)))
                 },
                 _ => Err(())
             }
         }
 
         fn simplify_value_to_number(node: &CalcValueNode) -> Option<CSSFloat> {
             match *node {
                 CalcValueNode::Number(number) => Some(number),
-                CalcValueNode::Sum(box ref sum) => CalcLengthOrPercentage::simplify_sum_to_number(sum),
+                CalcValueNode::Sum(ref sum) => CalcLengthOrPercentage::simplify_sum_to_number(sum),
                 _ => None
             }
         }
 
         fn simplify_sum_to_number(node: &CalcSumNode) -> Option<CSSFloat> {
             let mut sum = 0.;
             for ref product in &node.products {
                 match CalcLengthOrPercentage::simplify_product_to_number(product) {
@@ -624,37 +631,37 @@ pub mod specified {
             }
             Some(product)
         }
 
         fn simplify_products_in_sum(node: &CalcSumNode) -> Result<SimplifiedValueNode, ()> {
             let mut simplified = Vec::new();
             for product in &node.products {
                 match try!(CalcLengthOrPercentage::simplify_product(product)) {
-                    SimplifiedValueNode::Sum(box sum) => simplified.extend_from_slice(&sum.values),
+                    SimplifiedValueNode::Sum(ref sum) => simplified.extend_from_slice(&sum.values),
                     val => simplified.push(val),
                 }
             }
 
             if simplified.len() == 1 {
                 Ok(simplified[0].clone())
             } else {
-                Ok(SimplifiedValueNode::Sum(box SimplifiedSumNode { values: simplified } ))
+                Ok(SimplifiedValueNode::Sum(Box::new(SimplifiedSumNode { values: simplified })))
             }
         }
 
         fn simplify_product(node: &CalcProductNode) -> Result<SimplifiedValueNode, ()> {
             let mut multiplier = 1.;
             let mut node_with_unit = None;
             for node in &node.values {
                 match CalcLengthOrPercentage::simplify_value_to_number(&node) {
                     Some(number) => multiplier *= number,
                     _ if node_with_unit.is_none() => {
                         node_with_unit = Some(match *node {
-                            CalcValueNode::Sum(box ref sum) =>
+                            CalcValueNode::Sum(ref sum) =>
                                 try!(CalcLengthOrPercentage::simplify_products_in_sum(sum)),
                             CalcValueNode::Length(l) => SimplifiedValueNode::Length(l),
                             CalcValueNode::Angle(a) => SimplifiedValueNode::Angle(a),
                             CalcValueNode::Time(t) => SimplifiedValueNode::Time(t),
                             CalcValueNode::Percentage(p) => SimplifiedValueNode::Percentage(p),
                             _ => unreachable!("Numbers should have been handled by simplify_value_to_nubmer")
                         })
                     },
@@ -850,26 +857,28 @@ pub mod specified {
 
             if count > 1 {
                try!(write!(dest, ")"));
             }
             Ok(())
          }
     }
 
-    #[derive(Clone, PartialEq, Copy, Debug, HeapSizeOf)]
+    #[derive(Clone, PartialEq, Copy, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct Percentage(pub CSSFloat); // [0 .. 100%] maps to [0.0 .. 1.0]
 
     impl ToCss for Percentage {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             write!(dest, "{}%", self.0 * 100.)
         }
     }
 
-    #[derive(Clone, PartialEq, Copy, Debug, HeapSizeOf)]
+    #[derive(Clone, PartialEq, Copy, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum LengthOrPercentage {
         Length(Length),
         Percentage(Percentage),
         Calc(CalcLengthOrPercentage),
     }
 
     impl ToCss for LengthOrPercentage {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
@@ -907,17 +916,18 @@ pub mod specified {
             LengthOrPercentage::parse_internal(input, &AllowedNumericType::All)
         }
         #[inline]
         pub fn parse_non_negative(input: &mut Parser) -> Result<LengthOrPercentage, ()> {
             LengthOrPercentage::parse_internal(input, &AllowedNumericType::NonNegative)
         }
     }
 
-    #[derive(Clone, PartialEq, Copy, Debug, HeapSizeOf)]
+    #[derive(Clone, PartialEq, Copy, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum LengthOrPercentageOrAuto {
         Length(Length),
         Percentage(Percentage),
         Auto,
         Calc(CalcLengthOrPercentage),
     }
 
     impl ToCss for LengthOrPercentageOrAuto {
@@ -956,17 +966,18 @@ pub mod specified {
             LengthOrPercentageOrAuto::parse_internal(input, &AllowedNumericType::All)
         }
         #[inline]
         pub fn parse_non_negative(input: &mut Parser) -> Result<LengthOrPercentageOrAuto, ()> {
             LengthOrPercentageOrAuto::parse_internal(input, &AllowedNumericType::NonNegative)
         }
     }
 
-    #[derive(Clone, PartialEq, Copy, Debug, HeapSizeOf)]
+    #[derive(Clone, PartialEq, Copy, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum LengthOrPercentageOrNone {
         Length(Length),
         Percentage(Percentage),
         Calc(CalcLengthOrPercentage),
         None,
     }
 
     impl ToCss for LengthOrPercentageOrNone {
@@ -1004,17 +1015,18 @@ pub mod specified {
             LengthOrPercentageOrNone::parse_internal(input, &AllowedNumericType::All)
         }
         #[inline]
         pub fn parse_non_negative(input: &mut Parser) -> Result<LengthOrPercentageOrNone, ()> {
             LengthOrPercentageOrNone::parse_internal(input, &AllowedNumericType::NonNegative)
         }
     }
 
-    #[derive(Clone, PartialEq, Copy, Debug, HeapSizeOf)]
+    #[derive(Clone, PartialEq, Copy, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum LengthOrNone {
         Length(Length),
         None,
     }
 
     impl ToCss for LengthOrNone {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             match *self {
@@ -1044,17 +1056,18 @@ pub mod specified {
             LengthOrNone::parse_internal(input, &AllowedNumericType::All)
         }
         #[inline]
         pub fn parse_non_negative(input: &mut Parser) -> Result<LengthOrNone, ()> {
             LengthOrNone::parse_internal(input, &AllowedNumericType::NonNegative)
         }
     }
 
-    #[derive(Clone, PartialEq, Copy, Debug, HeapSizeOf)]
+    #[derive(Clone, PartialEq, Copy, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum LengthOrPercentageOrAutoOrContent {
         Length(Length),
         Percentage(Percentage),
         Calc(CalcLengthOrPercentage),
         Auto,
         Content
     }
 
@@ -1088,17 +1101,18 @@ pub mod specified {
                     let calc = try!(input.parse_nested_block(CalcLengthOrPercentage::parse_length_or_percentage));
                     Ok(LengthOrPercentageOrAutoOrContent::Calc(calc))
                 },
                 _ => Err(())
             }
         }
     }
 
-    #[derive(Clone, PartialEq, Copy, Debug, HeapSizeOf)]
+    #[derive(Clone, PartialEq, Copy, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct BorderRadiusSize(pub Size2D<LengthOrPercentage>);
 
     impl BorderRadiusSize {
         pub fn zero() -> BorderRadiusSize {
             let zero = LengthOrPercentage::Length(Length::Absolute(Au(0)));
                 BorderRadiusSize(Size2D::new(zero, zero))
         }
 
@@ -1164,17 +1178,18 @@ pub mod specified {
                 PositionComponent::Left |
                 PositionComponent::Top => LengthOrPercentage::Percentage(Percentage(0.0)),
                 PositionComponent::Right |
                 PositionComponent::Bottom => LengthOrPercentage::Percentage(Percentage(1.0)),
             }
         }
     }
 
-    #[derive(Clone, PartialEq, PartialOrd, Copy, Debug, HeapSizeOf, Deserialize, Serialize)]
+    #[derive(Clone, PartialEq, PartialOrd, Copy, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
     pub struct Angle(pub CSSFloat);
 
     impl ToCss for Angle {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             write!(dest, "{}rad", self.0)
         }
     }
 
@@ -1210,17 +1225,18 @@ pub mod specified {
                 "turn" => Ok(Angle(value * RAD_PER_TURN)),
                 "rad" => Ok(Angle(value)),
                  _ => Err(())
             }
         }
     }
 
     /// Specified values for an image according to CSS-IMAGES.
-    #[derive(Clone, PartialEq, Debug, HeapSizeOf)]
+    #[derive(Clone, PartialEq, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum Image {
         Url(Url),
         LinearGradient(LinearGradient),
     }
 
     impl ToCss for Image {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             use values::LocalToCss;
@@ -1245,17 +1261,18 @@ pub mod specified {
                     },
                     _ => Err(())
                 }
             }
         }
     }
 
     /// Specified values for a CSS linear gradient.
-    #[derive(Clone, PartialEq, Debug, HeapSizeOf)]
+    #[derive(Clone, PartialEq, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct LinearGradient {
         /// The angle or corner of the gradient.
         pub angle_or_corner: AngleOrCorner,
 
         /// The color stops.
         pub stops: Vec<ColorStop>,
     }
 
@@ -1268,17 +1285,18 @@ pub mod specified {
                 try!(stop.to_css(dest));
             }
             try!(dest.write_str(")"));
             Ok(())
         }
     }
 
     /// Specified values for an angle or a corner in a linear gradient.
-    #[derive(Clone, PartialEq, Copy, Debug, HeapSizeOf)]
+    #[derive(Clone, PartialEq, Copy, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum AngleOrCorner {
         Angle(Angle),
         Corner(HorizontalDirection, VerticalDirection),
     }
 
     impl ToCss for AngleOrCorner {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             match *self {
@@ -1290,17 +1308,18 @@ pub mod specified {
                     try!(vertical.to_css(dest));
                     Ok(())
                 }
             }
         }
     }
 
     /// Specified values for one color stop in a linear gradient.
-    #[derive(Clone, PartialEq, Debug, HeapSizeOf)]
+    #[derive(Clone, PartialEq, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct ColorStop {
         /// The color of this stop.
         pub color: CSSColor,
 
         /// The position of this stop. If not specified, this stop is placed halfway between the
         /// point that precedes it and the point that follows it.
         pub position: Option<LengthOrPercentage>,
     }
@@ -1419,17 +1438,18 @@ pub mod specified {
 
     impl BorderStyle {
         pub fn none_or_hidden(&self) -> bool {
             matches!(*self, BorderStyle::none | BorderStyle::hidden)
         }
     }
 
     /// A time in seconds according to CSS-VALUES § 6.2.
-    #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, HeapSizeOf)]
+    #[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct Time(pub CSSFloat);
 
     impl Time {
         /// Returns the time in fractional seconds.
         pub fn seconds(self) -> f32 {
             let Time(seconds) = self;
             seconds
         }
@@ -1468,17 +1488,18 @@ pub mod specified {
     }
 
     impl ToCss for Time {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             write!(dest, "{}s", self.0)
         }
     }
 
-    #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, HeapSizeOf)]
+    #[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct Number(pub CSSFloat);
 
     impl Number {
         pub fn parse(input: &mut Parser) -> Result<Number, ()> {
             parse_number(input).map(Number)
         }
 
         fn parse_with_minimum(input: &mut Parser, min: CSSFloat) -> Result<Number, ()> {
@@ -1505,17 +1526,18 @@ pub mod specified {
     }
 
     impl ToCss for Number {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             self.0.to_css(dest)
         }
     }
 
-    #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, HeapSizeOf)]
+    #[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct Opacity(pub CSSFloat);
 
     impl Opacity {
         pub fn parse(input: &mut Parser) -> Result<Opacity, ()> {
             parse_number(input).map(Opacity)
         }
     }
 
@@ -1625,17 +1647,18 @@ pub mod computed {
                 specified::Length::ViewportPercentage(length) =>
                     length.to_computed_value(context.viewport_size()),
                 specified::Length::ServoCharacterWidth(length) =>
                     length.to_computed_value(context.style().get_font().clone_font_size())
             }
         }
     }
 
-    #[derive(Clone, PartialEq, Copy, Debug, HeapSizeOf)]
+    #[derive(Clone, PartialEq, Copy, Debug)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct CalcLengthOrPercentage {
         pub length: Option<Au>,
         pub percentage: Option<CSSFloat>,
     }
 
     impl CalcLengthOrPercentage {
         #[inline]
         pub fn length(&self) -> Au {
@@ -1729,17 +1752,18 @@ pub mod computed {
                 }
             }
 
             CalcLengthOrPercentage { length: length, percentage: self.percentage.map(|p| p.0) }
         }
     }
 
 
-    #[derive(PartialEq, Clone, Copy, HeapSizeOf)]
+    #[derive(PartialEq, Clone, Copy)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct BorderRadiusSize(pub Size2D<LengthOrPercentage>);
 
     impl BorderRadiusSize {
         pub fn zero() -> BorderRadiusSize {
             BorderRadiusSize(Size2D::new(LengthOrPercentage::Length(Au(0)), LengthOrPercentage::Length(Au(0))))
         }
     }
 
@@ -1757,17 +1781,18 @@ pub mod computed {
     impl ::cssparser::ToCss for BorderRadiusSize {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             try!(self.0.width.to_css(dest));
             try!(dest.write_str("/"));
             self.0.height.to_css(dest)
         }
     }
 
-    #[derive(PartialEq, Clone, Copy, HeapSizeOf)]
+    #[derive(PartialEq, Clone, Copy)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum LengthOrPercentage {
         Length(Au),
         Percentage(CSSFloat),
         Calc(CalcLengthOrPercentage),
     }
 
     impl LengthOrPercentage {
         #[inline]
@@ -1822,17 +1847,18 @@ pub mod computed {
                 LengthOrPercentage::Length(length) => length.to_css(dest),
                 LengthOrPercentage::Percentage(percentage)
                 => write!(dest, "{}%", percentage * 100.),
                 LengthOrPercentage::Calc(calc) => calc.to_css(dest),
             }
         }
     }
 
-    #[derive(PartialEq, Clone, Copy, HeapSizeOf)]
+    #[derive(PartialEq, Clone, Copy)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum LengthOrPercentageOrAuto {
         Length(Au),
         Percentage(CSSFloat),
         Auto,
         Calc(CalcLengthOrPercentage),
     }
 
     impl LengthOrPercentageOrAuto {
@@ -1889,17 +1915,18 @@ pub mod computed {
                 LengthOrPercentageOrAuto::Percentage(percentage)
                 => write!(dest, "{}%", percentage * 100.),
                 LengthOrPercentageOrAuto::Auto => dest.write_str("auto"),
                 LengthOrPercentageOrAuto::Calc(calc) => calc.to_css(dest),
             }
         }
     }
 
-    #[derive(PartialEq, Clone, Copy, HeapSizeOf)]
+    #[derive(PartialEq, Clone, Copy)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum LengthOrPercentageOrAutoOrContent {
         Length(Au),
         Percentage(CSSFloat),
         Calc(CalcLengthOrPercentage),
         Auto,
         Content
     }
     impl fmt::Debug for LengthOrPercentageOrAutoOrContent {
@@ -1947,17 +1974,18 @@ pub mod computed {
                 => write!(dest, "{}%", percentage * 100.),
                 LengthOrPercentageOrAutoOrContent::Calc(calc) => calc.to_css(dest),
                 LengthOrPercentageOrAutoOrContent::Auto => dest.write_str("auto"),
                 LengthOrPercentageOrAutoOrContent::Content => dest.write_str("content")
             }
         }
     }
 
-    #[derive(PartialEq, Clone, Copy, HeapSizeOf)]
+    #[derive(PartialEq, Clone, Copy)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum LengthOrPercentageOrNone {
         Length(Au),
         Percentage(CSSFloat),
         Calc(CalcLengthOrPercentage),
         None,
     }
     impl fmt::Debug for LengthOrPercentageOrNone {
         fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -1999,17 +2027,18 @@ pub mod computed {
                 LengthOrPercentageOrNone::Percentage(percentage) =>
                     write!(dest, "{}%", percentage * 100.),
                 LengthOrPercentageOrNone::Calc(calc) => calc.to_css(dest),
                 LengthOrPercentageOrNone::None => dest.write_str("none"),
             }
         }
     }
 
-    #[derive(PartialEq, Clone, Copy, HeapSizeOf)]
+    #[derive(PartialEq, Clone, Copy)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum LengthOrNone {
         Length(Au),
         None,
     }
     impl fmt::Debug for LengthOrNone {
         fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             match *self {
                 LengthOrNone::Length(length) => write!(f, "{:?}", length),
@@ -2057,33 +2086,35 @@ pub mod computed {
                     Image::LinearGradient(linear_gradient.to_computed_value(context))
                 }
             }
         }
     }
 
 
     /// Computed values for an image according to CSS-IMAGES.
-    #[derive(Clone, PartialEq, HeapSizeOf)]
+    #[derive(Clone, PartialEq)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub enum Image {
         Url(Url),
         LinearGradient(LinearGradient),
     }
 
     impl fmt::Debug for Image {
         fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             match *self {
                 Image::Url(ref url) => write!(f, "url(\"{}\")", url),
                 Image::LinearGradient(ref grad) => write!(f, "linear-gradient({:?})", grad),
             }
         }
     }
 
     /// Computed values for a CSS linear gradient.
-    #[derive(Clone, PartialEq, HeapSizeOf)]
+    #[derive(Clone, PartialEq)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct LinearGradient {
         /// The angle or corner of the gradient.
         pub angle_or_corner: AngleOrCorner,
 
         /// The color stops.
         pub stops: Vec<ColorStop>,
     }
 
@@ -2106,17 +2137,18 @@ pub mod computed {
             for stop in &self.stops {
                 let _ = write!(f, ", {:?}", stop);
             }
             Ok(())
         }
     }
 
     /// Computed values for one color stop in a linear gradient.
-    #[derive(Clone, PartialEq, Copy, HeapSizeOf)]
+    #[derive(Clone, PartialEq, Copy)]
+    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
     pub struct ColorStop {
         /// The color of this stop.
         pub color: CSSColor,
 
         /// The position of this stop. If not specified, this stop is placed halfway between the
         /// point that precedes it and the point that follows it per CSS-IMAGES § 3.4.
         pub position: Option<LengthOrPercentage>,
     }
--- a/servo/components/style/viewport.rs
+++ b/servo/components/style/viewport.rs
@@ -16,17 +16,18 @@ use std::intrinsics;
 use std::iter::Enumerate;
 use std::str::Chars;
 use style_traits::viewport::{Orientation, UserZoom, ViewportConstraints, Zoom};
 use stylesheets::Origin;
 use util::geometry::ViewportPx;
 use values::computed::{Context, ToComputedValue};
 use values::specified::{Length, LengthOrPercentageOrAuto, ViewportPercentageLength};
 
-#[derive(Copy, Clone, Debug, HeapSizeOf, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub enum ViewportDescriptor {
     MinWidth(ViewportLength),
     MaxWidth(ViewportLength),
 
     MinHeight(ViewportLength),
     MaxHeight(ViewportLength),
 
     Zoom(Zoom),
@@ -40,17 +41,18 @@ pub enum ViewportDescriptor {
 trait FromMeta: Sized {
     fn from_meta (value: &str) -> Option<Self>;
 }
 
 // ViewportLength is a length | percentage | auto | extend-to-zoom
 // See:
 // * http://dev.w3.org/csswg/css-device-adapt/#min-max-width-desc
 // * http://dev.w3.org/csswg/css-device-adapt/#extend-to-zoom
-#[derive(Copy, Clone, Debug, HeapSizeOf, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub enum ViewportLength {
     Specified(LengthOrPercentageOrAuto),
     ExtendToZoom
 }
 
 impl ToCss for ViewportLength {
     fn to_css<W>(&self, dest: &mut W) -> fmt::Result
         where W: fmt::Write
@@ -128,17 +130,18 @@ impl FromMeta for UserZoom {
         })
     }
 }
 
 struct ViewportRuleParser<'a, 'b: 'a> {
     context: &'a ParserContext<'b>
 }
 
-#[derive(Copy, Clone, Debug, HeapSizeOf, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub struct ViewportDescriptorDeclaration {
     pub origin: Origin,
     pub descriptor: ViewportDescriptor,
     pub important: bool
 }
 
 impl ViewportDescriptorDeclaration {
     pub fn new(origin: Origin,
@@ -223,17 +226,18 @@ impl<'a, 'b> DeclarationParser for Viewp
             n if n.eq_ignore_ascii_case("orientation") =>
                 ok!(Orientation(Orientation::parse)),
 
             _ => Err(()),
         }
     }
 }
 
-#[derive(Debug, HeapSizeOf, PartialEq)]
+#[derive(Debug, PartialEq)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub struct ViewportRule {
     pub declarations: Vec<ViewportDescriptorDeclaration>
 }
 
 /// Whitespace as defined by DEVICE-ADAPT § 9.2
 // TODO: should we just use whitespace as defined by HTML5?
 const WHITESPACE: &'static [char] = &['\t', '\n', '\r', ' '];
 
--- a/servo/components/style_traits/Cargo.toml
+++ b/servo/components/style_traits/Cargo.toml
@@ -3,18 +3,21 @@ name = "style_traits"
 version = "0.0.1"
 authors = ["The Servo Project Developers"]
 publish = false
 
 [lib]
 name = "style_traits"
 path = "lib.rs"
 
+[features]
+servo = ["heapsize", "heapsize_plugin", "serde", "serde_macros", "euclid/plugins",
+         "cssparser/heap_size", "cssparser/serde-serialization", "util/servo"]
+
 [dependencies]
 util = {path = "../util"}
-plugins = {path = "../plugins"}
-cssparser = {version = "0.5.4", features = ["heap_size", "serde-serialization"]}
-euclid = {version = "0.6.4", features = ["plugins"]}
-heapsize = "0.3.0"
-heapsize_plugin = "0.1.2"
+cssparser = "0.5.4"
+euclid = "0.6.4"
+heapsize = {version = "0.3.0", optional = true}
+heapsize_plugin = {version = "0.1.2", optional = true}
 rustc-serialize = "0.3"
-serde = "0.7"
-serde_macros = "0.7"
+serde = {version = "0.7", optional = true}
+serde_macros = {version = "0.7", optional = true}
--- a/servo/components/style_traits/cursor.rs
+++ b/servo/components/style_traits/cursor.rs
@@ -3,17 +3,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //! A list of common mouse cursors per CSS3-UI § 8.1.1.
 
 use cssparser::ToCss;
 
 macro_rules! define_cursor {
     ($( $css: expr => $variant: ident = $value: expr, )+) => {
-        #[derive(Clone, Copy, Debug, Deserialize, Eq, HeapSizeOf, PartialEq, Serialize)]
+        #[derive(Clone, Copy, Debug, Eq, PartialEq)]
+        #[cfg_attr(feature = "servo", derive(Deserialize, Serialize, HeapSizeOf))]
         #[repr(u8)]
         pub enum Cursor {
             $( $variant = $value ),+
         }
 
         impl Cursor {
             pub fn from_css_keyword(keyword: &str) -> Result<Cursor, ()> {
                 match_ignore_ascii_case! { keyword,
--- a/servo/components/style_traits/lib.rs
+++ b/servo/components/style_traits/lib.rs
@@ -3,28 +3,29 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //! This module contains shared types and messages for use by devtools/script.
 //! The traits are here instead of in script so that the devtools crate can be
 //! modified independently of the rest of Servo.
 
 #![crate_name = "style_traits"]
 #![crate_type = "rlib"]
-#![feature(custom_derive)]
-#![feature(plugin)]
-#![plugin(heapsize_plugin)]
-#![plugin(serde_macros)]
-#![plugin(plugins)]
+
 #![deny(unsafe_code)]
 
+#![cfg_attr(feature = "servo", feature(custom_derive))]
+#![cfg_attr(feature = "servo", feature(plugin))]
+#![cfg_attr(feature = "servo", plugin(serde_macros))]
+#![cfg_attr(feature = "servo", plugin(heapsize_plugin))]
+
 #[macro_use]
 extern crate cssparser;
 extern crate euclid;
-extern crate heapsize;
+#[cfg(feature = "servo")] extern crate heapsize;
 extern crate rustc_serialize;
-extern crate serde;
+#[cfg(feature = "servo")] extern crate serde;
 extern crate util;
 
 pub mod cursor;
 #[macro_use]
 pub mod values;
 pub mod viewport;
 
--- a/servo/components/style_traits/values.rs
+++ b/servo/components/style_traits/values.rs
@@ -1,21 +1,47 @@
 /* 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/. */
 
 #[macro_export]
 macro_rules! define_css_keyword_enum {
     ($name: ident: $( $css: expr => $variant: ident ),+,) => {
-        define_css_keyword_enum!($name: $( $css => $variant ),+);
+        __define_css_keyword_enum__add_optional_traits!($name [ $( $css => $variant ),+ ]);
     };
     ($name: ident: $( $css: expr => $variant: ident ),+) => {
+        __define_css_keyword_enum__add_optional_traits!($name [ $( $css => $variant ),+ ]);
+    };
+}
+
+#[cfg(feature = "servo")]
+#[macro_export]
+macro_rules! __define_css_keyword_enum__add_optional_traits {
+    ($name: ident [ $( $css: expr => $variant: ident ),+ ]) => {
+        __define_css_keyword_enum__actual! {
+            $name [ Deserialize, Serialize, HeapSizeOf ] [ $( $css => $variant ),+ ]
+        }
+    };
+}
+
+#[cfg(not(feature = "servo"))]
+#[macro_export]
+macro_rules! __define_css_keyword_enum__add_optional_traits {
+    ($name: ident [ $( $css: expr => $variant: ident ),+ ]) => {
+        __define_css_keyword_enum__actual! {
+            $name [] [ $( $css => $variant ),+ ]
+        }
+    };
+}
+
+#[macro_export]
+macro_rules! __define_css_keyword_enum__actual {
+    ($name: ident [ $( $derived_trait: ident),* ] [ $( $css: expr => $variant: ident ),+ ]) => {
         #[allow(non_camel_case_types)]
-        #[derive(Clone, Eq, PartialEq, Copy, Hash, RustcEncodable, Debug, HeapSizeOf)]
-        #[derive(Deserialize, Serialize)]
+        #[derive(Clone, Eq, PartialEq, Copy, Hash, RustcEncodable, Debug $(, $derived_trait )* )]
         pub enum $name {
             $( $variant ),+
         }
 
         impl $name {
             pub fn parse(input: &mut ::cssparser::Parser) -> Result<$name, ()> {
                 match_ignore_ascii_case! { try!(input.expect_ident()),
                                            $( $css => Ok($name::$variant), )+
--- a/servo/components/style_traits/viewport.rs
+++ b/servo/components/style_traits/viewport.rs
@@ -15,17 +15,18 @@ define_css_keyword_enum!(UserZoom:
                          "fixed" => Fixed);
 
 define_css_keyword_enum!(Orientation:
                          "auto" => Auto,
                          "portrait" => Portrait,
                          "landscape" => Landscape);
 
 
-#[derive(Clone, Debug, PartialEq, Deserialize, Serialize, HeapSizeOf)]
+#[derive(Clone, Debug, PartialEq)]
+#[cfg_attr(feature = "servo", derive(Deserialize, Serialize, HeapSizeOf))]
 pub struct ViewportConstraints {
     pub size: TypedSize2D<ViewportPx, f32>,
 
     pub initial_zoom: ScaleFactor<PagePx, ViewportPx, f32>,
     pub min_zoom: Option<ScaleFactor<PagePx, ViewportPx, f32>>,
     pub max_zoom: Option<ScaleFactor<PagePx, ViewportPx, f32>>,
 
     pub user_zoom: UserZoom,
@@ -49,17 +50,18 @@ impl ToCss for ViewportConstraints {
         try!(write!(dest, " user-zoom: ")); try!(self.user_zoom.to_css(dest));
         try!(write!(dest, "; orientation: ")); try!(self.orientation.to_css(dest));
         write!(dest, "; }}")
     }
 }
 
 /// Zoom is a number | percentage | auto
 /// See http://dev.w3.org/csswg/css-device-adapt/#descdef-viewport-zoom
-#[derive(Copy, Clone, Debug, HeapSizeOf, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub enum Zoom {
     Number(f32),
     Percentage(f32),
     Auto,
 }
 
 impl ToCss for Zoom {
     fn to_css<W>(&self, dest: &mut W) -> fmt::Result
--- a/servo/components/util/Cargo.toml
+++ b/servo/components/util/Cargo.toml
@@ -3,36 +3,39 @@ name = "util"
 version = "0.0.1"
 authors = ["The Servo Project Developers"]
 publish = false
 
 [lib]
 name = "util"
 path = "lib.rs"
 
+[features]
+# servo as opposed to geckolib
+servo = ["serde", "serde_macros", "backtrace", "ipc-channel", "app_units/plugins",
+         "euclid/plugins", "euclid/unstable", "url/heap_size", "url/serde"]
+
 [dependencies]
-app_units = {version = "0.2.3", features = ["plugins"]}
-backtrace = "0.2.1"
+app_units = "0.2.3"
+backtrace = {version = "0.2.1", optional = true}
 bitflags = "0.7"
 deque = "0.3.1"
-euclid = {version = "0.6.4", features = ["unstable", "plugins"]}
+euclid = "0.6.4"
 getopts = "0.2.11"
 heapsize = "0.3.0"
-heapsize_plugin = "0.1.2"
-ipc-channel = {git = "https://github.com/servo/ipc-channel"}
+ipc-channel = {git = "https://github.com/servo/ipc-channel", optional = true}
 lazy_static = "0.2"
 libc = "0.2"
 log = "0.3.5"
 num_cpus = "0.2.2"
 num-traits = "0.1.32"
-plugins = {path = "../plugins"}
 rand = "0.3"
 rustc-serialize = "0.3"
-serde = "0.7"
-serde_macros = "0.7"
+serde = {version = "0.7", optional = true}
+serde_macros = {version = "0.7", optional = true}
 smallvec = "0.1"
-url = {version = "1.0.0", features = ["heap_size", "serde"]}
+url = "1.0.0"
 
 [target.'cfg(all(unix, not(target_os = "macos"), not(target_os = "ios"), not(target_os = "android")))'.dependencies]
 xdg = "2.0"
 
 [target.'cfg(windows)'.dependencies]
 kernel32-sys = "0.2"
--- a/servo/components/util/geometry.rs
+++ b/servo/components/util/geometry.rs
@@ -18,40 +18,42 @@ use std::i32;
 ///
 /// The relationship between DevicePixel and ScreenPx is defined by the OS.  On most low-dpi
 /// screens, one ScreenPx is equal to one DevicePixel.  But on high-density screens it can be
 /// some larger number.  For example, by default on Apple "retina" displays, one ScreenPx equals
 /// two DevicePixels.  On Android "MDPI" displays, one ScreenPx equals 1.5 device pixels.
 ///
 /// The ratio between ScreenPx and DevicePixel for a given display be found by calling
 /// `servo::windowing::WindowMethods::hidpi_factor`.
-#[derive(Clone, Copy, Debug, HeapSizeOf)]
+#[derive(Clone, Copy, Debug)]
 pub enum ScreenPx {}
 
 /// One CSS "px" in the coordinate system of the "initial viewport":
 /// http://www.w3.org/TR/css-device-adapt/#initial-viewport
 ///
 /// ViewportPx is equal to ScreenPx times a "page zoom" factor controlled by the user.  This is
 /// the desktop-style "full page" zoom that enlarges content but then reflows the layout viewport
 /// so it still exactly fits the visible area.
 ///
 /// At the default zoom level of 100%, one PagePx is equal to one ScreenPx.  However, if the
 /// document is zoomed in or out then this scale may be larger or smaller.
-#[derive(Clone, Copy, Debug, HeapSizeOf)]
+#[derive(Clone, Copy, Debug)]
 pub enum ViewportPx {}
 
 /// One CSS "px" in the root coordinate system for the content document.
 ///
 /// PagePx is equal to ViewportPx multiplied by a "viewport zoom" factor controlled by the user.
 /// This is the mobile-style "pinch zoom" that enlarges content without reflowing it.  When the
 /// viewport zoom is not equal to 1.0, then the layout viewport is no longer the same physical size
 /// as the viewable area.
-#[derive(Clone, Copy, Debug, HeapSizeOf)]
+#[derive(Clone, Copy, Debug)]
 pub enum PagePx {}
 
+known_heap_size!(0, ScreenPx, ViewportPx, PagePx);
+
 // In summary, the hierarchy of pixel units and the factors to convert from one to the next:
 //
 // DevicePixel
 //   / hidpi_ratio => ScreenPx
 //     / desktop_zoom => ViewportPx
 //       / pinch_zoom => PagePx
 
 // An Au is an "App Unit" and represents 1/60th of a CSS pixel.  It was
--- a/servo/components/util/lib.rs
+++ b/servo/components/util/lib.rs
@@ -1,76 +1,64 @@
 /* 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/. */
 
-#![feature(box_syntax)]
-#![feature(core_intrinsics)]
-#![feature(custom_derive)]
-#![feature(fnbox)]
-#![feature(plugin)]
-#![feature(reflect_marker)]
-#![feature(step_by)]
-
-#![plugin(heapsize_plugin, plugins, serde_macros)]
+#![cfg_attr(feature = "servo", feature(core_intrinsics))]
+#![cfg_attr(feature = "servo", feature(custom_derive))]
+#![cfg_attr(feature = "servo", feature(fnbox))]
+#![cfg_attr(feature = "servo", feature(plugin))]
+#![cfg_attr(feature = "servo", feature(reflect_marker))]
+#![cfg_attr(feature = "servo", plugin(serde_macros))]
 
 #![deny(unsafe_code)]
 
 extern crate app_units;
-extern crate backtrace;
-#[allow(unused_extern_crates)]
-#[macro_use]
-extern crate bitflags;
+#[cfg(feature = "servo")] extern crate backtrace;
+#[allow(unused_extern_crates)] #[macro_use] extern crate bitflags;
 extern crate deque;
 extern crate euclid;
 extern crate getopts;
-extern crate heapsize;
-extern crate ipc_channel;
-#[allow(unused_extern_crates)]
-#[macro_use]
-extern crate lazy_static;
+#[macro_use] extern crate heapsize;
+#[cfg(feature = "servo")] extern crate ipc_channel;
+#[allow(unused_extern_crates)] #[macro_use] extern crate lazy_static;
 extern crate libc;
-#[macro_use]
-extern crate log;
+#[macro_use] extern crate log;
 extern crate num_cpus;
 extern crate num_traits;
 extern crate rand;
 extern crate rustc_serialize;
-extern crate serde;
+#[cfg(feature = "servo")] extern crate serde;
 extern crate smallvec;
 extern crate url;
 #[cfg(all(unix, not(target_os = "macos"), not(target_os = "ios"), not(target_os = "android")))]
 extern crate xdg;
 
 use std::sync::Arc;
 
 pub mod basedir;
 pub mod cache;
-#[allow(unsafe_code)]
-pub mod debug_utils;
+#[allow(unsafe_code)] pub mod debug_utils;
 pub mod geometry;
-#[allow(unsafe_code)]
-pub mod ipc;
-pub mod linked_list;
-#[allow(unsafe_code)]
-pub mod opts;
-pub mod panicking;
+#[cfg(feature = "servo")] #[allow(unsafe_code)] pub mod ipc;
+#[cfg(feature = "servo")] pub mod linked_list;
+#[allow(unsafe_code)] pub mod opts;
+#[cfg(feature = "servo")] pub mod panicking;
 pub mod prefs;
-pub mod print_tree;
+#[cfg(feature = "servo")] pub mod print_tree;
 pub mod resource_files;
-#[allow(unsafe_code)]
 pub mod str;
 pub mod thread;
 pub mod thread_state;
 pub mod tid;
-pub mod time;
+#[cfg(feature = "servo")] pub mod time;
 pub mod vec;
-#[allow(unsafe_code)]
-pub mod workqueue;
+#[allow(unsafe_code)] pub mod workqueue;
 
+#[cfg(feature = "servo")]
 #[allow(unsafe_code)]
 pub fn breakpoint() {
     unsafe { ::std::intrinsics::breakpoint() };
 }
 
 // Workaround for lack of `ptr_eq` on Arcs...
 #[inline]
 pub fn arc_ptr_eq<T: 'static>(a: &Arc<T>, b: &Arc<T>) -> bool {
--- a/servo/components/util/opts.rs
+++ b/servo/components/util/opts.rs
@@ -18,17 +18,18 @@ use std::fs::{self, File};
 use std::io::{self, Read, Write, stderr};
 use std::path::{Path, PathBuf};
 use std::process;
 use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
 use url::{self, Url};
 
 
 /// Global flags for Servo, currently set on the command line.
-#[derive(Clone, Deserialize, Serialize)]
+#[derive(Clone)]
+#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
 pub struct Opts {
     pub is_running_problem_test: bool,
 
     /// The initial URL to load.
     pub url: Option<Url>,
 
     /// How many threads to use for CPU painting (`-t`).
     ///
@@ -374,17 +375,18 @@ pub fn print_debug_usage(app: &str) -> !
     print_option("msaa", "Use multisample antialiasing in WebRender.");
     print_option("full-backtraces", "Print full backtraces for all errors");
 
     println!("");
 
     process::exit(0)
 }
 
-#[derive(Clone, Deserialize, Serialize)]
+#[derive(Clone)]
+#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
 pub enum OutputOptions {
     FileName(String),
     Stdout(f64)
 }
 
 fn args_fail(msg: &str) -> ! {
     let mut stderr = io::stderr();
     stderr.write_all(msg.as_bytes()).unwrap();
@@ -399,17 +401,18 @@ pub fn multiprocess() -> bool {
     MULTIPROCESS.load(Ordering::Relaxed)
 }
 
 enum UserAgent {
     Desktop,
     Android,
 }
 
-#[derive(Clone, Debug, Eq, Deserialize, PartialEq, Serialize)]
+#[derive(Clone, Debug, Eq, PartialEq)]
+#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
 pub enum RenderApi {
     GL,
     ES2,
 }
 
 const DEFAULT_RENDER_API: RenderApi = RenderApi::GL;
 
 fn default_user_agent_string(agent: UserAgent) -> String {
@@ -853,17 +856,17 @@ lazy_static! {
         }
     };
 }
 
 pub fn set_defaults(opts: Opts) {
     unsafe {
         assert!(DEFAULT_OPTIONS.is_null());
         assert!(DEFAULT_OPTIONS != INVALID_OPTIONS);
-        let box_opts = box opts;
+        let box_opts = Box::new(opts);
         DEFAULT_OPTIONS = Box::into_raw(box_opts);
     }
 }
 
 #[inline]
 pub fn get() -> &'static Opts {
     &OPTIONS
 }
--- a/servo/components/util/prefs.rs
+++ b/servo/components/util/prefs.rs
@@ -15,17 +15,18 @@ use std::sync::{Arc, Mutex};
 
 lazy_static! {
     static ref PREFS: Arc<Mutex<HashMap<String, Pref>>> = {
         let prefs = read_prefs().unwrap_or(HashMap::new());
         Arc::new(Mutex::new(prefs))
     };
 }
 
-#[derive(PartialEq, Clone, Debug, Deserialize, Serialize)]
+#[derive(PartialEq, Clone, Debug)]
+#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
 pub enum PrefValue {
     Boolean(bool),
     String(String),
     Number(f64),
     Missing
 }
 
 impl PrefValue {
@@ -86,17 +87,18 @@ impl ToJson for PrefValue {
             PrefValue::Number(x) => {
                 Json::F64(x)
             },
             PrefValue::Missing => Json::Null
         }
     }
 }
 
-#[derive(Clone, Debug, Deserialize, Serialize)]
+#[derive(Clone, Debug)]
+#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
 pub enum Pref {
     NoDefault(Arc<PrefValue>),
     WithDefault(Arc<PrefValue>, Option<Arc<PrefValue>>)
 }
 
 
 impl Pref {
     pub fn new(value: PrefValue) -> Pref {
--- a/servo/components/util/thread.rs
+++ b/servo/components/util/thread.rs
@@ -1,27 +1,28 @@
 /* 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 backtrace::Backtrace;
-use ipc_channel::ipc::IpcSender;
-use panicking;
-use serde::Serialize;
-use std::any::Any;
+#[cfg(feature = "servo")] use backtrace::Backtrace;
+#[cfg(feature = "servo")] use ipc_channel::ipc::IpcSender;
+#[cfg(feature = "servo")] use panicking;
+#[cfg(feature = "servo")] use serde::Serialize;
+#[cfg(feature = "servo")] use std::any::Any;
+#[cfg(feature = "servo")] use thread_state;
 use std::thread;
-use thread_state;
 
 pub fn spawn_named<F>(name: String, f: F)
     where F: FnOnce() + Send + 'static
 {
     thread::Builder::new().name(name).spawn(f).expect("Thread spawn failed");
 }
 
 /// Arrange to send a particular message to a channel if the thread fails.
+#[cfg(feature = "servo")]
 pub fn spawn_named_with_send_on_panic<F, Id>(name: String,
                                              state: thread_state::ThreadState,
                                              f: F,
                                              id: Id,
                                              panic_chan: IpcSender<(Id, String, String)>)
     where F: FnOnce() + Send + 'static,
           Id: Copy + Send + Serialize + 'static,
 {
--- a/servo/components/util/vec.rs
+++ b/servo/components/util/vec.rs
@@ -4,20 +4,23 @@
 
 use std::marker::PhantomData;
 use std::ops;
 use super::smallvec::VecLike;
 
 // TODO(pcwalton): Speed up with SIMD, or better yet, find some way to not do this.
 pub fn byte_swap(data: &mut [u8]) {
     let length = data.len();
-    for i in (0..length).step_by(4) {
+    // FIXME(rust #27741): Range::step_by is not stable yet as of this writing.
+    let mut i = 0;
+    while i < length {
         let r = data[i + 2];
         data[i + 2] = data[i + 0];
         data[i + 0] = r;
+        i += 4;
     }
 }
 
 /// A `VecLike` that only tracks whether or not something was ever pushed to it.
 pub struct ForgetfulSink<T> {
     empty: bool,
     _data: PhantomData<T>,
 }
--- a/servo/ports/cef/Cargo.lock
+++ b/servo/ports/cef/Cargo.lock
@@ -2095,17 +2095,16 @@ dependencies = [
  "euclid 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "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)",
  "lazy_static 0.2.1 (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)",
- "plugins 0.0.1",
  "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_macros 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.1.7 (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)",
@@ -2117,17 +2116,16 @@ dependencies = [
 [[package]]
 name = "style_traits"
 version = "0.0.1"
 dependencies = [
  "cssparser 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "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)",
- "plugins 0.0.1",
  "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_macros 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "util 0.0.1",
 ]
 
 [[package]]
 name = "task_info"
@@ -2302,25 +2300,23 @@ version = "0.0.1"
 dependencies = [
  "app_units 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "backtrace 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "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.2.3 (git+https://github.com/servo/ipc-channel)",
  "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.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 0.2.12 (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)",
  "serde 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_macros 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.1.7 (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)",
 ]
--- a/servo/ports/geckolib/Cargo.lock
+++ b/servo/ports/geckolib/Cargo.lock
@@ -3,22 +3,20 @@ name = "geckoservo"
 version = "0.0.1"
 dependencies = [
  "app_units 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "cssparser 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "gecko_bindings 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)",
  "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "plugins 0.0.1",
  "selectors 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "string_cache 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
  "style 0.0.1",
  "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)",
  "util 0.0.1",
@@ -71,17 +69,17 @@ version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "bincode"
-version = "0.5.6"
+version = "0.5.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -252,25 +250,24 @@ source = "registry+https://github.com/ru
 dependencies = [
  "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "ipc-channel"
-version = "0.2.3"
-source = "git+https://github.com/servo/ipc-channel#48137d69955f5460da586c552de275ecdc3f4efe"
+version = "0.2.4"
+source = "git+https://github.com/servo/ipc-channel#8411eeabf3a712006ad1b47637b2d8fe71177f85"
 dependencies = [
- "bincode 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bincode 0.5.7 (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.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "uuid 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "kernel32-sys"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
@@ -315,23 +312,16 @@ source = "registry+https://github.com/ru
 name = "num_cpus"
 version = "0.2.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
-name = "plugins"
-version = "0.0.1"
-dependencies = [
- "tenacious 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
 name = "quasi"
 version = "0.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "quasi_codegen"
 version = "0.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -463,17 +453,16 @@ dependencies = [
  "fnv 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "gecko_bindings 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)",
  "lazy_static 0.2.1 (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)",
- "plugins 0.0.1",
  "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_macros 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.1.7 (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)",
@@ -485,29 +474,23 @@ dependencies = [
 [[package]]
 name = "style_traits"
 version = "0.0.1"
 dependencies = [
  "cssparser 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "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)",
- "plugins 0.0.1",
  "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_macros 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "util 0.0.1",
 ]
 
 [[package]]
-name = "tenacious"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
 name = "thread-id"
 version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -576,25 +559,23 @@ version = "0.0.1"
 dependencies = [
  "app_units 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "backtrace 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "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.2.3 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.4 (git+https://github.com/servo/ipc-channel)",
  "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.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 0.2.12 (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)",
  "serde 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_macros 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.1.7 (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)",
 ]
--- a/servo/ports/geckolib/Cargo.toml
+++ b/servo/ports/geckolib/Cargo.toml
@@ -12,38 +12,38 @@ crate-type = ["staticlib"]
 
 [features]
 default = ["servo_features"]
 
 # Features that aren't actually required for geckolib, but match the ones used
 # in the full Servo build.  Enabling this reduces the number of things
 # recompiled when building both Servo and geckolib in the same source tree.
 servo_features = [
+  "heapsize",
+  "style/servo",
   "time",
   "url/query_encoding",
   "url/rustc-serialize",
   "uuid",
 ]
 
 [dependencies]
 app_units = "0.2.3"
 cssparser = "0.5.4"
 euclid = "0.6.4"
 gecko_bindings = {version = "0.0.1", path = "gecko_bindings"}
-heapsize = "0.3.0"
-heapsize_plugin = "0.1.2"
+heapsize = {version = "0.3.0", optional = true}
 lazy_static = "0.2"
 libc = "0.2"
 num_cpus = "0.2.2"
 selectors = {version = "0.6", features = ["unstable"]}
 smallvec = "0.1"
 string_cache = {version = "0.2.20", features = ["unstable"]}
 url = "1.0.0"
 log = {version = "0.3.5", features = ["release_max_level_info"]}
-plugins = {path = "../../components/plugins"}
 time = {version = "0.1", optional = true, features = ["rustc-serialize"]}
 util = {path = "../../components/util"}
 uuid = {version = "0.2", optional = true, features = ["v4", "serde"]}
 style = {path = "../../components/style", features = ["gecko"]}
 style_traits = {path = "../../components/style_traits"}
 env_logger = "0.3"
 
 [replace]
--- a/servo/ports/geckolib/gecko_bindings/lib.rs
+++ b/servo/ports/geckolib/gecko_bindings/lib.rs
@@ -1,15 +1,13 @@
 /* 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/. */
 
 #![feature(const_fn)]
-#![feature(concat_idents)]
-#![feature(type_macros)]
 
 extern crate heapsize;
 
 #[allow(dead_code, non_camel_case_types)]
 pub mod bindings;
 pub mod ptr;
 #[cfg(debug_assertions)]
 #[allow(dead_code, non_camel_case_types, non_snake_case, non_upper_case_globals)]
--- a/servo/ports/geckolib/gecko_bindings/ptr.rs
+++ b/servo/ports/geckolib/gecko_bindings/ptr.rs
@@ -5,26 +5,26 @@
 use bindings::*;
 use heapsize::HeapSizeOf;
 use std::fmt::{self, Debug};
 
 // Defines an Arc-like type that manages a refcounted Gecko object stored
 // in a ThreadSafeFooHolder smart pointer.  Used in tandem with the
 // NS_DECL_HOLDER_FFI_REFCOUNTING-defined types and functions in Gecko.
 macro_rules! define_holder_arc {
-    ($arc_type:ident, $name:ident, $holder_type:ident) => (
+    ($arc_type:ident, $name:ident, $holder_type:ident, $addref: ident, $release: ident) => (
         #[derive(PartialEq)]
         pub struct $arc_type {
             ptr: *mut $holder_type,
         }
 
         impl $arc_type {
             pub fn new(data: *mut $holder_type) -> $arc_type {
                 debug_assert!(!data.is_null());
-                unsafe { concat_idents!(Gecko_AddRef, $name, ArbitraryThread)(data); }
+                unsafe { $addref(data); }
                 $arc_type {
                     ptr: data
                 }
             }
 
             pub fn as_raw(&self) -> *mut $holder_type { self.ptr }
         }
 
@@ -34,26 +34,28 @@ macro_rules! define_holder_arc {
         impl Clone for $arc_type {
             fn clone(&self) -> $arc_type {
                 $arc_type::new(self.ptr)
             }
         }
 
         impl Drop for $arc_type {
             fn drop(&mut self) {
-                unsafe { concat_idents!(Gecko_Release, $name, ArbitraryThread)(self.ptr); }
+                unsafe { $release(self.ptr); }
             }
         }
 
         impl HeapSizeOf for $arc_type {
             fn heap_size_of_children(&self) -> usize { 0 }
         }
 
         impl Debug for $arc_type {
             fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                 write!(f, stringify!($name))
             }
         }
     )
 }
 
-define_holder_arc!(GeckoArcPrincipal, Principal, ThreadSafePrincipalHolder);
-define_holder_arc!(GeckoArcURI, URI, ThreadSafeURIHolder);
+define_holder_arc!(GeckoArcPrincipal, Principal, ThreadSafePrincipalHolder,
+                   Gecko_AddRefPrincipalArbitraryThread, Gecko_ReleasePrincipalArbitraryThread);
+define_holder_arc!(GeckoArcURI, URI, ThreadSafeURIHolder,
+                   Gecko_AddRefURIArbitraryThread, Gecko_ReleaseURIArbitraryThread);
--- a/servo/ports/geckolib/lib.rs
+++ b/servo/ports/geckolib/lib.rs
@@ -1,28 +1,21 @@
 /* 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/. */
 
 #![feature(as_unsafe_cell)]
-#![feature(box_syntax)]
-#![feature(custom_attribute)]
-#![feature(custom_derive)]
-#![feature(plugin)]
-
-#![plugin(heapsize_plugin)]
-#![plugin(plugins)]
 
 extern crate app_units;
 #[macro_use]
 extern crate cssparser;
 extern crate env_logger;
 extern crate euclid;
 extern crate gecko_bindings;
-extern crate heapsize;
+#[cfg(feature = "servo_features")] #[macro_use] extern crate heapsize;
 #[macro_use]
 extern crate lazy_static;
 extern crate libc;
 #[macro_use]
 extern crate log;
 extern crate num_cpus;
 extern crate selectors;
 extern crate smallvec;
--- a/servo/ports/geckolib/properties.mako.rs
+++ b/servo/ports/geckolib/properties.mako.rs
@@ -131,17 +131,16 @@ impl ComputedValues for GeckoComputedVal
     fn set_writing_mode(&mut self, mode: WritingMode) { self.writing_mode = mode; }
 
     // FIXME(bholley): Implement this properly.
     #[inline]
     fn is_multicol(&self) -> bool { false }
 }
 
 <%def name="declare_style_struct(style_struct)">
-#[derive(HeapSizeOf)]
 pub struct ${style_struct.gecko_struct_name} {
     gecko: ${style_struct.gecko_ffi_name},
 }
 </%def>
 
 <%def name="impl_simple_setter(ident, gecko_ffi_name)">
     fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
         ${set_gecko_property(gecko_ffi_name, "v")}
--- a/servo/ports/geckolib/selector_impl.rs
+++ b/servo/ports/geckolib/selector_impl.rs
@@ -8,19 +8,22 @@ use style;
 use style::element_state::ElementState;
 use style::selector_impl::{PseudoElementCascadeType, SelectorImplExt};
 
 pub type Stylist = style::selector_matching::Stylist<GeckoSelectorImpl>;
 pub type Stylesheet = style::stylesheets::Stylesheet<GeckoSelectorImpl>;
 pub type SharedStyleContext = style::context::SharedStyleContext<GeckoSelectorImpl>;
 pub type PrivateStyleData = style::data::PrivateStyleData<GeckoSelectorImpl, GeckoComputedValues>;
 
+#[cfg(feature = "servo_features")]
+known_heap_size!(0, GeckoSelectorImpl, PseudoElement, NonTSPseudoClass);
+
 pub struct GeckoSelectorImpl;
 
-#[derive(Clone, Debug, PartialEq, Eq, HeapSizeOf, Hash)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
 pub enum PseudoElement {
     Before,
     After,
 
     Backdrop,
     FirstLetter,
     FirstLine,
     MozSelection,
@@ -41,17 +44,17 @@ pub enum PseudoElement {
     MozMeterBar,
     MozPlaceholder,
     MozColorSwatch,
 
     AnonBox(AnonBoxPseudoElement),
 }
 
 // https://mxr.mozilla.org/mozilla-central/source/layout/style/nsCSSAnonBoxList.h
-#[derive(Clone, Debug, PartialEq, Eq, HeapSizeOf, Hash)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
 pub enum AnonBoxPseudoElement {
     MozNonElement,
     MozAnonymousBlock,
     MozAnonymousPositionedBlock,
     MozMathMLAnonymousBlock,
     MozXULAnonymousBlock,
 
     MozHorizontalFramesetBorder,
@@ -109,17 +112,17 @@ pub enum AnonBoxPseudoElement {
     MozTreeDropFeedback,
 
     MozSVGMarkerAnonChild,
     MozSVGOuterSVGAnonChild,
     MozSVGForeignContent,
     MozSVGText,
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, HeapSizeOf, Hash)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
 pub enum NonTSPseudoClass {
     AnyLink,
     Link,
     Visited,
     Active,
     Focus,
     Hover,
     Enabled,
--- a/servo/ports/geckolib/wrapper.rs
+++ b/servo/ports/geckolib/wrapper.rs
@@ -80,17 +80,17 @@ impl<'ln> GeckoNode<'ln> {
         unsafe {
             Gecko_GetNodeData(self.node) as NonOpaqueStyleData
         }
     }
 
     pub fn initialize_data(self) {
         unsafe {
             if self.get_node_data().is_null() {
-                let ptr: NonOpaqueStyleData = Box::into_raw(box RefCell::new(PrivateStyleData::new()));
+                let ptr: NonOpaqueStyleData = Box::into_raw(Box::new(RefCell::new(PrivateStyleData::new())));
                 Gecko_SetNodeData(self.node, ptr as *mut ServoNodeData);
             }
         }
     }
 }
 
 #[derive(Clone, Copy)]
 pub struct DummyRestyleDamage;