servo: Merge #17345 - Upgrade cssparser to 0.15 (from servo:cssparserup); r=<try>
authorSimon Sapin <simon.sapin@exyr.org>
Fri, 16 Jun 2017 06:09:52 -0700
changeset 364386 49dfd9859718e1b8c7158727e2be93ec562b116a
parent 364385 4dffb09212c01524915b648e592ca44259a52af8
child 364387 c1a32a092c6c1f08e261c70e84c56cdf2cb50b86
push id32039
push userkwierso@gmail.com
push dateSat, 17 Jun 2017 00:15:12 +0000
treeherdermozilla-central@dfb091ee151a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
servo: Merge #17345 - Upgrade cssparser to 0.15 (from servo:cssparserup); r=<try> Depends on https://github.com/servo/rust-cssparser/pull/159 Source-Repo: https://github.com/servo/servo Source-Revision: 75876a0e2220b7b95541feef4393288b195b090e
servo/Cargo.lock
servo/components/canvas/Cargo.toml
servo/components/canvas_traits/Cargo.toml
servo/components/script/Cargo.toml
servo/components/script/dom/bindings/str.rs
servo/components/script_layout_interface/Cargo.toml
servo/components/selectors/Cargo.toml
servo/components/selectors/parser.rs
servo/components/style/Cargo.toml
servo/components/style/counter_style/mod.rs
servo/components/style/custom_properties.rs
servo/components/style/error_reporting.rs
servo/components/style/font_face.rs
servo/components/style/gecko/media_queries.rs
servo/components/style/gecko/selector_parser.rs
servo/components/style/gecko/url.rs
servo/components/style/properties/declaration_block.rs
servo/components/style/properties/longhand/effects.mako.rs
servo/components/style/properties/longhand/list.mako.rs
servo/components/style/properties/properties.mako.rs
servo/components/style/servo/selector_parser.rs
servo/components/style/servo/url.rs
servo/components/style/stylesheets/keyframes_rule.rs
servo/components/style/stylesheets/rule_parser.rs
servo/components/style/stylesheets/viewport_rule.rs
servo/components/style/values/mod.rs
servo/components/style/values/specified/calc.rs
servo/components/style/values/specified/color.rs
servo/components/style/values/specified/grid.rs
servo/components/style/values/specified/image.rs
servo/components/style/values/specified/length.rs
servo/components/style/values/specified/mod.rs
servo/components/style_traits/Cargo.toml
servo/components/style_traits/lib.rs
servo/components/style_traits/viewport.rs
servo/ports/geckolib/Cargo.toml
servo/ports/geckolib/glue.rs
servo/tests/unit/gfx/Cargo.toml
servo/tests/unit/style/Cargo.toml
servo/tests/unit/style/parsing/mod.rs
servo/tests/unit/style/properties/mod.rs
servo/tests/unit/stylo/Cargo.toml
--- a/servo/Cargo.lock
+++ b/servo/Cargo.lock
@@ -307,32 +307,32 @@ version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "canvas"
 version = "0.0.1"
 dependencies = [
  "azure 0.19.0 (git+https://github.com/servo/rust-azure)",
  "canvas_traits 0.0.1",
- "cssparser 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "gleam 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "ipc-channel 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "offscreen_gl_context 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "servo_config 0.0.1",
  "webrender_traits 0.43.0 (git+https://github.com/servo/webrender)",
 ]
 
 [[package]]
 name = "canvas_traits"
 version = "0.0.1"
 dependencies = [
- "cssparser 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "ipc-channel 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "webrender_traits 0.43.0 (git+https://github.com/servo/webrender)",
 ]
 
@@ -567,17 +567,17 @@ source = "registry+https://github.com/ru
 dependencies = [
  "core-foundation 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cssparser"
-version = "0.15.0"
+version = "0.16.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "procedural-masquerade 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -994,17 +994,17 @@ dependencies = [
  "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "geckoservo"
 version = "0.0.1"
 dependencies = [
  "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cssparser 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "nsstring_vendor 0.1.0",
  "parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.19.0",
  "style 0.0.1",
  "style_traits 0.0.1",
@@ -1060,17 +1060,17 @@ dependencies = [
  "xi-unicode 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "xml5ever 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "gfx_tests"
 version = "0.0.1"
 dependencies = [
- "cssparser 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "gfx 0.0.1",
  "ipc-channel 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "style 0.0.1",
 ]
 
 [[package]]
 name = "gfx_traits"
 version = "0.0.1"
@@ -2356,17 +2356,17 @@ dependencies = [
  "base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bluetooth_traits 0.0.1",
  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "canvas_traits 0.0.1",
  "caseless 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "cmake 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "cookie 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "cssparser 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "deny_public_fields 0.0.1",
  "devtools_traits 0.0.1",
  "dom_struct 0.0.1",
  "domobject_derive 0.0.1",
  "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "gfx_traits 0.0.1",
@@ -2429,17 +2429,17 @@ dependencies = [
 
 [[package]]
 name = "script_layout_interface"
 version = "0.0.1"
 dependencies = [
  "app_units 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "canvas_traits 0.0.1",
- "cssparser 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "gfx_traits 0.0.1",
  "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "html5ever 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "ipc-channel 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2500,17 +2500,17 @@ dependencies = [
  "webvr_traits 0.0.1",
 ]
 
 [[package]]
 name = "selectors"
 version = "0.19.0"
 dependencies = [
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cssparser 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "precomputed-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "servo_arc 0.0.1",
  "size_of_test 0.0.1",
@@ -2892,17 +2892,17 @@ dependencies = [
  "arraydeque 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "arrayvec 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bindgen 0.25.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cssparser 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "html5ever 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2945,17 +2945,17 @@ dependencies = [
 ]
 
 [[package]]
 name = "style_tests"
 version = "0.0.1"
 dependencies = [
  "app_units 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cssparser 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "html5ever 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.19.0",
  "servo_atoms 0.0.1",
  "servo_config 0.0.1",
@@ -2966,30 +2966,30 @@ dependencies = [
 ]
 
 [[package]]
 name = "style_traits"
 version = "0.0.1"
 dependencies = [
  "app_units 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cssparser 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.19.0",
  "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "stylo_tests"
 version = "0.0.1"
 dependencies = [
  "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cssparser 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "geckoservo 0.0.1",
  "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.19.0",
  "size_of_test 0.0.1",
  "style 0.0.1",
@@ -3559,17 +3559,17 @@ dependencies = [
 "checksum cocoa 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d3fa729f0b38d496bcff4564c4cacd99f890e15c2235cc11ae8f4583d36c55"
 "checksum color_quant 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a475fc4af42d83d28adf72968d9bcfaf035a1a9381642d8e85d8a04957767b0d"
 "checksum compiletest_rs 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "df47edea8bf052f23ce25a15cbf0be09c96911e3be943d1e81415bfaf0e74bf8"
 "checksum cookie 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30b3493e12a550c2f96be785088d1da8d93189e7237c8a8d0d871bc9070334c3"
 "checksum core-foundation 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f51ce3b8ebe311c56de14231eb57572c15abebd2d32b3bcb99bcdb9c101f5ac3"
 "checksum core-foundation-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "41115a6aa5d3e1e5ef98148373f25971d1fad53818553f216495f9e67e90a624"
 "checksum core-graphics 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a9f841e9637adec70838c537cae52cb4c751cc6514ad05669b51d107c2021c79"
 "checksum core-text 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74ba2a7abdccb94fb6c00822addef48504182b285aa45a30e78286487888fcb4"
-"checksum cssparser 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd54cdee668d71d20e9f8b9676e2e969968d186ab20a101af59c28398393a2b0"
+"checksum cssparser 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c711c0c610b1e5fc2bf96e325b2d9f85839a8e71f6279a77c194af5dcafa502"
 "checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df"
 "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850"
 "checksum dbus 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4aee01fb76ada3e5e7ca642ea6664ebf7308a810739ca2aca44909a1191ac254"
 "checksum debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a032eac705ca39214d169f83e3d3da290af06d8d1d344d1baad2fd002dca4b3"
 "checksum deflate 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ebb02aaf4b775afc96684b8402510a338086974e38570a1f65bea8c202eb77a7"
 "checksum device 0.0.1 (git+https://github.com/servo/devices)" = "<none>"
 "checksum dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80c8b71fd71146990a9742fc06dcbbde19161a267e0ad4e572c35162f4578c90"
 "checksum dwmapi-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07c4c7cc7b396419bc0a4d90371d0cee16cb5053b53647d287c0b728000c41fe"
--- a/servo/components/canvas/Cargo.toml
+++ b/servo/components/canvas/Cargo.toml
@@ -7,17 +7,17 @@ publish = false
 
 [lib]
 name = "canvas"
 path = "lib.rs"
 
 [dependencies]
 azure = {git = "https://github.com/servo/rust-azure"}
 canvas_traits = {path = "../canvas_traits"}
-cssparser = "0.15"
+cssparser = "0.16"
 euclid = "0.15"
 gleam = "0.4"
 ipc-channel = "0.8"
 log = "0.3.5"
 num-traits = "0.1.32"
 offscreen_gl_context = { version = "0.11", features = ["serde"] }
 servo_config = {path = "../config"}
 webrender_traits = {git = "https://github.com/servo/webrender", features = ["ipc"]}
--- a/servo/components/canvas_traits/Cargo.toml
+++ b/servo/components/canvas_traits/Cargo.toml
@@ -5,15 +5,15 @@ authors = ["The Servo Project Developers
 license = "MPL-2.0"
 publish = false
 
 [lib]
 name = "canvas_traits"
 path = "lib.rs"
 
 [dependencies]
-cssparser = "0.15"
+cssparser = "0.16"
 euclid = "0.15"
 heapsize = "0.4"
 heapsize_derive = "0.1"
 ipc-channel = "0.8"
 serde = "1.0"
 webrender_traits = {git = "https://github.com/servo/webrender", features = ["ipc"]}
--- a/servo/components/script/Cargo.toml
+++ b/servo/components/script/Cargo.toml
@@ -30,17 +30,17 @@ audio-video-metadata = "0.1.2"
 atomic_refcell = "0.1"
 base64 = "0.5.2"
 bitflags = "0.7"
 bluetooth_traits = {path = "../bluetooth_traits"}
 byteorder = "1.0"
 canvas_traits = {path = "../canvas_traits"}
 caseless = "0.1.0"
 cookie = "0.6"
-cssparser = "0.15"
+cssparser = "0.16"
 deny_public_fields = {path = "../deny_public_fields"}
 devtools_traits = {path = "../devtools_traits"}
 dom_struct = {path = "../dom_struct"}
 domobject_derive = {path = "../domobject_derive"}
 encoding = "0.2"
 euclid = "0.15"
 fnv = "1.0"
 gleam = "0.4"
--- a/servo/components/script/dom/bindings/str.rs
+++ b/servo/components/script/dom/bindings/str.rs
@@ -1,14 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //! The `ByteString` struct.
 
+use cssparser::CompactCowStr;
 use html5ever::{LocalName, Namespace};
 use servo_atoms::Atom;
 use std::ascii::AsciiExt;
 use std::borrow::{Borrow, Cow, ToOwned};
 use std::fmt;
 use std::hash::{Hash, Hasher};
 use std::ops;
 use std::ops::{Deref, DerefMut};
@@ -293,13 +294,19 @@ impl Into<Vec<u8>> for DOMString {
 }
 
 impl<'a> Into<Cow<'a, str>> for DOMString {
     fn into(self) -> Cow<'a, str> {
         self.0.into()
     }
 }
 
+impl<'a> Into<CompactCowStr<'a>> for DOMString {
+    fn into(self) -> CompactCowStr<'a> {
+        self.0.into()
+    }
+}
+
 impl Extend<char> for DOMString {
     fn extend<I>(&mut self, iterable: I) where I: IntoIterator<Item=char> {
         self.0.extend(iterable)
     }
 }
--- a/servo/components/script_layout_interface/Cargo.toml
+++ b/servo/components/script_layout_interface/Cargo.toml
@@ -8,17 +8,17 @@ publish = false
 [lib]
 name = "script_layout_interface"
 path = "lib.rs"
 
 [dependencies]
 app_units = "0.5"
 atomic_refcell = "0.1"
 canvas_traits = {path = "../canvas_traits"}
-cssparser = "0.15"
+cssparser = "0.16"
 euclid = "0.15"
 gfx_traits = {path = "../gfx_traits"}
 heapsize = "0.4"
 heapsize_derive = "0.1"
 html5ever = "0.18"
 ipc-channel = "0.8"
 libc = "0.2"
 log = "0.3.5"
--- a/servo/components/selectors/Cargo.toml
+++ b/servo/components/selectors/Cargo.toml
@@ -19,17 +19,17 @@ path = "lib.rs"
 doctest = false
 
 [features]
 gecko_like_types = []
 
 [dependencies]
 bitflags = "0.7"
 matches = "0.1"
-cssparser = "0.15"
+cssparser = "0.16"
 log = "0.3"
 fnv = "1.0"
 phf = "0.7.18"
 precomputed-hash = "0.1"
 servo_arc = { path = "../servo_arc" }
 smallvec = "0.4"
 
 [dev-dependencies]
--- a/servo/components/selectors/parser.rs
+++ b/servo/components/selectors/parser.rs
@@ -1,16 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use attr::{AttrSelectorWithNamespace, ParsedAttrSelectorOperation, AttrSelectorOperator};
 use attr::{ParsedCaseSensitivity, SELECTOR_WHITESPACE, NamespaceConstraint};
 use bloom::BLOOM_HASH_MASK;
-use cssparser::{ParseError, BasicParseError};
+use cssparser::{ParseError, BasicParseError, CompactCowStr};
 use cssparser::{Token, Parser as CssParser, parse_nth, ToCss, serialize_identifier, CssStringWriter};
 use precomputed_hash::PrecomputedHash;
 use servo_arc::{Arc, HeaderWithLength, ThinArc};
 use smallvec::SmallVec;
 use std::ascii::AsciiExt;
 use std::borrow::{Borrow, Cow};
 use std::cmp;
 use std::fmt::{self, Display, Debug, Write};
@@ -53,17 +53,17 @@ pub enum SelectorParseError<'i, T> {
     NegationSelectorComponentNotNamespace,
     NegationSelectorComponentNotLocalName,
     EmptySelector,
     NonSimpleSelectorInNegation,
     UnexpectedTokenInAttributeSelector,
     PseudoElementExpectedColon,
     PseudoElementExpectedIdent,
     UnsupportedPseudoClass,
-    UnexpectedIdent(Cow<'i, str>),
+    UnexpectedIdent(CompactCowStr<'i>),
     ExpectedNamespace,
     Custom(T),
 }
 
 impl<'a, T> Into<ParseError<'a, SelectorParseError<'a, T>>> for SelectorParseError<'a, T> {
     fn into(self) -> ParseError<'a, SelectorParseError<'a, T>> {
         ParseError::Custom(self)
     }
@@ -128,31 +128,31 @@ with_bounds! {
 }
 
 pub trait Parser<'i> {
     type Impl: SelectorImpl;
     type Error: 'i;
 
     /// This function can return an "Err" pseudo-element in order to support CSS2.1
     /// pseudo-elements.
-    fn parse_non_ts_pseudo_class(&self, name: Cow<'i, str>)
+    fn parse_non_ts_pseudo_class(&self, name: CompactCowStr<'i>)
                                  -> Result<<Self::Impl as SelectorImpl>::NonTSPseudoClass,
                                            ParseError<'i, SelectorParseError<'i, Self::Error>>> {
         Err(ParseError::Custom(SelectorParseError::UnexpectedIdent(name)))
     }
 
     fn parse_non_ts_functional_pseudo_class<'t>
-        (&self, name: Cow<'i, str>, _arguments: &mut CssParser<'i, 't>)
+        (&self, name: CompactCowStr<'i>, _arguments: &mut CssParser<'i, 't>)
          -> Result<<Self::Impl as SelectorImpl>::NonTSPseudoClass,
                    ParseError<'i, SelectorParseError<'i, Self::Error>>>
     {
         Err(ParseError::Custom(SelectorParseError::UnexpectedIdent(name)))
     }
 
-    fn parse_pseudo_element(&self, name: Cow<'i, str>)
+    fn parse_pseudo_element(&self, name: CompactCowStr<'i>)
                             -> Result<<Self::Impl as SelectorImpl>::PseudoElement,
                                       ParseError<'i, SelectorParseError<'i, Self::Error>>> {
         Err(ParseError::Custom(SelectorParseError::UnexpectedIdent(name)))
     }
 
     fn default_namespace(&self) -> Option<<Self::Impl as SelectorImpl>::NamespaceUrl> {
         None
     }
@@ -1147,17 +1147,17 @@ fn parse_type_selector<'i, 't, P, E, Imp
                 QNamePrefix::ImplicitNoNamespace => {
                     unreachable!()  // Not returned with in_attr_selector = false
                 }
             }
             match local_name {
                 Some(name) => {
                     sequence.push(Component::LocalName(LocalName {
                         lower_name: from_cow_str(to_ascii_lowercase(&name)),
-                        name: from_cow_str(name),
+                        name: from_cow_str(name.into()),
                     }))
                 }
                 None => {
                     sequence.push(Component::ExplicitUniversalType)
                 }
             }
             Ok(true)
         }
@@ -1181,17 +1181,17 @@ enum QNamePrefix<Impl: SelectorImpl> {
 }
 
 /// * `Err(())`: Invalid selector, abort
 /// * `Ok(None)`: Not a simple selector, could be something else. `input` was not consumed.
 /// * `Ok(Some((namespace, local_name)))`: `None` for the local name means a `*` universal selector
 fn parse_qualified_name<'i, 't, P, E, Impl>
                        (parser: &P, input: &mut CssParser<'i, 't>,
                         in_attr_selector: bool)
-                        -> Result<Option<(QNamePrefix<Impl>, Option<Cow<'i, str>>)>,
+                        -> Result<Option<(QNamePrefix<Impl>, Option<CompactCowStr<'i>>)>,
                                   ParseError<'i, SelectorParseError<'i, E>>>
     where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl
 {
     let default_namespace = |local_name| {
         let namespace = match parser.default_namespace() {
             Some(url) => QNamePrefix::ImplicitDefaultNamespace(url),
             None => QNamePrefix::ImplicitAnyNamespace,
         };
@@ -1212,17 +1212,17 @@ fn parse_qualified_name<'i, 't, P, E, Im
     };
 
     let position = input.position();
     match input.next_including_whitespace() {
         Ok(Token::Ident(value)) => {
             let position = input.position();
             match input.next_including_whitespace() {
                 Ok(Token::Delim('|')) => {
-                    let prefix = from_cow_str(value);
+                    let prefix = from_cow_str(value.into());
                     let result = parser.namespace_for_prefix(&prefix);
                     let url = result.ok_or(ParseError::Custom(SelectorParseError::ExpectedNamespace))?;
                     explicit_namespace(input, QNamePrefix::ExplicitNamespace(prefix, url))
                 },
                 _ => {
                     input.reset(position);
                     if in_attr_selector {
                         Ok(Some((QNamePrefix::ImplicitNoNamespace, Some(value))))
@@ -1295,17 +1295,17 @@ fn parse_attribute_selector<'i, 't, P, E
 
     let operator;
     let value;
     let never_matches;
     match input.next() {
         // [foo]
         Err(_) => {
             let local_name_lower = from_cow_str(to_ascii_lowercase(&local_name));
-            let local_name = from_cow_str(local_name);
+            let local_name = from_cow_str(local_name.into());
             if let Some(namespace) = namespace {
                 return Ok(Component::AttributeOther(Box::new(AttrSelectorWithNamespace {
                     namespace: namespace,
                     local_name: local_name,
                     local_name_lower: local_name_lower,
                     operation: ParsedAttrSelectorOperation::Exists,
                     never_matches: false,
                 })))
@@ -1353,32 +1353,32 @@ fn parse_attribute_selector<'i, 't, P, E
             never_matches = value.is_empty();
             operator = AttrSelectorOperator::Suffix;
         }
         _ => return Err(SelectorParseError::UnexpectedTokenInAttributeSelector.into())
     }
 
     let mut case_sensitivity = parse_attribute_flags(input)?;
 
-    let value = from_cow_str(value);
+    let value = from_cow_str(value.into());
     let local_name_lower;
     {
         let local_name_lower_cow = to_ascii_lowercase(&local_name);
         if let ParsedCaseSensitivity::CaseSensitive = case_sensitivity {
             if namespace.is_none() &&
                 include!(concat!(env!("OUT_DIR"), "/ascii_case_insensitive_html_attributes.rs"))
                 .contains(&*local_name_lower_cow)
             {
                 case_sensitivity =
                     ParsedCaseSensitivity::AsciiCaseInsensitiveIfInHtmlElementInHtmlDocument
             }
         }
-        local_name_lower = from_cow_str(local_name_lower_cow);
+        local_name_lower = from_cow_str(local_name_lower_cow.into());
     }
-    let local_name = from_cow_str(local_name);
+    let local_name = from_cow_str(local_name.into());
     if let Some(namespace) = namespace {
         Ok(Component::AttributeOther(Box::new(AttrSelectorWithNamespace {
             namespace: namespace,
             local_name: local_name,
             local_name_lower: local_name_lower,
             never_matches: never_matches,
             operation: ParsedAttrSelectorOperation::WithValue {
                 operator: operator,
@@ -1546,17 +1546,17 @@ fn parse_compound_selector<'i, 't, P, E,
         Err(ParseError::Custom(SelectorParseError::EmptySelector))
     } else {
         Ok(pseudo)
     }
 }
 
 fn parse_functional_pseudo_class<'i, 't, P, E, Impl>(parser: &P,
                                                      input: &mut CssParser<'i, 't>,
-                                                     name: Cow<'i, str>,
+                                                     name: CompactCowStr<'i>,
                                                      inside_negation: bool)
                                                      -> Result<Component<Impl>,
                                                                ParseError<'i, SelectorParseError<'i, E>>>
     where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl
 {
     match_ignore_ascii_case! { &name,
         "nth-child" => return parse_nth_pseudo_class(input, Component::NthChild),
         "nth-of-type" => return parse_nth_pseudo_class(input, Component::NthOfType),
@@ -1594,23 +1594,23 @@ fn parse_one_simple_selector<'i, 't, P, 
                                                  inside_negation: bool)
                                                  -> Result<Option<SimpleSelectorParseResult<Impl>>,
                                                            ParseError<'i, SelectorParseError<'i, E>>>
     where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl
 {
     let start_position = input.position();
     match input.next_including_whitespace() {
         Ok(Token::IDHash(id)) => {
-            let id = Component::ID(from_cow_str(id));
+            let id = Component::ID(from_cow_str(id.into()));
             Ok(Some(SimpleSelectorParseResult::SimpleSelector(id)))
         }
         Ok(Token::Delim('.')) => {
             match input.next_including_whitespace() {
                 Ok(Token::Ident(class)) => {
-                    let class = Component::Class(from_cow_str(class));
+                    let class = Component::Class(from_cow_str(class.into()));
                     Ok(Some(SimpleSelectorParseResult::SimpleSelector(class)))
                 }
                 Ok(t) => Err(ParseError::Basic(BasicParseError::UnexpectedToken(t))),
                 Err(e) => Err(ParseError::Basic(e)),
             }
         }
         Ok(Token::SquareBracketBlock) => {
             let attr = input.parse_nested_block(|input| parse_attribute_selector(parser, input))?;
@@ -1654,17 +1654,17 @@ fn parse_one_simple_selector<'i, 't, P, 
         }
         _ => {
             input.reset(start_position);
             Ok(None)
         }
     }
 }
 
-fn parse_simple_pseudo_class<'i, P, E, Impl>(parser: &P, name: Cow<'i, str>)
+fn parse_simple_pseudo_class<'i, P, E, Impl>(parser: &P, name: CompactCowStr<'i>)
                                              -> Result<Component<Impl>,
                                                        ParseError<'i, SelectorParseError<'i, E>>>
     where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl
 {
     (match_ignore_ascii_case! { &name,
         "first-child" => Ok(Component::FirstChild),
         "last-child"  => Ok(Component::LastChild),
         "only-child"  => Ok(Component::OnlyChild),
@@ -1799,37 +1799,37 @@ pub mod tests {
             return 0
         }
     }
 
     impl<'i> Parser<'i> for DummyParser {
         type Impl = DummySelectorImpl;
         type Error = ();
 
-        fn parse_non_ts_pseudo_class(&self, name: Cow<'i, str>)
+        fn parse_non_ts_pseudo_class(&self, name: CompactCowStr<'i>)
                                      -> Result<PseudoClass,
                                                ParseError<'i, SelectorParseError<'i, ()>>> {
             match_ignore_ascii_case! { &name,
                 "hover" => Ok(PseudoClass::Hover),
                 "active" => Ok(PseudoClass::Active),
                 _ => Err(SelectorParseError::Custom(()).into())
             }
         }
 
-        fn parse_non_ts_functional_pseudo_class<'t>(&self, name: Cow<'i, str>,
+        fn parse_non_ts_functional_pseudo_class<'t>(&self, name: CompactCowStr<'i>,
                                                     parser: &mut CssParser<'i, 't>)
                                                     -> Result<PseudoClass,
                                                               ParseError<'i, SelectorParseError<'i, ()>>> {
             match_ignore_ascii_case! { &name,
                 "lang" => Ok(PseudoClass::Lang(try!(parser.expect_ident_or_string()).into_owned())),
                 _ => Err(SelectorParseError::Custom(()).into())
             }
         }
 
-        fn parse_pseudo_element(&self, name: Cow<'i, str>)
+        fn parse_pseudo_element(&self, name: CompactCowStr<'i>)
                                 -> Result<PseudoElement,
                                           ParseError<'i, SelectorParseError<'i, ()>>> {
             match_ignore_ascii_case! { &name,
                 "before" => Ok(PseudoElement::Before),
                 "after" => Ok(PseudoElement::After),
                 _ => Err(SelectorParseError::Custom(()).into())
             }
         }
--- a/servo/components/style/Cargo.toml
+++ b/servo/components/style/Cargo.toml
@@ -33,17 +33,17 @@ gecko_debug = ["nsstring_vendor/gecko_de
 app_units = "0.5"
 arrayvec = "0.3.20"
 arraydeque = "0.2.3"
 atomic_refcell = "0.1"
 bitflags = "0.7"
 bit-vec = "0.4.3"
 byteorder = "1.0"
 cfg-if = "0.1.0"
-cssparser = "0.15"
+cssparser = "0.16"
 encoding = {version = "0.2", optional = true}
 euclid = "0.15"
 fnv = "1.0"
 heapsize = {version = "0.4", optional = true}
 heapsize_derive = {version = "0.1", optional = true}
 itoa = "0.3"
 html5ever = {version = "0.18", optional = true}
 lazy_static = "0.2"
--- a/servo/components/style/counter_style/mod.rs
+++ b/servo/components/style/counter_style/mod.rs
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //! The [`@counter-style`][counter-style] at-rule.
 //!
 //! [counter-style]: https://drafts.csswg.org/css-counter-styles/
 
 use Atom;
 use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser};
-use cssparser::{Parser, Token, serialize_identifier, BasicParseError};
+use cssparser::{Parser, Token, serialize_identifier, BasicParseError, CompactCowStr};
 use error_reporting::ContextualParseError;
 #[cfg(feature = "gecko")] use gecko::rules::CounterStyleDescriptors;
 #[cfg(feature = "gecko")] use gecko_bindings::structs::nsCSSCounterDesc;
 use parser::{ParserContext, log_css_error, Parse};
 use selectors::parser::SelectorParseError;
 use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
 use std::ascii::AsciiExt;
 use std::borrow::Cow;
@@ -179,17 +179,17 @@ macro_rules! counter_style_descriptors {
                 )*
             }
         }
 
         impl<'a, 'b, 'i> DeclarationParser<'i> for CounterStyleRuleParser<'a, 'b> {
             type Declaration = ();
             type Error = SelectorParseError<'i, StyleParseError<'i>>;
 
-            fn parse_value<'t>(&mut self, name: Cow<'i, str>, input: &mut Parser<'i, 't>)
+            fn parse_value<'t>(&mut self, name: CompactCowStr<'i>, input: &mut Parser<'i, 't>)
                                -> Result<(), ParseError<'i>> {
                 match_ignore_ascii_case! { &*name,
                     $(
                         $name => {
                             // DeclarationParser also calls parse_entirely
                             // so we’d normally not need to,
                             // but in this case we do because we set the value as a side effect
                             // rather than returning it.
@@ -425,17 +425,17 @@ impl Parse for Ranges {
                 Ok(opt_start..opt_end)
             }).map(Ranges)
         }
     }
 }
 
 fn parse_bound<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Option<i32>, ParseError<'i>> {
     match input.next() {
-        Ok(Token::Number(ref v)) if v.int_value.is_some() => Ok(Some(v.int_value.unwrap())),
+        Ok(Token::Number { int_value: Some(v), .. }) => Ok(Some(v)),
         Ok(Token::Ident(ref ident)) if ident.eq_ignore_ascii_case("infinite") => Ok(None),
         Ok(t) => Err(BasicParseError::UnexpectedToken(t).into()),
         Err(e) => Err(e.into()),
     }
 }
 
 impl ToCss for Ranges {
     fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
--- a/servo/components/style/custom_properties.rs
+++ b/servo/components/style/custom_properties.rs
@@ -276,17 +276,17 @@ fn parse_declaration_value_block<'i, 't>
                 }
                 token.serialization_type()
             }
             Token::Ident(ref value) |
             Token::AtKeyword(ref value) |
             Token::Hash(ref value) |
             Token::IDHash(ref value) |
             Token::UnquotedUrl(ref value) |
-            Token::Dimension(_, ref value) => {
+            Token::Dimension { unit: ref value, .. } => {
                 if value.ends_with("�") && input.slice_from(token_start).ends_with("\\") {
                     // Unescaped backslash at EOF in these contexts is interpreted as U+FFFD
                     // Check the value in case the final backslash was itself escaped.
                     // Serialize as escaped U+FFFD, which is also interpreted as U+FFFD.
                     // (Unescaped U+FFFD would also work, but removing the backslash is annoying.)
                     missing_closing_characters.push_str("�")
                 }
                 if matches!(token, Token::UnquotedUrl(_)) {
--- a/servo/components/style/error_reporting.rs
+++ b/servo/components/style/error_reporting.rs
@@ -1,17 +1,17 @@
 /* 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/. */
 
 //! Types used to report parsing errors.
 
 #![deny(missing_docs)]
 
-use cssparser::{Parser, SourcePosition, BasicParseError, Token, NumericValue, PercentageValue};
+use cssparser::{Parser, SourcePosition, BasicParseError, Token};
 use cssparser::ParseError as CssParseError;
 use log;
 use style_traits::ParseError;
 use stylesheets::UrlExtraData;
 
 /// Errors that can be encountered while parsing CSS.
 pub enum ContextualParseError<'a> {
     /// A property declaration was not recognized.
@@ -49,21 +49,21 @@ impl<'a> ContextualParseError<'a> {
             match *t {
                 Token::Ident(ref i) => format!("identifier {}", i),
                 Token::AtKeyword(ref kw) => format!("keyword @{}", kw),
                 Token::Hash(ref h) => format!("hash #{}", h),
                 Token::IDHash(ref h) => format!("id selector #{}", h),
                 Token::QuotedString(ref s) => format!("quoted string \"{}\"", s),
                 Token::UnquotedUrl(ref u) => format!("url {}", u),
                 Token::Delim(ref d) => format!("delimiter {}", d),
-                Token::Number(NumericValue { int_value: Some(i), .. }) => format!("number {}", i),
-                Token::Number(ref n) => format!("number {}", n.value),
-                Token::Percentage(PercentageValue { int_value: Some(i), .. }) => format!("percentage {}", i),
-                Token::Percentage(ref p) => format!("percentage {}", p.unit_value),
-                Token::Dimension(_, ref d) => format!("dimension {}", d),
+                Token::Number { int_value: Some(i), .. } => format!("number {}", i),
+                Token::Number { value, .. } => format!("number {}", value),
+                Token::Percentage { int_value: Some(i), .. } => format!("percentage {}", i),
+                Token::Percentage { unit_value, .. } => format!("percentage {}", unit_value * 100.),
+                Token::Dimension { value, ref unit, .. } => format!("dimension {}{}", value, unit),
                 Token::WhiteSpace(_) => format!("whitespace"),
                 Token::Comment(_) => format!("comment"),
                 Token::Colon => format!("colon (:)"),
                 Token::Semicolon => format!("semicolon (;)"),
                 Token::Comma => format!("comma (,)"),
                 Token::IncludeMatch => format!("include match (~=)"),
                 Token::DashMatch => format!("dash match (|=)"),
                 Token::PrefixMatch => format!("prefix match (^=)"),
--- a/servo/components/style/font_face.rs
+++ b/servo/components/style/font_face.rs
@@ -7,24 +7,23 @@
 //! [ff]: https://drafts.csswg.org/css-fonts/#at-font-face-rule
 
 #![deny(missing_docs)]
 
 #[cfg(feature = "gecko")]
 use computed_values::{font_feature_settings, font_stretch, font_style, font_weight};
 use computed_values::font_family::FamilyName;
 use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser};
-use cssparser::SourceLocation;
+use cssparser::{SourceLocation, CompactCowStr};
 use error_reporting::ContextualParseError;
 #[cfg(feature = "gecko")] use gecko_bindings::structs::CSSFontFaceDescriptors;
 #[cfg(feature = "gecko")] use cssparser::UnicodeRange;
 use parser::{ParserContext, log_css_error, Parse};
 use selectors::parser::SelectorParseError;
 use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
-use std::borrow::Cow;
 use std::fmt;
 use style_traits::{ToCss, OneOrMoreCommaSeparated, ParseError, StyleParseError};
 use values::specified::url::SpecifiedUrl;
 
 /// A source for a font-face rule.
 #[derive(Clone, Debug, PartialEq, Eq)]
 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
 pub enum Source {
@@ -251,17 +250,17 @@ macro_rules! font_face_descriptors_commo
                 dest.write_str("}")
             }
         }
 
        impl<'a, 'b, 'i> DeclarationParser<'i> for FontFaceRuleParser<'a, 'b> {
            type Declaration = ();
            type Error = SelectorParseError<'i, StyleParseError<'i>>;
 
-           fn parse_value<'t>(&mut self, name: Cow<'i, str>, input: &mut Parser<'i, 't>)
+           fn parse_value<'t>(&mut self, name: CompactCowStr<'i>, input: &mut Parser<'i, 't>)
                               -> Result<(), ParseError<'i>> {
                 match_ignore_ascii_case! { &*name,
                     $(
                         $name => {
                             // DeclarationParser also calls parse_entirely
                             // so we’d normally not need to,
                             // but in this case we do because we set the value as a side effect
                             // rather than returning it.
--- a/servo/components/style/gecko/media_queries.rs
+++ b/servo/components/style/gecko/media_queries.rs
@@ -226,31 +226,30 @@ impl Resolution {
             Resolution::Dpi(f) => f,
             Resolution::Dppx(f) => f * 96.0,
             Resolution::Dpcm(f) => f * 2.54,
         }
     }
 
     fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
         let (value, unit) = match try!(input.next()) {
-            Token::Dimension(value, unit) => {
+            Token::Dimension { value, unit, .. } => {
                 (value, unit)
             },
             t => return Err(BasicParseError::UnexpectedToken(t).into()),
         };
 
-        let inner_value = value.value;
-        if inner_value <= 0. {
+        if value <= 0. {
             return Err(StyleParseError::UnspecifiedError.into())
         }
 
         (match_ignore_ascii_case! { &unit,
-            "dpi" => Ok(Resolution::Dpi(inner_value)),
-            "dppx" => Ok(Resolution::Dppx(inner_value)),
-            "dpcm" => Ok(Resolution::Dpcm(inner_value)),
+            "dpi" => Ok(Resolution::Dpi(value)),
+            "dppx" => Ok(Resolution::Dppx(value)),
+            "dpcm" => Ok(Resolution::Dpcm(value)),
             _ => Err(())
         }).map_err(|()| StyleParseError::UnexpectedDimension(unit).into())
     }
 }
 
 impl ToCss for Resolution {
     fn to_css<W>(&self, dest: &mut W) -> fmt::Result
         where W: fmt::Write,
--- a/servo/components/style/gecko/selector_parser.rs
+++ b/servo/components/style/gecko/selector_parser.rs
@@ -1,21 +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/. */
 
 //! Gecko-specific bits for selector-parsing.
 
-use cssparser::{Parser, ToCss};
+use cssparser::{Parser, ToCss, CompactCowStr};
 use element_state::ElementState;
 use gecko_bindings::structs::CSSPseudoClassType;
 use selector_parser::{SelectorParser, PseudoElementCascadeType};
 use selectors::parser::{Selector, SelectorMethods, SelectorParseError};
 use selectors::visitor::SelectorVisitor;
-use std::borrow::Cow;
 use std::fmt;
 use string_cache::{Atom, Namespace, WeakAtom, WeakNamespace};
 use style_traits::{ParseError, StyleParseError};
 
 pub use gecko::pseudo_element::{PseudoElement, EAGER_PSEUDOS, EAGER_PSEUDO_COUNT};
 pub use gecko::snapshot::SnapshotMap;
 
 bitflags! {
@@ -244,17 +243,17 @@ impl ::selectors::SelectorImpl for Selec
                                 NonTSPseudoClass::Hover)
     }
 }
 
 impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
     type Impl = SelectorImpl;
     type Error = StyleParseError<'i>;
 
-    fn parse_non_ts_pseudo_class(&self, name: Cow<'i, str>)
+    fn parse_non_ts_pseudo_class(&self, name: CompactCowStr<'i>)
                                  -> Result<NonTSPseudoClass, ParseError<'i>> {
         macro_rules! pseudo_class_parse {
             (bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*],
              string: [$(($s_css:expr, $s_name:ident, $s_gecko_type:tt, $s_state:tt, $s_flags:tt),)*],
              keyword: [$(($k_css:expr, $k_name:ident, $k_gecko_type:tt, $k_state:tt, $k_flags:tt),)*]) => {
                 match_ignore_ascii_case! { &name,
                     $($css => NonTSPseudoClass::$name,)*
                     _ => return Err(::selectors::parser::SelectorParseError::UnexpectedIdent(
@@ -266,17 +265,17 @@ impl<'a, 'i> ::selectors::Parser<'i> for
         if !pseudo_class.is_internal() || self.in_user_agent_stylesheet() {
             Ok(pseudo_class)
         } else {
             Err(SelectorParseError::UnexpectedIdent(name).into())
         }
     }
 
     fn parse_non_ts_functional_pseudo_class<'t>(&self,
-                                                name: Cow<'i, str>,
+                                                name: CompactCowStr<'i>,
                                                 parser: &mut Parser<'i, 't>)
                                                 -> Result<NonTSPseudoClass, ParseError<'i>> {
         macro_rules! pseudo_class_string_parse {
             (bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*],
              string: [$(($s_css:expr, $s_name:ident, $s_gecko_type:tt, $s_state:tt, $s_flags:tt),)*],
              keyword: [$(($k_css:expr, $k_name:ident, $k_gecko_type:tt, $k_state:tt, $k_flags:tt),)*]) => {
                 match_ignore_ascii_case! { &name,
                     $($s_css => {
@@ -310,17 +309,17 @@ impl<'a, 'i> ::selectors::Parser<'i> for
         let pseudo_class = apply_non_ts_list!(pseudo_class_string_parse);
         if !pseudo_class.is_internal() || self.in_user_agent_stylesheet() {
             Ok(pseudo_class)
         } else {
             Err(SelectorParseError::UnexpectedIdent(name).into())
         }
     }
 
-    fn parse_pseudo_element(&self, name: Cow<'i, str>) -> Result<PseudoElement, ParseError<'i>> {
+    fn parse_pseudo_element(&self, name: CompactCowStr<'i>) -> Result<PseudoElement, ParseError<'i>> {
         PseudoElement::from_slice(&name, self.in_user_agent_stylesheet())
             .ok_or(SelectorParseError::UnexpectedIdent(name.clone()).into())
     }
 
     fn default_namespace(&self) -> Option<Namespace> {
         self.namespaces.default.clone().as_ref().map(|&(ref ns, _)| ns.clone())
     }
 
--- a/servo/components/style/gecko/url.rs
+++ b/servo/components/style/gecko/url.rs
@@ -4,17 +4,16 @@
 
 //! Common handling for the specified value CSS url() values.
 
 use cssparser::CssStringWriter;
 use gecko_bindings::structs::{ServoBundledURI, URLExtraData};
 use gecko_bindings::structs::root::mozilla::css::ImageValue;
 use gecko_bindings::sugar::refptr::RefPtr;
 use parser::ParserContext;
-use std::borrow::Cow;
 use std::fmt::{self, Write};
 use style_traits::{ToCss, ParseError};
 use stylearc::Arc;
 
 /// A specified url() value for gecko. Gecko does not eagerly resolve SpecifiedUrls.
 #[derive(Clone, Debug, PartialEq)]
 pub struct SpecifiedUrl {
     /// The URL in unresolved string form.
@@ -31,21 +30,21 @@ pub struct SpecifiedUrl {
     pub image_value: Option<RefPtr<ImageValue>>,
 }
 
 impl SpecifiedUrl {
     /// Try to parse a URL from a string value that is a valid CSS token for a
     /// URL.
     ///
     /// Returns `Err` in the case that extra_data is incomplete.
-    pub fn parse_from_string<'a>(url: Cow<'a, str>,
+    pub fn parse_from_string<'a>(url: String,
                                  context: &ParserContext)
                                  -> Result<Self, ParseError<'a>> {
         Ok(SpecifiedUrl {
-            serialization: Arc::new(url.into_owned()),
+            serialization: Arc::new(url),
             extra_data: context.url_data.clone(),
             image_value: None,
         })
     }
 
     /// Returns true if the URL is definitely invalid. We don't eagerly resolve
     /// URLs in gecko, so we just return false here.
     /// use its |resolved| status.
--- a/servo/components/style/properties/declaration_block.rs
+++ b/servo/components/style/properties/declaration_block.rs
@@ -2,17 +2,17 @@
  * 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/. */
 
 //! A property declaration block.
 
 #![deny(missing_docs)]
 
 use context::QuirksMode;
-use cssparser::{DeclarationListParser, parse_important, ParserInput};
+use cssparser::{DeclarationListParser, parse_important, ParserInput, CompactCowStr};
 use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter};
 use error_reporting::{ParseErrorReporter, ContextualParseError};
 use parser::{ParserContext, log_css_error};
 use properties::animated_properties::AnimationValue;
 use selectors::parser::SelectorParseError;
 use shared_lock::Locked;
 use smallvec::SmallVec;
 use std::fmt;
@@ -927,17 +927,17 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for Pr
     type AtRule = Importance;
     type Error = SelectorParseError<'i, StyleParseError<'i>>;
 }
 
 impl<'a, 'b, 'i> DeclarationParser<'i> for PropertyDeclarationParser<'a, 'b> {
     type Declaration = Importance;
     type Error = SelectorParseError<'i, StyleParseError<'i>>;
 
-    fn parse_value<'t>(&mut self, name: Cow<'i, str>, input: &mut Parser<'i, 't>)
+    fn parse_value<'t>(&mut self, name: CompactCowStr<'i>, input: &mut Parser<'i, 't>)
                        -> Result<Importance, ParseError<'i>> {
         let id = try!(PropertyId::parse(name));
         input.parse_until_before(Delimiter::Bang, |input| {
             PropertyDeclaration::parse_into(self.declarations, id, self.context, input)
                 .map_err(|e| e.into())
         })?;
         let importance = match input.try(parse_important) {
             Ok(()) => Importance::Important,
--- a/servo/components/style/properties/longhand/effects.mako.rs
+++ b/servo/components/style/properties/longhand/effects.mako.rs
@@ -301,18 +301,18 @@
                 return Ok(SpecifiedValue(filters))
             }
         }
     }
 
     fn parse_factor<'i, 't>(input: &mut Parser<'i, 't>) -> Result<::values::CSSFloat, ParseError<'i>> {
         use cssparser::Token;
         match input.next() {
-            Ok(Token::Number(value)) if value.value.is_sign_positive() => Ok(value.value),
-            Ok(Token::Percentage(value)) if value.unit_value.is_sign_positive() => Ok(value.unit_value),
+            Ok(Token::Number { value, .. }) if value.is_sign_positive() => Ok(value),
+            Ok(Token::Percentage { unit_value, .. }) if unit_value.is_sign_positive() => Ok(unit_value),
             Ok(t) => Err(BasicParseError::UnexpectedToken(t).into()),
             Err(e) => Err(e.into())
         }
     }
 
     impl ToComputedValue for SpecifiedValue {
         type ComputedValue = computed_value::T;
 
--- a/servo/components/style/properties/longhand/list.mako.rs
+++ b/servo/components/style/properties/longhand/list.mako.rs
@@ -139,17 +139,17 @@
         % endif
 
         return Ok(SpecifiedValue(value));
     }
 </%helpers:longhand>
 
 <%helpers:longhand name="quotes" animation_value_type="none"
                    spec="https://drafts.csswg.org/css-content/#propdef-quotes">
-    use std::borrow::Cow;
+    use cssparser::serialize_string;
     use std::fmt;
     use style_traits::ToCss;
     use values::computed::ComputedValueAsSpecified;
 
     pub use self::computed_value::T as SpecifiedValue;
 
     pub mod computed_value {
         #[derive(Debug, Clone, PartialEq)]
@@ -164,22 +164,22 @@
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             if self.0.is_empty() {
                 return dest.write_str("none")
             }
 
             let mut first = true;
             for pair in &self.0 {
                 if !first {
-                    try!(dest.write_str(" "));
+                    dest.write_str(" ")?;
                 }
                 first = false;
-                try!(Token::QuotedString(Cow::from(&*pair.0)).to_css(dest));
-                try!(dest.write_str(" "));
-                try!(Token::QuotedString(Cow::from(&*pair.1)).to_css(dest));
+                serialize_string(&*pair.0, dest)?;
+                dest.write_str(" ")?;
+                serialize_string(&*pair.1, dest)?;
             }
             Ok(())
         }
     }
 
     #[inline]
     pub fn get_initial_value() -> computed_value::T {
         computed_value::T(vec![
--- a/servo/components/style/properties/properties.mako.rs
+++ b/servo/components/style/properties/properties.mako.rs
@@ -15,17 +15,17 @@ use std::collections::HashSet;
 use std::fmt;
 use std::mem;
 use std::ops::Deref;
 use stylearc::{Arc, UniqueArc};
 
 use app_units::Au;
 #[cfg(feature = "servo")] use cssparser::RGBA;
 use cssparser::{Parser, TokenSerializationType, serialize_identifier};
-use cssparser::ParserInput;
+use cssparser::{ParserInput, CompactCowStr};
 use error_reporting::ParseErrorReporter;
 #[cfg(feature = "servo")] use euclid::SideOffsets2D;
 use computed_values;
 use context::QuirksMode;
 use font_metrics::FontMetricsProvider;
 #[cfg(feature = "gecko")] use gecko_bindings::bindings;
 #[cfg(feature = "gecko")] use gecko_bindings::structs::{self, nsCSSPropertyID};
 #[cfg(feature = "servo")] use logical_geometry::{LogicalMargin, PhysicalSide};
@@ -486,17 +486,17 @@ impl CSSWideKeyword {
             CSSWideKeyword::Initial => "initial",
             CSSWideKeyword::Inherit => "inherit",
             CSSWideKeyword::Unset => "unset",
         }
     }
 
     /// Takes the result of cssparser::Parser::expect_ident() and converts it
     /// to a CSSWideKeyword.
-    pub fn from_ident<'i>(ident: &Cow<'i, str>) -> Option<Self> {
+    pub fn from_ident<'i>(ident: &str) -> Option<Self> {
         match_ignore_ascii_case! { ident,
             // If modifying this set of keyword, also update values::CustomIdent::from_ident
             "initial" => Some(CSSWideKeyword::Initial),
             "inherit" => Some(CSSWideKeyword::Inherit),
             "unset" => Some(CSSWideKeyword::Unset),
             _ => None
         }
     }
@@ -981,17 +981,17 @@ impl ToCss for PropertyId {
         }
     }
 }
 
 impl PropertyId {
     /// Returns a given property from the string `s`.
     ///
     /// Returns Err(()) for unknown non-custom properties
-    pub fn parse<'i>(property_name: Cow<'i, str>) -> Result<Self, ParseError<'i>> {
+    pub fn parse<'i>(property_name: CompactCowStr<'i>) -> Result<Self, ParseError<'i>> {
         if let Ok(name) = ::custom_properties::parse_name(&property_name) {
             return Ok(PropertyId::Custom(::custom_properties::Name::from(name)))
         }
 
         // FIXME(https://github.com/rust-lang/rust/issues/33156): remove this enum and use PropertyId
         // when stable Rust allows destructors in statics.
         pub enum StaticId {
             Longhand(LonghandId),
--- a/servo/components/style/servo/selector_parser.rs
+++ b/servo/components/style/servo/selector_parser.rs
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #![deny(missing_docs)]
 
 //! Servo's selector parser.
 
 use {Atom, Prefix, Namespace, LocalName, CaseSensitivityExt};
 use attr::{AttrIdentifier, AttrValue};
-use cssparser::{Parser as CssParser, ToCss, serialize_identifier};
+use cssparser::{Parser as CssParser, ToCss, serialize_identifier, CompactCowStr};
 use dom::{OpaqueNode, TElement, TNode};
 use element_state::ElementState;
 use fnv::FnvHashMap;
 use invalidation::element::element_wrapper::ElementSnapshot;
 use selector_parser::{AttrValue as SelectorAttrValue, ElementExt, PseudoElementCascadeType, SelectorParser};
 use selectors::Element;
 use selectors::attr::{AttrSelectorOperation, NamespaceConstraint, CaseSensitivity};
 use selectors::parser::{SelectorMethods, SelectorParseError};
@@ -306,17 +306,17 @@ impl ::selectors::SelectorImpl for Selec
                                 NonTSPseudoClass::Hover)
     }
 }
 
 impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
     type Impl = SelectorImpl;
     type Error = StyleParseError<'i>;
 
-    fn parse_non_ts_pseudo_class(&self, name: Cow<'i, str>)
+    fn parse_non_ts_pseudo_class(&self, name: CompactCowStr<'i>)
                                  -> Result<NonTSPseudoClass, ParseError<'i>> {
         use self::NonTSPseudoClass::*;
         let pseudo_class = match_ignore_ascii_case! { &name,
             "active" => Active,
             "any-link" => AnyLink,
             "checked" => Checked,
             "disabled" => Disabled,
             "enabled" => Enabled,
@@ -339,37 +339,37 @@ impl<'a, 'i> ::selectors::Parser<'i> for
             },
             _ => return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()),
         };
 
         Ok(pseudo_class)
     }
 
     fn parse_non_ts_functional_pseudo_class<'t>(&self,
-                                                name: Cow<'i, str>,
+                                                name: CompactCowStr<'i>,
                                                 parser: &mut CssParser<'i, 't>)
                                                 -> Result<NonTSPseudoClass, ParseError<'i>> {
         use self::NonTSPseudoClass::*;
         let pseudo_class = match_ignore_ascii_case!{ &name,
             "lang" => {
                 Lang(parser.expect_ident_or_string()?.into_owned().into_boxed_str())
             }
             "-servo-case-sensitive-type-attr" => {
                 if !self.in_user_agent_stylesheet() {
                     return Err(SelectorParseError::UnexpectedIdent(name.clone()).into());
                 }
-                ServoCaseSensitiveTypeAttr(Atom::from(parser.expect_ident()?))
+                ServoCaseSensitiveTypeAttr(Atom::from(Cow::from(parser.expect_ident()?)))
             }
             _ => return Err(SelectorParseError::UnexpectedIdent(name.clone()).into())
         };
 
         Ok(pseudo_class)
     }
 
-    fn parse_pseudo_element(&self, name: Cow<'i, str>) -> Result<PseudoElement, ParseError<'i>> {
+    fn parse_pseudo_element(&self, name: CompactCowStr<'i>) -> Result<PseudoElement, ParseError<'i>> {
         use self::PseudoElement::*;
         let pseudo_element = match_ignore_ascii_case! { &name,
             "before" => Before,
             "after" => After,
             "selection" => Selection,
             "-servo-details-summary" => {
                 if !self.in_user_agent_stylesheet() {
                     return Err(SelectorParseError::UnexpectedIdent(name.clone()).into())
--- a/servo/components/style/servo/url.rs
+++ b/servo/components/style/servo/url.rs
@@ -2,17 +2,16 @@
  * 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/. */
 
 //! Common handling for the specified value CSS url() values.
 
 use cssparser::CssStringWriter;
 use parser::ParserContext;
 use servo_url::ServoUrl;
-use std::borrow::Cow;
 use std::fmt::{self, Write};
 // Note: We use std::sync::Arc rather than stylearc::Arc here because the
 // nonzero optimization is important in keeping the size of SpecifiedUrl below
 // the threshold.
 use std::sync::Arc;
 use style_traits::{ToCss, ParseError};
 
 /// A specified url() value for servo.
@@ -36,20 +35,20 @@ pub struct SpecifiedUrl {
     /// The resolved value for the url, if valid.
     resolved: Option<ServoUrl>,
 }
 
 impl SpecifiedUrl {
     /// Try to parse a URL from a string value that is a valid CSS token for a
     /// URL. Never fails - the API is only fallible to be compatible with the
     /// gecko version.
-    pub fn parse_from_string<'a>(url: Cow<'a, str>,
+    pub fn parse_from_string<'a>(url: String,
                                  context: &ParserContext)
                                  -> Result<Self, ParseError<'a>> {
-        let serialization = Arc::new(url.into_owned());
+        let serialization = Arc::new(url);
         let resolved = context.url_data.join(&serialization).ok();
         Ok(SpecifiedUrl {
             original: Some(serialization),
             resolved: resolved,
         })
     }
 
     /// Returns true if the URL is definitely invalid. For Servo URLs, we can
--- a/servo/components/style/stylesheets/keyframes_rule.rs
+++ b/servo/components/style/stylesheets/keyframes_rule.rs
@@ -1,26 +1,25 @@
 /* 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/. */
 
 //! Keyframes: https://drafts.csswg.org/css-animations/#keyframes
 
-use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, RuleListParser, ParserInput};
+use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, RuleListParser, ParserInput, CompactCowStr};
 use cssparser::{DeclarationListParser, DeclarationParser, parse_one_rule, SourceLocation};
 use error_reporting::{NullReporter, ContextualParseError};
 use parser::{ParserContext, log_css_error};
 use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock, PropertyId};
 use properties::{PropertyDeclarationId, LonghandId, SourcePropertyDeclaration};
 use properties::LonghandIdSet;
 use properties::animated_properties::AnimatableLonghand;
 use properties::longhands::transition_timing_function::single_value::SpecifiedValue as SpecifiedTimingFunction;
 use selectors::parser::SelectorParseError;
 use shared_lock::{DeepCloneWithLock, SharedRwLock, SharedRwLockReadGuard, Locked, ToCssWithGuard};
-use std::borrow::Cow;
 use std::fmt;
 use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError, StyleParseError};
 use stylearc::Arc;
 use stylesheets::{CssRuleType, Stylesheet};
 use stylesheets::rule_parser::VendorPrefix;
 use values::KeyframesName;
 
 /// A [`@keyframes`][keyframes] rule.
@@ -518,17 +517,17 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for Ke
     type AtRule = ();
     type Error = SelectorParseError<'i, StyleParseError<'i>>;
 }
 
 impl<'a, 'b, 'i> DeclarationParser<'i> for KeyframeDeclarationParser<'a, 'b> {
     type Declaration = ();
     type Error = SelectorParseError<'i, StyleParseError<'i>>;
 
-    fn parse_value<'t>(&mut self, name: Cow<'i, str>, input: &mut Parser<'i, 't>)
+    fn parse_value<'t>(&mut self, name: CompactCowStr<'i>, input: &mut Parser<'i, 't>)
                        -> Result<(), ParseError<'i>> {
         let id = try!(PropertyId::parse(name.into()));
         match PropertyDeclaration::parse_into(self.declarations, id, self.context, input) {
             Ok(()) => {
                 // In case there is still unparsed text in the declaration, we should roll back.
                 input.expect_exhausted().map_err(|e| e.into())
             }
             Err(_e) => Err(StyleParseError::UnspecifiedError.into())
--- a/servo/components/style/stylesheets/rule_parser.rs
+++ b/servo/components/style/stylesheets/rule_parser.rs
@@ -1,17 +1,18 @@
 /* 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/. */
 
 //! Parsing of the stylesheet contents.
 
 use {Namespace, Prefix};
 use counter_style::{parse_counter_style_body, parse_counter_style_name};
-use cssparser::{AtRuleParser, AtRuleType, Parser, QualifiedRuleParser, RuleListParser, SourceLocation};
+use cssparser::{AtRuleParser, AtRuleType, Parser, QualifiedRuleParser, RuleListParser};
+use cssparser::{CompactCowStr, SourceLocation};
 use error_reporting::ContextualParseError;
 use font_face::parse_font_face_block;
 use media_queries::{parse_media_query_list, MediaList};
 use parking_lot::RwLock;
 use parser::{Parse, ParserContext, log_css_error};
 use properties::parse_property_declaration_list;
 use selector_parser::{SelectorImpl, SelectorParser};
 use selectors::SelectorList;
@@ -139,31 +140,31 @@ fn register_namespace(_: &Namespace) -> 
 
 impl<'a, 'i> AtRuleParser<'i> for TopLevelRuleParser<'a> {
     type Prelude = AtRulePrelude;
     type AtRule = CssRule;
     type Error = SelectorParseError<'i, StyleParseError<'i>>;
 
     fn parse_prelude<'t>(
         &mut self,
-        name: Cow<'i, str>,
+        name: CompactCowStr<'i>,
         input: &mut Parser<'i, 't>
     ) -> Result<AtRuleType<AtRulePrelude, CssRule>, ParseError<'i>> {
         let location = get_location_with_offset(input.current_source_location(),
                                                 self.context.line_number_offset);
         match_ignore_ascii_case! { &*name,
             "import" => {
                 if self.state > State::Imports {
                     self.state = State::Invalid;
                     // "@import must be before any rule but @charset"
                     return Err(StyleParseError::UnexpectedImportRule.into())
                 }
 
                 self.state = State::Imports;
-                let url_string = input.expect_url_or_string()?;
+                let url_string = input.expect_url_or_string()?.into_owned();
                 let specified_url = SpecifiedUrl::parse_from_string(url_string, &self.context)?;
 
                 let media = parse_media_query_list(&self.context, input);
                 let media = Arc::new(self.shared_lock.wrap(media));
 
                 let noop_loader = NoOpLoader;
                 let loader = if !specified_url.is_invalid() {
                     self.loader.expect("Expected a stylesheet loader for @import")
@@ -198,25 +199,25 @@ impl<'a, 'i> AtRuleParser<'i> for TopLev
                 if self.state > State::Namespaces {
                     self.state = State::Invalid;
                     // "@namespace must be before any rule but @charset and @import"
                     return Err(StyleParseError::UnexpectedNamespaceRule.into())
                 }
                 self.state = State::Namespaces;
 
                 let prefix_result = input.try(|input| input.expect_ident());
-                let url = Namespace::from(try!(input.expect_url_or_string()));
+                let url = Namespace::from(Cow::from(input.expect_url_or_string()?));
 
                 let id = register_namespace(&url)
                     .map_err(|()| StyleParseError::UnspecifiedError)?;
 
                 let mut namespaces = self.namespaces.as_mut().unwrap();
 
                 let opt_prefix = if let Ok(prefix) = prefix_result {
-                    let prefix = Prefix::from(prefix);
+                    let prefix = Prefix::from(Cow::from(prefix));
                     namespaces
                         .prefixes
                         .insert(prefix.clone(), (url.clone(), id));
                     Some(prefix)
                 } else {
                     namespaces.default = Some((url.clone(), id));
                     None
                 };
@@ -332,17 +333,17 @@ impl<'a, 'b> NestedRuleParser<'a, 'b> {
 
 impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
     type Prelude = AtRulePrelude;
     type AtRule = CssRule;
     type Error = SelectorParseError<'i, StyleParseError<'i>>;
 
     fn parse_prelude<'t>(
         &mut self,
-        name: Cow<'i, str>,
+        name: CompactCowStr<'i>,
         input: &mut Parser<'i, 't>
     ) -> Result<AtRuleType<AtRulePrelude, CssRule>, ParseError<'i>> {
         let location =
             get_location_with_offset(
                 input.current_source_location(),
                 self.context.line_number_offset
             );
 
--- a/servo/components/style/stylesheets/viewport_rule.rs
+++ b/servo/components/style/stylesheets/viewport_rule.rs
@@ -5,17 +5,17 @@
 //! The [`@viewport`][at] at-rule and [`meta`][meta] element.
 //!
 //! [at]: https://drafts.csswg.org/css-device-adapt/#atviewport-rule
 //! [meta]: https://drafts.csswg.org/css-device-adapt/#viewport-meta
 
 use app_units::Au;
 use context::QuirksMode;
 use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser, parse_important};
-use cssparser::ToCss as ParserToCss;
+use cssparser::{CompactCowStr, ToCss as ParserToCss};
 use error_reporting::ContextualParseError;
 use euclid::TypedSize2D;
 use font_metrics::get_metrics_provider_for_product;
 use media_queries::Device;
 use parser::{Parse, ParserContext, log_css_error};
 use properties::StyleBuilder;
 use selectors::parser::SelectorParseError;
 use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
@@ -276,17 +276,17 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for Vi
     type AtRule = Vec<ViewportDescriptorDeclaration>;
     type Error = SelectorParseError<'i, StyleParseError<'i>>;
 }
 
 impl<'a, 'b, 'i> DeclarationParser<'i> for ViewportRuleParser<'a, 'b> {
     type Declaration = Vec<ViewportDescriptorDeclaration>;
     type Error = SelectorParseError<'i, StyleParseError<'i>>;
 
-    fn parse_value<'t>(&mut self, name: Cow<'i, str>, input: &mut Parser<'i, 't>)
+    fn parse_value<'t>(&mut self, name: CompactCowStr<'i>, input: &mut Parser<'i, 't>)
                        -> Result<Vec<ViewportDescriptorDeclaration>, ParseError<'i>> {
         macro_rules! declaration {
             ($declaration:ident($parse:expr)) => {
                 declaration!($declaration(value: try!($parse(input)),
                                           important: input.try(parse_important).is_ok()))
             };
             ($declaration:ident(value: $value:expr, important: $important:expr)) => {
                 ViewportDescriptorDeclaration::new(
--- a/servo/components/style/values/mod.rs
+++ b/servo/components/style/values/mod.rs
@@ -4,17 +4,17 @@
 
 //! Common [values][values] used in CSS.
 //!
 //! [values]: https://drafts.csswg.org/css-values/
 
 #![deny(missing_docs)]
 
 use Atom;
-pub use cssparser::{RGBA, Token, Parser, serialize_identifier, BasicParseError};
+pub use cssparser::{RGBA, Token, Parser, serialize_identifier, BasicParseError, CompactCowStr};
 use parser::{Parse, ParserContext};
 use selectors::parser::SelectorParseError;
 use std::ascii::AsciiExt;
 use std::borrow::Cow;
 use std::fmt::{self, Debug};
 use std::hash;
 use style_traits::{ToCss, ParseError, StyleParseError};
 
@@ -88,28 +88,28 @@ impl<A: ToComputedValue, B: ToComputedVa
 
 /// https://drafts.csswg.org/css-values-4/#custom-idents
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 pub struct CustomIdent(pub Atom);
 
 impl CustomIdent {
     /// Parse an already-tokenizer identifier
-    pub fn from_ident<'i>(ident: Cow<'i, str>, excluding: &[&str]) -> Result<Self, ParseError<'i>> {
+    pub fn from_ident<'i>(ident: CompactCowStr<'i>, excluding: &[&str]) -> Result<Self, ParseError<'i>> {
         let valid = match_ignore_ascii_case! { &ident,
             "initial" | "inherit" | "unset" | "default" => false,
             _ => true
         };
         if !valid {
             return Err(SelectorParseError::UnexpectedIdent(ident).into());
         }
         if excluding.iter().any(|s| ident.eq_ignore_ascii_case(s)) {
             Err(StyleParseError::UnspecifiedError.into())
         } else {
-            Ok(CustomIdent(ident.into()))
+            Ok(CustomIdent(Atom::from(Cow::from(ident))))
         }
     }
 }
 
 impl ToCss for CustomIdent {
     fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
         serialize_identifier(&self.0.to_string(), dest)
     }
@@ -123,19 +123,20 @@ pub enum KeyframesName {
     Ident(CustomIdent),
     /// <string>
     QuotedString(Atom),
 }
 
 impl KeyframesName {
     /// https://drafts.csswg.org/css-animations/#dom-csskeyframesrule-name
     pub fn from_ident(value: String) -> Self {
-        match CustomIdent::from_ident((&*value).into(), &["none"]) {
-            Ok(ident) => KeyframesName::Ident(ident),
-            Err(_) => KeyframesName::QuotedString(value.into()),
+        let custom_ident = CustomIdent::from_ident((&*value).into(), &["none"]).ok();
+        match custom_ident {
+            Some(ident) => KeyframesName::Ident(ident),
+            None => KeyframesName::QuotedString(value.into()),
         }
     }
 
     /// The name as an Atom
     pub fn as_atom(&self) -> &Atom {
         match *self {
             KeyframesName::Ident(ref ident) => &ident.0,
             KeyframesName::QuotedString(ref atom) => atom,
@@ -156,17 +157,17 @@ impl hash::Hash for KeyframesName {
         self.as_atom().hash(state)
     }
 }
 
 impl Parse for KeyframesName {
     fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
         match input.next() {
             Ok(Token::Ident(s)) => Ok(KeyframesName::Ident(CustomIdent::from_ident(s, &["none"])?)),
-            Ok(Token::QuotedString(s)) => Ok(KeyframesName::QuotedString(s.into())),
+            Ok(Token::QuotedString(s)) => Ok(KeyframesName::QuotedString(Atom::from(Cow::from(s)))),
             Ok(t) => Err(BasicParseError::UnexpectedToken(t).into()),
             Err(e) => Err(e.into()),
         }
     }
 }
 
 impl ToCss for KeyframesName {
     fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
--- a/servo/components/style/values/specified/calc.rs
+++ b/servo/components/style/values/specified/calc.rs
@@ -145,39 +145,35 @@ impl CalcNode {
     /// expression, for example.
     fn parse_one<'i, 't>(
         context: &ParserContext,
         input: &mut Parser<'i, 't>,
         expected_unit: CalcUnit)
         -> Result<Self, ParseError<'i>>
     {
         match (try!(input.next()), expected_unit) {
-            (Token::Number(ref value), _) => Ok(CalcNode::Number(value.value)),
-            (Token::Dimension(ref value, ref unit), CalcUnit::Length) |
-            (Token::Dimension(ref value, ref unit), CalcUnit::LengthOrPercentage) => {
-                NoCalcLength::parse_dimension(context, value.value, unit)
+            (Token::Number { value, .. }, _) => Ok(CalcNode::Number(value)),
+            (Token::Dimension { value, ref unit, .. }, CalcUnit::Length) |
+            (Token::Dimension { value, ref unit, .. }, CalcUnit::LengthOrPercentage) => {
+                NoCalcLength::parse_dimension(context, value, unit)
                     .map(CalcNode::Length)
                     .map_err(|()| StyleParseError::UnspecifiedError.into())
             }
-            (Token::Dimension(ref value, ref unit), CalcUnit::Angle) => {
-                Angle::parse_dimension(value.value,
-                                       unit,
-                                       /* from_calc = */ true)
+            (Token::Dimension { value, ref unit, .. }, CalcUnit::Angle) => {
+                Angle::parse_dimension(value, unit, /* from_calc = */ true)
                     .map(CalcNode::Angle)
                     .map_err(|()| StyleParseError::UnspecifiedError.into())
             }
-            (Token::Dimension(ref value, ref unit), CalcUnit::Time) => {
-                Time::parse_dimension(value.value,
-                                      unit,
-                                      /* from_calc = */ true)
+            (Token::Dimension { value, ref unit, .. }, CalcUnit::Time) => {
+                Time::parse_dimension(value, unit, /* from_calc = */ true)
                     .map(CalcNode::Time)
                     .map_err(|()| StyleParseError::UnspecifiedError.into())
             }
-            (Token::Percentage(ref value), CalcUnit::LengthOrPercentage) => {
-                Ok(CalcNode::Percentage(value.unit_value))
+            (Token::Percentage { unit_value, .. }, CalcUnit::LengthOrPercentage) => {
+                Ok(CalcNode::Percentage(unit_value))
             }
             (Token::ParenthesisBlock, _) => {
                 input.parse_nested_block(|i| {
                     CalcNode::parse(context, i, expected_unit)
                 })
             }
             (Token::Function(ref name), _) if name.eq_ignore_ascii_case("calc") => {
                 input.parse_nested_block(|i| {
--- a/servo/components/style/values/specified/color.rs
+++ b/servo/components/style/values/specified/color.rs
@@ -168,35 +168,34 @@ impl Color {
             Color::parse_quirky_color(input).map(|rgba| Color::rgba(rgba))
         })
     }
 
     /// Parse a <quirky-color> value.
     ///
     /// https://quirks.spec.whatwg.org/#the-hashless-hex-color-quirk
     fn parse_quirky_color<'i, 't>(input: &mut Parser<'i, 't>) -> Result<RGBA, ParseError<'i>> {
-        let (number, dimension) = match input.next()? {
-            Token::Number(number) => {
-                (number, None)
+        let (value, unit) = match input.next()? {
+            Token::Number { int_value: Some(integer), .. } => {
+                (integer, None)
             },
-            Token::Dimension(number, dimension) => {
-                (number, Some(dimension))
+            Token::Dimension { int_value: Some(integer), unit, .. } => {
+                (integer, Some(unit))
             },
             Token::Ident(ident) => {
                 if ident.len() != 3 && ident.len() != 6 {
                     return Err(StyleParseError::UnspecifiedError.into());
                 }
                 return parse_hash_color(ident.as_bytes())
                     .map_err(|()| StyleParseError::UnspecifiedError.into());
             }
             t => {
                 return Err(BasicParseError::UnexpectedToken(t).into());
             },
         };
-        let value = number.int_value.ok_or(StyleParseError::UnspecifiedError)?;
         if value < 0 {
             return Err(StyleParseError::UnspecifiedError.into());
         }
         let length = if value <= 9 {
             1
         } else if value <= 99 {
             2
         } else if value <= 999 {
@@ -205,26 +204,26 @@ impl Color {
             4
         } else if value <= 99999 {
             5
         } else if value <= 999999 {
             6
         } else {
             return Err(StyleParseError::UnspecifiedError.into())
         };
-        let total = length + dimension.as_ref().map_or(0, |d| d.len());
+        let total = length + unit.as_ref().map_or(0, |d| d.len());
         if total > 6 {
             return Err(StyleParseError::UnspecifiedError.into());
         }
         let mut serialization = [b'0'; 6];
         let space_padding = 6 - total;
         let mut written = space_padding;
         written += itoa::write(&mut serialization[written..], value).unwrap();
-        if let Some(dimension) = dimension {
-            written += (&mut serialization[written..]).write(dimension.as_bytes()).unwrap();
+        if let Some(unit) = unit {
+            written += (&mut serialization[written..]).write(unit.as_bytes()).unwrap();
         }
         debug_assert!(written == 6);
         parse_hash_color(&serialization).map_err(|()| StyleParseError::UnspecifiedError.into())
     }
 
     /// Returns false if the color is completely transparent, and
     /// true otherwise.
     pub fn is_non_transparent(&self) -> bool {
--- a/servo/components/style/values/specified/grid.rs
+++ b/servo/components/style/values/specified/grid.rs
@@ -14,18 +14,18 @@ use values::{CSSFloat, CustomIdent, Eith
 use values::computed::{self, Context, ToComputedValue};
 use values::generics::grid::{RepeatCount, TrackBreadth, TrackKeyword, TrackRepeat};
 use values::generics::grid::{TrackSize, TrackList, TrackListType};
 use values::specified::LengthOrPercentage;
 
 /// Parse a single flexible length.
 pub fn parse_flex<'i, 't>(input: &mut Parser<'i, 't>) -> Result<CSSFloat, ParseError<'i>> {
     match input.next()? {
-        Token::Dimension(ref value, ref unit) if unit.eq_ignore_ascii_case("fr") && value.value.is_sign_positive()
-            => Ok(value.value),
+        Token::Dimension { value, ref unit, .. } if unit.eq_ignore_ascii_case("fr") && value.is_sign_positive()
+            => Ok(value),
         t => Err(BasicParseError::UnexpectedToken(t).into()),
     }
 }
 
 impl Parse for TrackBreadth<LengthOrPercentage> {
     fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
         if let Ok(lop) = input.try(|i| LengthOrPercentage::parse_non_negative(context, i)) {
             return Ok(TrackBreadth::Breadth(lop))
--- a/servo/components/style/values/specified/image.rs
+++ b/servo/components/style/values/specified/image.rs
@@ -8,16 +8,17 @@
 //! [image]: https://drafts.csswg.org/css-images/#image-values
 
 use Atom;
 use cssparser::{Parser, Token, BasicParseError};
 use parser::{Parse, ParserContext};
 use selectors::parser::SelectorParseError;
 #[cfg(feature = "servo")]
 use servo_url::ServoUrl;
+use std::borrow::Cow;
 use std::cmp::Ordering;
 use std::f32::consts::PI;
 use std::fmt;
 use style_traits::{ToCss, ParseError, StyleParseError};
 use values::{Either, None_};
 use values::generics::image::{Circle, CompatMode, Ellipse, ColorStop as GenericColorStop};
 use values::generics::image::{EndingShape as GenericEndingShape, Gradient as GenericGradient};
 use values::generics::image::{GradientItem as GenericGradientItem, GradientKind as GenericGradientKind};
@@ -132,17 +133,17 @@ impl Image {
         GenericImage::Url(SpecifiedUrl::for_cascade(url))
     }
 
     /// Parses a `-moz-element(# <element-id>)`.
     fn parse_element<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Atom, ParseError<'i>> {
         input.try(|i| i.expect_function_matching("-moz-element"))?;
         input.parse_nested_block(|i| {
             match i.next()? {
-                Token::IDHash(id) => Ok(Atom::from(id)),
+                Token::IDHash(id) => Ok(Atom::from(Cow::from(id))),
                 t => Err(BasicParseError::UnexpectedToken(t).into()),
             }
         })
     }
 }
 
 impl Parse for Gradient {
     fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
@@ -694,28 +695,28 @@ impl Parse for ColorStop {
 }
 
 impl Parse for PaintWorklet {
     fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
         input.expect_function_matching("paint")?;
         input.parse_nested_block(|i| {
             let name = i.expect_ident()?;
             Ok(PaintWorklet {
-                name: Atom::from(name),
+                name: Atom::from(Cow::from(name)),
             })
         })
     }
 }
 
 impl Parse for ImageRect {
     fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
         input.try(|i| i.expect_function_matching("-moz-image-rect"))?;
         input.parse_nested_block(|i| {
             let string = i.expect_url_or_string()?;
-            let url = SpecifiedUrl::parse_from_string(string, context)?;
+            let url = SpecifiedUrl::parse_from_string(string.into_owned(), context)?;
             i.expect_comma()?;
             let top = NumberOrPercentage::parse_non_negative(context, i)?;
             i.expect_comma()?;
             let right = NumberOrPercentage::parse_non_negative(context, i)?;
             i.expect_comma()?;
             let bottom = NumberOrPercentage::parse_non_negative(context, i)?;
             i.expect_comma()?;
             let left = NumberOrPercentage::parse_non_negative(context, i)?;
--- a/servo/components/style/values/specified/length.rs
+++ b/servo/components/style/values/specified/length.rs
@@ -606,30 +606,32 @@ impl Length {
     #[inline]
     fn parse_internal<'i, 't>(context: &ParserContext,
                               input: &mut Parser<'i, 't>,
                               num_context: AllowedLengthType,
                               allow_quirks: AllowQuirks)
                               -> Result<Length, ParseError<'i>> {
         let token = try!(input.next());
         match token {
-            Token::Dimension(ref value, ref unit) if num_context.is_ok(context.parsing_mode, value.value) =>
-                Length::parse_dimension(context, value.value, unit),
-            Token::Number(ref value) if num_context.is_ok(context.parsing_mode, value.value) => {
-                if value.value != 0. &&
+            Token::Dimension { value, ref unit, .. } if num_context.is_ok(context.parsing_mode, value) => {
+                Length::parse_dimension(context, value, unit)
+            }
+            Token::Number { value, .. } if num_context.is_ok(context.parsing_mode, value) => {
+                if value != 0. &&
                    !context.parsing_mode.allows_unitless_lengths() &&
                    !allow_quirks.allowed(context.quirks_mode) {
                     return Err(StyleParseError::UnspecifiedError.into())
                 }
-                Ok(Length::NoCalc(NoCalcLength::Absolute(AbsoluteLength::Px(value.value))))
+                Ok(Length::NoCalc(NoCalcLength::Absolute(AbsoluteLength::Px(value))))
             },
-            Token::Function(ref name) if name.eq_ignore_ascii_case("calc") =>
+            Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
                 return input.parse_nested_block(|input| {
                     CalcNode::parse_length(context, input, num_context).map(|calc| Length::Calc(Box::new(calc)))
-                }),
+                })
+            }
             _ => Err(())
         }.map_err(|()| BasicParseError::UnexpectedToken(token).into())
     }
 
     /// Parse a non-negative length
     #[inline]
     pub fn parse_non_negative<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
                                       -> Result<Length, ParseError<'i>> {
@@ -715,18 +717,18 @@ impl ToCss for Percentage {
 
 impl Percentage {
     /// Parse a specific kind of percentage.
     pub fn parse_with_clamping_mode<'i, 't>(context: &ParserContext,
                                             input: &mut Parser<'i, 't>,
                                             num_context: AllowedNumericType)
                                             -> Result<Self, ParseError<'i>> {
         match try!(input.next()) {
-            Token::Percentage(ref value) if num_context.is_ok(context.parsing_mode, value.unit_value) => {
-                Ok(Percentage(value.unit_value))
+            Token::Percentage { unit_value, .. } if num_context.is_ok(context.parsing_mode, unit_value) => {
+                Ok(Percentage(unit_value))
             }
             t => Err(BasicParseError::UnexpectedToken(t).into())
         }
     }
 
     /// Parses a percentage token, but rejects it if it's negative.
     pub fn parse_non_negative<'i, 't>(context: &ParserContext,
                                       input: &mut Parser<'i, 't>)
@@ -799,35 +801,37 @@ impl LengthOrPercentage {
     fn parse_internal<'i, 't>(context: &ParserContext,
                               input: &mut Parser<'i, 't>,
                               num_context: AllowedLengthType,
                               allow_quirks: AllowQuirks)
                               -> Result<LengthOrPercentage, ParseError<'i>>
     {
         let token = try!(input.next());
         match token {
-            Token::Dimension(ref value, ref unit) if num_context.is_ok(context.parsing_mode, value.value) =>
-                NoCalcLength::parse_dimension(context, value.value, unit).map(LengthOrPercentage::Length),
-            Token::Percentage(ref value) if num_context.is_ok(context.parsing_mode, value.unit_value) =>
-                return Ok(LengthOrPercentage::Percentage(Percentage(value.unit_value))),
-            Token::Number(value) if num_context.is_ok(context.parsing_mode, value.value) => {
-                if value.value != 0. &&
+            Token::Dimension { value, ref unit, .. } if num_context.is_ok(context.parsing_mode, value) => {
+                NoCalcLength::parse_dimension(context, value, unit).map(LengthOrPercentage::Length)
+            }
+            Token::Percentage { unit_value, .. } if num_context.is_ok(context.parsing_mode, unit_value) => {
+                return Ok(LengthOrPercentage::Percentage(Percentage(unit_value)))
+            }
+            Token::Number { value, .. } if num_context.is_ok(context.parsing_mode, value) => {
+                if value != 0. &&
                    !context.parsing_mode.allows_unitless_lengths() &&
                    !allow_quirks.allowed(context.quirks_mode) {
                     Err(())
                 } else {
-                    return Ok(LengthOrPercentage::Length(NoCalcLength::from_px(value.value)))
+                    return Ok(LengthOrPercentage::Length(NoCalcLength::from_px(value)))
                 }
             }
             Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
                 let calc = try!(input.parse_nested_block(|i| {
                     CalcNode::parse_length_or_percentage(context, i, num_context)
                 }));
                 return Ok(LengthOrPercentage::Calc(Box::new(calc)))
-            },
+            }
             _ => Err(())
         }.map_err(|()| BasicParseError::UnexpectedToken(token).into())
     }
 
     /// Parse a non-negative length.
     #[inline]
     pub fn parse_non_negative<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
                                       -> Result<LengthOrPercentage, ParseError<'i>> {
@@ -933,38 +937,41 @@ impl From<Percentage> for LengthOrPercen
 impl LengthOrPercentageOrAuto {
     fn parse_internal<'i, 't>(context: &ParserContext,
                               input: &mut Parser<'i, 't>,
                               num_context: AllowedLengthType,
                               allow_quirks: AllowQuirks)
                               -> Result<Self, ParseError<'i>> {
         let token = try!(input.next());
         match token {
-            Token::Dimension(ref value, ref unit) if num_context.is_ok(context.parsing_mode, value.value) =>
-                NoCalcLength::parse_dimension(context, value.value, unit).map(LengthOrPercentageOrAuto::Length),
-            Token::Percentage(ref value) if num_context.is_ok(context.parsing_mode, value.unit_value) =>
-                Ok(LengthOrPercentageOrAuto::Percentage(Percentage(value.unit_value))),
-            Token::Number(ref value) if num_context.is_ok(context.parsing_mode, value.value) => {
-                if value.value != 0. &&
+            Token::Dimension { value, ref unit, .. } if num_context.is_ok(context.parsing_mode, value) => {
+                NoCalcLength::parse_dimension(context, value, unit).map(LengthOrPercentageOrAuto::Length)
+            }
+            Token::Percentage { unit_value, .. } if num_context.is_ok(context.parsing_mode, unit_value) => {
+                Ok(LengthOrPercentageOrAuto::Percentage(Percentage(unit_value)))
+            }
+            Token::Number { value, .. } if num_context.is_ok(context.parsing_mode, value) => {
+                if value != 0. &&
                    !context.parsing_mode.allows_unitless_lengths() &&
                    !allow_quirks.allowed(context.quirks_mode) {
                     return Err(StyleParseError::UnspecifiedError.into())
                 }
                 Ok(LengthOrPercentageOrAuto::Length(
-                    NoCalcLength::Absolute(AbsoluteLength::Px(value.value))
+                    NoCalcLength::Absolute(AbsoluteLength::Px(value))
                 ))
             }
-            Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") =>
-                Ok(LengthOrPercentageOrAuto::Auto),
+            Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") => {
+                Ok(LengthOrPercentageOrAuto::Auto)
+            }
             Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
                 let calc = try!(input.parse_nested_block(|i| {
                     CalcNode::parse_length_or_percentage(context, i, num_context)
                 }));
                 Ok(LengthOrPercentageOrAuto::Calc(Box::new(calc)))
-            },
+            }
             _ => Err(())
         }.map_err(|()| BasicParseError::UnexpectedToken(token).into())
     }
 
     /// Parse a non-negative length, percentage, or auto.
     #[inline]
     pub fn parse_non_negative<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
                                       -> Result<LengthOrPercentageOrAuto, ParseError<'i>> {
@@ -1029,35 +1036,37 @@ impl LengthOrPercentageOrNone {
     fn parse_internal<'i, 't>(context: &ParserContext,
                               input: &mut Parser<'i, 't>,
                               num_context: AllowedLengthType,
                               allow_quirks: AllowQuirks)
                               -> Result<LengthOrPercentageOrNone, ParseError<'i>>
     {
         let token = try!(input.next());
         match token {
-            Token::Dimension(ref value, ref unit) if num_context.is_ok(context.parsing_mode, value.value) =>
-                NoCalcLength::parse_dimension(context, value.value, unit).map(LengthOrPercentageOrNone::Length),
-            Token::Percentage(ref value) if num_context.is_ok(context.parsing_mode, value.unit_value) =>
-                Ok(LengthOrPercentageOrNone::Percentage(Percentage(value.unit_value))),
-            Token::Number(value) if num_context.is_ok(context.parsing_mode, value.value) => {
-                if value.value != 0. && !context.parsing_mode.allows_unitless_lengths() &&
+            Token::Dimension { value, ref unit, .. } if num_context.is_ok(context.parsing_mode, value) => {
+                NoCalcLength::parse_dimension(context, value, unit).map(LengthOrPercentageOrNone::Length)
+            }
+            Token::Percentage { unit_value, .. } if num_context.is_ok(context.parsing_mode, unit_value) => {
+                Ok(LengthOrPercentageOrNone::Percentage(Percentage(unit_value)))
+            }
+            Token::Number { value, .. } if num_context.is_ok(context.parsing_mode, value) => {
+                if value != 0. && !context.parsing_mode.allows_unitless_lengths() &&
                    !allow_quirks.allowed(context.quirks_mode) {
                     return Err(StyleParseError::UnspecifiedError.into())
                 }
                 Ok(LengthOrPercentageOrNone::Length(
-                    NoCalcLength::Absolute(AbsoluteLength::Px(value.value))
+                    NoCalcLength::Absolute(AbsoluteLength::Px(value))
                 ))
             }
             Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
                 let calc = try!(input.parse_nested_block(|i| {
                     CalcNode::parse_length_or_percentage(context, i, num_context)
                 }));
                 Ok(LengthOrPercentageOrNone::Calc(Box::new(calc)))
-            },
+            }
             Token::Ident(ref value) if value.eq_ignore_ascii_case("none") =>
                 Ok(LengthOrPercentageOrNone::None),
             _ => Err(())
         }.map_err(|()| BasicParseError::UnexpectedToken(token).into())
     }
 
     /// Parse a non-negative LengthOrPercentageOrNone.
     #[inline]
@@ -1111,33 +1120,38 @@ pub enum LengthOrPercentageOrAutoOrConte
 
 impl LengthOrPercentageOrAutoOrContent {
     /// Parse a non-negative LengthOrPercentageOrAutoOrContent.
     pub fn parse_non_negative<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
                                       -> Result<Self, ParseError<'i>> {
         let num_context = AllowedLengthType::NonNegative;
         let token = try!(input.next());
         match token {
-            Token::Dimension(ref value, ref unit) if num_context.is_ok(context.parsing_mode, value.value) =>
-                NoCalcLength::parse_dimension(context, value.value, unit)
-                             .map(LengthOrPercentageOrAutoOrContent::Length),
-            Token::Percentage(ref value) if num_context.is_ok(context.parsing_mode, value.unit_value) =>
-                Ok(LengthOrPercentageOrAutoOrContent::Percentage(Percentage(value.unit_value))),
-            Token::Number(ref value) if value.value == 0. =>
-                Ok(Self::zero()),
-            Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") =>
-                Ok(LengthOrPercentageOrAutoOrContent::Auto),
-            Token::Ident(ref value) if value.eq_ignore_ascii_case("content") =>
-                Ok(LengthOrPercentageOrAutoOrContent::Content),
+            Token::Dimension { value, ref unit, .. } if num_context.is_ok(context.parsing_mode, value) => {
+                NoCalcLength::parse_dimension(context, value, unit)
+                             .map(LengthOrPercentageOrAutoOrContent::Length)
+            }
+            Token::Percentage { unit_value, .. } if num_context.is_ok(context.parsing_mode, unit_value) => {
+                Ok(LengthOrPercentageOrAutoOrContent::Percentage(Percentage(unit_value)))
+            }
+            Token::Number { value, .. } if value == 0. => {
+                Ok(Self::zero())
+            }
+            Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") => {
+                Ok(LengthOrPercentageOrAutoOrContent::Auto)
+            }
+            Token::Ident(ref value) if value.eq_ignore_ascii_case("content") => {
+                Ok(LengthOrPercentageOrAutoOrContent::Content)
+            }
             Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
                 let calc = try!(input.parse_nested_block(|i| {
                     CalcNode::parse_length_or_percentage(context, i, num_context)
                 }));
                 Ok(LengthOrPercentageOrAutoOrContent::Calc(Box::new(calc)))
-            },
+            }
             _ => Err(())
         }.map_err(|()| BasicParseError::UnexpectedToken(token).into())
     }
 
     /// Returns the `auto` value.
     pub fn auto() -> Self {
         LengthOrPercentageOrAutoOrContent::Auto
     }
--- a/servo/components/style/values/specified/mod.rs
+++ b/servo/components/style/values/specified/mod.rs
@@ -8,16 +8,17 @@
 
 use Namespace;
 use context::QuirksMode;
 use cssparser::{Parser, Token, serialize_identifier, BasicParseError};
 use parser::{ParserContext, Parse};
 use self::grid::TrackSizeOrRepeat;
 use self::url::SpecifiedUrl;
 use std::ascii::AsciiExt;
+use std::borrow::Cow;
 use std::f32;
 use std::fmt;
 use style_traits::{ToCss, ParseError, StyleParseError};
 use style_traits::values::specified::AllowedNumericType;
 use super::{Auto, CSSFloat, CSSInteger, Either, None_};
 use super::computed::{self, Context};
 use super::computed::{Shadow as ComputedShadow, ToComputedValue};
 use super::generics::grid::{TrackBreadth as GenericTrackBreadth, TrackSize as GenericTrackSize};
@@ -74,33 +75,33 @@ use values::computed::ComputedValueAsSpe
 #[cfg(feature = "servo")]
 pub use ::servo::url::*;
 #[cfg(feature = "gecko")]
 pub use ::gecko::url::*;
 
 impl Parse for SpecifiedUrl {
     fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
         let url = try!(input.expect_url());
-        Self::parse_from_string(url, context)
+        Self::parse_from_string(url.into_owned(), context)
     }
 }
 
 impl Eq for SpecifiedUrl {}
 
 // TODO(emilio): Maybe consider ComputedUrl to save a word in style structs?
 impl ComputedValueAsSpecified for SpecifiedUrl {}
 
 no_viewport_percentage!(SpecifiedUrl);
 }
 
 /// Parse an `<integer>` value, handling `calc()` correctly.
 pub fn parse_integer<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
                              -> Result<Integer, ParseError<'i>> {
     match try!(input.next()) {
-        Token::Number(ref value) => value.int_value.ok_or(StyleParseError::UnspecifiedError.into()).map(Integer::new),
+        Token::Number { int_value: Some(v), .. } => Ok(Integer::new(v)),
         Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
             let result = try!(input.parse_nested_block(|i| {
                 CalcNode::parse_integer(context, i)
             }));
 
             Ok(Integer::from_calc(result))
         }
         t => Err(BasicParseError::UnexpectedToken(t).into())
@@ -115,19 +116,19 @@ pub fn parse_number<'i, 't>(context: &Pa
 }
 
 /// Parse a `<number>` value, with a given clamping mode.
 pub fn parse_number_with_clamping_mode<'i, 't>(context: &ParserContext,
                                                input: &mut Parser<'i, 't>,
                                                clamping_mode: AllowedNumericType)
                                                -> Result<Number, ParseError<'i>> {
     match try!(input.next()) {
-        Token::Number(ref value) if clamping_mode.is_ok(context.parsing_mode, value.value) => {
+        Token::Number { value, .. } if clamping_mode.is_ok(context.parsing_mode, value) => {
             Ok(Number {
-                value: value.value.min(f32::MAX).max(f32::MIN),
+                value: value.min(f32::MAX).max(f32::MIN),
                 calc_clamping_mode: None,
             })
         },
         Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
             let result = try!(input.parse_nested_block(|i| {
                 CalcNode::parse_number(context, i)
             }));
 
@@ -221,20 +222,18 @@ impl Angle {
     }
 }
 
 impl Parse for Angle {
     /// Parses an angle according to CSS-VALUES § 6.1.
     fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
         let token = try!(input.next());
         match token {
-            Token::Dimension(ref value, ref unit) => {
-                Angle::parse_dimension(value.value,
-                                       unit,
-                                       /* from_calc = */ false)
+            Token::Dimension { value, ref unit, .. } => {
+                Angle::parse_dimension(value, unit, /* from_calc = */ false)
             }
             Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
                 return input.parse_nested_block(|i| CalcNode::parse_angle(context, i))
             }
             _ => Err(())
         }.map_err(|()| BasicParseError::UnexpectedToken(token).into())
     }
 }
@@ -263,22 +262,20 @@ impl Angle {
     /// angle and stores it as '0deg'.
     ///
     /// We can remove this and get back to the unified version Angle::parse once
     /// https://github.com/w3c/csswg-drafts/issues/1162 is resolved.
     pub fn parse_with_unitless<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
                                        -> Result<Self, ParseError<'i>> {
         let token = try!(input.next());
         match token {
-            Token::Dimension(ref value, ref unit) => {
-                Angle::parse_dimension(value.value,
-                                       unit,
-                                       /* from_calc = */ false)
+            Token::Dimension { value, ref unit, .. } => {
+                Angle::parse_dimension(value, unit, /* from_calc = */ false)
             }
-            Token::Number(ref value) if value.value == 0. => Ok(Angle::zero()),
+            Token::Number { value, .. } if value == 0. => Ok(Angle::zero()),
             Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
                 return input.parse_nested_block(|i| CalcNode::parse_angle(context, i))
             }
             _ => Err(())
         }.map_err(|()| BasicParseError::UnexpectedToken(token).into())
     }
 }
 
@@ -367,18 +364,18 @@ impl Time {
         use style_traits::PARSING_MODE_DEFAULT;
 
         match input.next() {
             // Note that we generally pass ParserContext to is_ok() to check
             // that the ParserMode of the ParserContext allows all numeric
             // values for SMIL regardless of clamping_mode, but in this Time
             // value case, the value does not animate for SMIL at all, so we use
             // PARSING_MODE_DEFAULT directly.
-            Ok(Token::Dimension(ref value, ref unit)) if clamping_mode.is_ok(PARSING_MODE_DEFAULT, value.value) => {
-                Time::parse_dimension(value.value, &unit, /* from_calc = */ false)
+            Ok(Token::Dimension { value, ref unit, .. }) if clamping_mode.is_ok(PARSING_MODE_DEFAULT, value) => {
+                Time::parse_dimension(value, unit, /* from_calc = */ false)
                     .map_err(|()| StyleParseError::UnspecifiedError.into())
             }
             Ok(Token::Function(ref name)) if name.eq_ignore_ascii_case("calc") => {
                 match input.parse_nested_block(|i| CalcNode::parse_time(context, i)) {
                     Ok(time) if clamping_mode.is_ok(PARSING_MODE_DEFAULT, time.seconds) => Ok(time),
                     _ => Err(StyleParseError::UnspecifiedError.into()),
                 }
             }
@@ -1101,17 +1098,17 @@ impl Attr {
             }
             // must be followed by an ident
             let second_token = match input.next_including_whitespace()? {
                 Token::Ident(second) => second,
                 t => return Err(BasicParseError::UnexpectedToken(t).into()),
             };
 
             let ns_with_id = if let Some(ns) = first {
-                let ns: Namespace = ns.into();
+                let ns = Namespace::from(Cow::from(ns));
                 let id: Result<_, ParseError> =
                     get_id_for_namespace(&ns, context)
                     .map_err(|()| StyleParseError::UnspecifiedError.into());
                 Some((ns, id?))
             } else {
                 None
             };
             return Ok(Attr {
--- a/servo/components/style_traits/Cargo.toml
+++ b/servo/components/style_traits/Cargo.toml
@@ -11,14 +11,14 @@ path = "lib.rs"
 
 [features]
 servo = ["heapsize", "heapsize_derive", "serde", "cssparser/heapsize", "cssparser/serde"]
 gecko = []
 
 [dependencies]
 app_units = "0.5"
 bitflags = "0.7"
-cssparser = "0.15"
+cssparser = "0.16"
 euclid = "0.15"
 heapsize = {version = "0.4", optional = true}
 heapsize_derive = {version = "0.1", optional = true}
 selectors = { path = "../selectors" }
 serde = {version = "1.0", optional = true}
--- a/servo/components/style_traits/lib.rs
+++ b/servo/components/style_traits/lib.rs
@@ -17,18 +17,18 @@ extern crate app_units;
 #[macro_use] extern crate bitflags;
 #[macro_use] extern crate cssparser;
 extern crate euclid;
 #[cfg(feature = "servo")] extern crate heapsize;
 #[cfg(feature = "servo")] #[macro_use] extern crate heapsize_derive;
 extern crate selectors;
 #[cfg(feature = "servo")] #[macro_use] extern crate serde;
 
+use cssparser::CompactCowStr;
 use selectors::parser::SelectorParseError;
-use std::borrow::Cow;
 
 /// Opaque type stored in type-unsafe work queues for parallel layout.
 /// Must be transmutable to and from `TNode`.
 pub type UnsafeNode = (usize, usize);
 
 /// Represents a mobile style pinch zoom factor.
 /// TODO(gw): Once WR supports pinch zoom, use a type directly from webrender_traits.
 #[derive(Clone, Copy, Debug, PartialEq)]
@@ -90,29 +90,29 @@ pub enum StyleParseError<'i> {
     UnbalancedCloseSquareBracketInDeclarationValueBlock,
     /// Unexpected closing curly bracket in a DVB.
     UnbalancedCloseCurlyBracketInDeclarationValueBlock,
     /// A property declaration parsing error.
     PropertyDeclaration(PropertyDeclarationParseError),
     /// A property declaration value had input remaining after successfully parsing.
     PropertyDeclarationValueNotExhausted,
     /// An unexpected dimension token was encountered.
-    UnexpectedDimension(Cow<'i, str>),
+    UnexpectedDimension(CompactCowStr<'i>),
     /// A media query using a ranged expression with no value was encountered.
     RangedExpressionWithNoValue,
     /// A function was encountered that was not expected.
-    UnexpectedFunction(Cow<'i, str>),
+    UnexpectedFunction(CompactCowStr<'i>),
     /// @namespace must be before any rule but @charset and @import
     UnexpectedNamespaceRule,
     /// @import must be before any rule but @charset
     UnexpectedImportRule,
     /// Unexpected @charset rule encountered.
     UnexpectedCharsetRule,
     /// Unsupported @ rule
-    UnsupportedAtRule(Cow<'i, str>),
+    UnsupportedAtRule(CompactCowStr<'i>),
     /// A placeholder for many sources of errors that require more specific variants.
     UnspecifiedError,
 }
 
 /// The result of parsing a property declaration.
 #[derive(Eq, PartialEq, Copy, Clone, Debug)]
 pub enum PropertyDeclarationParseError {
     /// The property declaration was for an unknown property.
--- a/servo/components/style_traits/viewport.rs
+++ b/servo/components/style_traits/viewport.rs
@@ -144,22 +144,25 @@ impl Zoom {
         use cssparser::Token;
         use values::specified::AllowedLengthType::NonNegative;
 
         match try!(input.next()) {
             // TODO: This parse() method should take ParserContext as an
             // argument, and pass ParsingMode owned by the ParserContext to
             // is_ok() instead of using PARSING_MODE_DEFAULT directly.
             // In order to do so, we might want to move these stuff into style::stylesheets::viewport_rule.
-            Token::Percentage(ref value) if NonNegative.is_ok(PARSING_MODE_DEFAULT, value.unit_value) =>
-                Ok(Zoom::Percentage(value.unit_value)),
-            Token::Number(ref value) if NonNegative.is_ok(PARSING_MODE_DEFAULT, value.value) =>
-                Ok(Zoom::Number(value.value)),
-            Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") =>
-                Ok(Zoom::Auto),
+            Token::Percentage { unit_value, .. } if NonNegative.is_ok(PARSING_MODE_DEFAULT, unit_value) => {
+                Ok(Zoom::Percentage(unit_value))
+            }
+            Token::Number { value, .. } if NonNegative.is_ok(PARSING_MODE_DEFAULT, value) => {
+                Ok(Zoom::Number(value))
+            }
+            Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") => {
+                Ok(Zoom::Auto)
+            }
             t => Err(CssParseError::Basic(BasicParseError::UnexpectedToken(t)))
         }
     }
 
     /// Get this zoom value as a float value. Returns `None` if the value is the
     /// `auto` keyword.
     #[inline]
     pub fn to_f32(&self) -> Option<f32> {
--- a/servo/ports/geckolib/Cargo.toml
+++ b/servo/ports/geckolib/Cargo.toml
@@ -11,17 +11,17 @@ crate-type = ["staticlib", "rlib"]
 
 [features]
 bindgen = ["style/use_bindgen"]
 testing = ["style/testing"]
 gecko_debug = ["style/gecko_debug"]
 
 [dependencies]
 atomic_refcell = "0.1"
-cssparser = "0.15"
+cssparser = "0.16"
 env_logger = {version = "0.4", default-features = false} # disable `regex` to reduce code size
 libc = "0.2"
 log = {version = "0.3.5", features = ["release_max_level_info"]}
 nsstring_vendor = {path = "../../components/style/gecko_bindings/nsstring_vendor"}
 parking_lot = "0.3"
 selectors = {path = "../../components/selectors"}
 style = {path = "../../components/style", features = ["gecko"]}
 style_traits = {path = "../../components/style_traits"}
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -2,17 +2,16 @@
  * 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 atomic_refcell::AtomicRefMut;
 use cssparser::{Parser, ParserInput};
 use cssparser::ToCss as ParserToCss;
 use env_logger::LogBuilder;
 use selectors::Element;
-use std::borrow::Cow;
 use std::env;
 use std::fmt::Write;
 use std::ptr;
 use style::context::{QuirksMode, SharedStyleContext, StyleContext};
 use style::context::ThreadLocalStyleContext;
 use style::data::{ElementData, ElementStyles, RestyleData};
 use style::dom::{AnimationOnlyDirtyDescendants, DirtyDescendants};
 use style::dom::{ShowSubtreeData, TElement, TNode};
@@ -1647,17 +1646,19 @@ pub extern "C" fn Servo_ParseEasing(easi
     let context = ParserContext::new(Origin::Author,
                                      url_data,
                                      &reporter,
                                      Some(CssRuleType::Style),
                                      PARSING_MODE_DEFAULT,
                                      QuirksMode::NoQuirks);
     let easing = unsafe { (*easing).to_string() };
     let mut input = ParserInput::new(&easing);
-    match transition_timing_function::single_value::parse(&context, &mut Parser::new(&mut input)) {
+    let mut parser = Parser::new(&mut input);
+    let result = transition_timing_function::single_value::parse(&context, &mut parser);
+    match result {
         Ok(parsed_easing) => {
             *output = parsed_easing.into();
             true
         },
         Err(_) => false
     }
 }
 
@@ -1821,17 +1822,17 @@ pub extern "C" fn Servo_DeclarationBlock
             false
         }
     })
 }
 
 macro_rules! get_property_id_from_property {
     ($property: ident, $ret: expr) => {{
         let property = unsafe { $property.as_ref().unwrap().as_str_unchecked() };
-        match PropertyId::parse(Cow::Borrowed(property)) {
+        match PropertyId::parse(property.into()) {
             Ok(property_id) => property_id,
             Err(_) => { return $ret; }
         }
     }}
 }
 
 fn get_property_value(declarations: RawServoDeclarationBlockBorrowed,
                       property_id: PropertyId, value: *mut nsAString) {
@@ -2346,17 +2347,18 @@ pub extern "C" fn Servo_DeclarationBlock
                                                        value: *const nsAString) {
     use cssparser::{Parser, ParserInput};
     use style::properties::PropertyDeclaration;
     use style::properties::longhands::font_family::SpecifiedValue as FontFamily;
 
     let string = unsafe { (*value).to_string() };
     let mut input = ParserInput::new(&string);
     let mut parser = Parser::new(&mut input);
-    if let Ok(family) = FontFamily::parse(&mut parser) {
+    let result = FontFamily::parse(&mut parser);
+    if let Ok(family) = result {
         if parser.is_exhausted() {
             let decl = PropertyDeclaration::FontFamily(Box::new(family));
             write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
                 decls.push(decl, Importance::Normal);
             })
         }
     }
 }
--- a/servo/tests/unit/gfx/Cargo.toml
+++ b/servo/tests/unit/gfx/Cargo.toml
@@ -5,12 +5,12 @@ authors = ["The Servo Project Developers
 license = "MPL-2.0"
 
 [lib]
 name = "gfx_tests"
 path = "lib.rs"
 doctest = false
 
 [dependencies]
-cssparser = "0.15"
+cssparser = "0.16"
 gfx = {path = "../../../components/gfx"}
 ipc-channel = "0.8"
 style = {path = "../../../components/style"}
--- a/servo/tests/unit/style/Cargo.toml
+++ b/servo/tests/unit/style/Cargo.toml
@@ -10,17 +10,17 @@ path = "lib.rs"
 doctest = false
 
 [features]
 testing = ["style/testing"]
 
 [dependencies]
 byteorder = "1.0"
 app_units = "0.5"
-cssparser = "0.15"
+cssparser = "0.16"
 euclid = "0.15"
 html5ever = "0.18"
 parking_lot = "0.3"
 rayon = "0.8"
 rustc-serialize = "0.3"
 selectors = {path = "../../../components/selectors"}
 servo_atoms = {path = "../../../components/atoms"}
 servo_config = {path = "../../../components/config"}
--- a/servo/tests/unit/style/parsing/mod.rs
+++ b/servo/tests/unit/style/parsing/mod.rs
@@ -82,23 +82,24 @@ macro_rules! assert_roundtrip_with_conte
             let parsed = $fun(context, i)
                          .expect(&format!("Failed to parse {}", $input));
             let serialized = ToCss::to_css_string(&parsed);
             assert_eq!(serialized, $output);
             Ok(serialized)
         }, &mut input).unwrap();
 
         let mut input = ::cssparser::ParserInput::new(&serialized);
-        super::parse_input(|context, i| {
+        let unwrapped = super::parse_input(|context, i| {
             let re_parsed = $fun(context, i)
                             .expect(&format!("Failed to parse serialization {}", $input));
             let re_serialized = ToCss::to_css_string(&re_parsed);
             assert_eq!(serialized, re_serialized);
             Ok(())
-        }, &mut input).unwrap()
+        }, &mut input).unwrap();
+        unwrapped
     }}
 }
 
 macro_rules! assert_roundtrip {
     ($fun:expr, $string:expr) => {
         assert_roundtrip!($fun, $string, $string);
     };
     ($fun:expr, $input:expr, $output:expr) => {
--- a/servo/tests/unit/style/properties/mod.rs
+++ b/servo/tests/unit/style/properties/mod.rs
@@ -35,22 +35,23 @@ macro_rules! assert_roundtrip_with_conte
             let parsed = $fun(context, i)
                          .expect(&format!("Failed to parse {}", $input));
             let serialized = ToCss::to_css_string(&parsed);
             assert_eq!(serialized, $output);
             Ok(serialized)
         }, $input).unwrap();
 
         let mut input = ::cssparser::ParserInput::new(&serialized);
-        parse_input(|context, i| {
+        let unwrapped = parse_input(|context, i| {
             let re_parsed = $fun(context, i)
                             .expect(&format!("Failed to parse serialization {}", $input));
             let re_serialized = ToCss::to_css_string(&re_parsed);
             assert_eq!(serialized, re_serialized);
             Ok(())
-        }, &mut input).unwrap()
+        }, &mut input).unwrap();
+        unwrapped
     }}
 }
 
 mod background;
 mod scaffolding;
 mod serialization;
 mod viewport;
--- a/servo/tests/unit/stylo/Cargo.toml
+++ b/servo/tests/unit/stylo/Cargo.toml
@@ -11,17 +11,17 @@ name = "stylo_tests"
 path = "lib.rs"
 doctest = false
 
 [features]
 testing = ["style/testing"]
 
 [dependencies]
 atomic_refcell = "0.1"
-cssparser = "0.15"
+cssparser = "0.16"
 env_logger = "0.4"
 euclid = "0.15"
 geckoservo = {path = "../../../ports/geckolib"}
 libc = "0.2"
 log = {version = "0.3.5", features = ["release_max_level_info"]}
 selectors = {path = "../../../components/selectors", features = ["gecko_like_types"]}
 size_of_test = {path = "../../../components/size_of_test"}
 style_traits = {path = "../../../components/style_traits"}