servo: Merge #18025 - Update to cssparser 0.19, count line numbers during tokenization (from servo:line-counting); r=jdm
authorSimon Sapin <simon.sapin@exyr.org>
Wed, 09 Aug 2017 16:16:33 -0500
changeset 373838 7d250c6f693ad6c1f1f8e3f9733da8d1f504ce2e
parent 373837 3a1579259a05dc44426299d2051bc3ed449d95d5
child 373839 4bbcbd1d473d4802021f62422207b8404321bade
push id93597
push userarchaeopteryx@coole-files.de
push dateThu, 10 Aug 2017 15:43:43 +0000
treeherdermozilla-inbound@17a9aa5732e5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdm
bugs18025
milestone57.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 #18025 - Update to cssparser 0.19, count line numbers during tokenization (from servo:line-counting); r=jdm https://github.com/servo/rust-cssparser/pull/177 Also simplify the `ParseErrorReporter` trait a bit. Source-Repo: https://github.com/servo/servo Source-Revision: 845131c425ebd50eea2fe5bf6005b6c304664242
servo/Cargo.lock
servo/components/canvas/Cargo.toml
servo/components/canvas_traits/Cargo.toml
servo/components/script/Cargo.toml
servo/components/script_layout_interface/Cargo.toml
servo/components/script_layout_interface/reporter.rs
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/parser.rs
servo/components/style/properties/declaration_block.rs
servo/components/style/properties/properties.mako.rs
servo/components/style/stylesheets/font_feature_values_rule.rs
servo/components/style/stylesheets/keyframes_rule.rs
servo/components/style/stylesheets/rule_parser.rs
servo/components/style/stylesheets/stylesheet.rs
servo/components/style/stylesheets/viewport_rule.rs
servo/components/style/values/specified/calc.rs
servo/components/style/values/specified/color.rs
servo/components/style_traits/Cargo.toml
servo/ports/geckolib/Cargo.toml
servo/ports/geckolib/error_reporter.rs
servo/tests/unit/gfx/Cargo.toml
servo/tests/unit/style/Cargo.toml
servo/tests/unit/style/media_queries.rs
servo/tests/unit/style/rule_tree/bench.rs
servo/tests/unit/style/stylesheets.rs
servo/tests/unit/style/stylist.rs
servo/tests/unit/stylo/Cargo.toml
--- a/servo/Cargo.lock
+++ b/servo/Cargo.lock
@@ -320,32 +320,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.20.1 (git+https://github.com/servo/rust-azure)",
  "canvas_traits 0.0.1",
- "cssparser 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "gleam 0.4.7 (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_api 0.48.0 (git+https://github.com/servo/webrender)",
 ]
 
 [[package]]
 name = "canvas_traits"
 version = "0.0.1"
 dependencies = [
- "cssparser 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.1 (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_api 0.48.0 (git+https://github.com/servo/webrender)",
 ]
 
@@ -581,17 +581,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.18.0"
+version = "0.19.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)",
@@ -1021,17 +1021,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.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.19.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.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.19.0",
  "servo_arc 0.0.1",
  "style 0.0.1",
@@ -1089,17 +1089,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.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.19.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"
@@ -2462,17 +2462,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.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.19.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.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "gleam 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2535,17 +2535,17 @@ dependencies = [
 
 [[package]]
 name = "script_layout_interface"
 version = "0.0.1"
 dependencies = [
  "app_units 0.5.2 (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.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.1 (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)",
@@ -2609,17 +2609,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.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.19.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",
@@ -3008,17 +3008,17 @@ dependencies = [
  "arraydeque 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "arrayvec 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bindgen 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "cssparser 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.19.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.1 (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)",
  "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3063,17 +3063,17 @@ dependencies = [
 ]
 
 [[package]]
 name = "style_tests"
 version = "0.0.1"
 dependencies = [
  "app_units 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cssparser 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.1 (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.4.4 (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_arc 0.0.1",
  "servo_atoms 0.0.1",
@@ -3085,32 +3085,32 @@ dependencies = [
 ]
 
 [[package]]
 name = "style_traits"
 version = "0.0.1"
 dependencies = [
  "app_units 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)",
- "cssparser 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.1 (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)",
  "servo_atoms 0.0.1",
  "webrender_api 0.48.0 (git+https://github.com/servo/webrender)",
 ]
 
 [[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.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cssparser 0.19.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.1 (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)",
  "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.19.0",
  "size_of_test 0.0.1",
@@ -3690,17 +3690,17 @@ dependencies = [
 "checksum cocoa 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4047fed6536f40cc2ae5e7834fb38e382c788270191c4cd69196f89686d076ce"
 "checksum color_quant 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a475fc4af42d83d28adf72968d9bcfaf035a1a9381642d8e85d8a04957767b0d"
 "checksum compiletest_rs 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "617b23d0ed4f57b3bcff6b5fe0a78f0010f1efb636298317665a960b6dbc0533"
 "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 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16ce16d9ed00181016c11ff48e561314bec92bfbce9fe48f319366618d4e5de6"
-"checksum cssparser 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7cf65dc20c985b085db316cf6e824fbccd4fa2c4641b57b8f42e06b0edb1052d"
+"checksum cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f3a5464ebae36626f28254b60d1abbba951417383192bcea65578b40fbec1a47"
 "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.18"
+cssparser = "0.19"
 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_api = {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.18"
+cssparser = "0.19"
 euclid = "0.15"
 heapsize = "0.4"
 heapsize_derive = "0.1"
 ipc-channel = "0.8"
 serde = "1.0"
 webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]}
--- a/servo/components/script/Cargo.toml
+++ b/servo/components/script/Cargo.toml
@@ -29,17 +29,17 @@ app_units = "0.5"
 audio-video-metadata = "0.1.2"
 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.18"
+cssparser = "0.19"
 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_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.18"
+cssparser = "0.19"
 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/script_layout_interface/reporter.rs
+++ b/servo/components/script_layout_interface/reporter.rs
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-use cssparser::{Parser, SourcePosition};
+use cssparser::SourceLocation;
 use ipc_channel::ipc::IpcSender;
 use log;
 use msg::constellation_msg::PipelineId;
 use script_traits::ConstellationControlMsg;
 use servo_url::ServoUrl;
 use std::sync::{Mutex, Arc};
 use style::error_reporting::{ParseErrorReporter, ContextualParseError};
 
@@ -17,28 +17,24 @@ pub struct CSSErrorReporter {
     // Arc+Mutex combo is necessary to make this struct Sync,
     // which is necessary to fulfill the bounds required by the
     // uses of the ParseErrorReporter trait.
     #[ignore_heap_size_of = "Arc is defined in libstd"]
     pub script_chan: Arc<Mutex<IpcSender<ConstellationControlMsg>>>,
 }
 
 impl ParseErrorReporter for CSSErrorReporter {
-    fn report_error<'a>(&self,
-                        input: &mut Parser,
-                        position: SourcePosition,
-                        error: ContextualParseError<'a>,
-                        url: &ServoUrl,
-                        line_number_offset: u64) {
-        let location = input.source_location(position);
-        let line_offset = location.line + line_number_offset as u32;
+    fn report_error(&self,
+                    url: &ServoUrl,
+                    location: SourceLocation,
+                    error: ContextualParseError) {
         if log_enabled!(log::LogLevel::Info) {
             info!("Url:\t{}\n{}:{} {}",
                   url.as_str(),
-                  line_offset,
+                  location.line,
                   location.column,
                   error.to_string())
         }
 
         //TODO: report a real filename
         let _ = self.script_chan.lock().unwrap().send(
             ConstellationControlMsg::ReportCSSError(self.pipelineid,
                                                     "".to_owned(),
--- a/servo/components/selectors/Cargo.toml
+++ b/servo/components/selectors/Cargo.toml
@@ -20,17 +20,17 @@ doctest = false
 
 [features]
 gecko_like_types = []
 unstable = []
 
 [dependencies]
 bitflags = "0.7"
 matches = "0.1"
-cssparser = "0.18"
+cssparser = "0.19"
 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
@@ -1045,34 +1045,34 @@ fn parse_selector<'i, 't, P, E, Impl>(
         if parsed_pseudo_element {
             break;
         }
 
         // Parse a combinator.
         let combinator;
         let mut any_whitespace = false;
         loop {
-            let position = input.position();
+            let before_this_token = input.state();
             match input.next_including_whitespace() {
                 Err(_e) => break 'outer_loop,
                 Ok(&Token::WhiteSpace(_)) => any_whitespace = true,
                 Ok(&Token::Delim('>')) => {
                     combinator = Combinator::Child;
                     break
                 }
                 Ok(&Token::Delim('+')) => {
                     combinator = Combinator::NextSibling;
                     break
                 }
                 Ok(&Token::Delim('~')) => {
                     combinator = Combinator::LaterSibling;
                     break
                 }
                 Ok(_) => {
-                    input.reset(position);
+                    input.reset(&before_this_token);
                     if any_whitespace {
                         combinator = Combinator::Descendant;
                         break
                     } else {
                         break 'outer_loop
                     }
                 }
             }
@@ -1202,64 +1202,64 @@ fn parse_qualified_name<'i, 't, P, E, Im
             Ok(&Token::Ident(ref local_name)) => {
                 Ok(Some((namespace, Some(local_name.clone()))))
             },
             Ok(t) => Err(ParseError::Basic(BasicParseError::UnexpectedToken(t.clone()))),
             Err(e) => Err(ParseError::Basic(e)),
         }
     };
 
-    let position = input.position();
+    let start = input.state();
     // FIXME: remove clone() when lifetimes are non-lexical
     match input.next_including_whitespace().map(|t| t.clone()) {
         Ok(Token::Ident(value)) => {
-            let position = input.position();
+            let after_ident = input.state();
             match input.next_including_whitespace() {
                 Ok(&Token::Delim('|')) => {
                     let prefix = value.as_ref().into();
                     let result = parser.namespace_for_prefix(&prefix);
                     let url = result.ok_or(ParseError::Custom(
                         SelectorParseError::ExpectedNamespace(value)))?;
                     explicit_namespace(input, QNamePrefix::ExplicitNamespace(prefix, url))
                 },
                 _ => {
-                    input.reset(position);
+                    input.reset(&after_ident);
                     if in_attr_selector {
                         Ok(Some((QNamePrefix::ImplicitNoNamespace, Some(value))))
                     } else {
                         default_namespace(Some(value))
                     }
                 }
             }
         },
         Ok(Token::Delim('*')) => {
-            let position = input.position();
+            let after_star = input.state();
             // FIXME: remove clone() when lifetimes are non-lexical
             match input.next_including_whitespace().map(|t| t.clone()) {
                 Ok(Token::Delim('|')) => {
                     explicit_namespace(input, QNamePrefix::ExplicitAnyNamespace)
                 }
                 result => {
-                    input.reset(position);
+                    input.reset(&after_star);
                     if in_attr_selector {
                         match result {
                             Ok(t) => Err(ParseError::Basic(BasicParseError::UnexpectedToken(t))),
                             Err(e) => Err(ParseError::Basic(e)),
                         }
                     } else {
                         default_namespace(None)
                     }
                 },
             }
         },
         Ok(Token::Delim('|')) => {
             explicit_namespace(input, QNamePrefix::ExplicitNoNamespace)
         }
         _ => {
-            input.reset(position);
+            input.reset(&start);
             Ok(None)
         }
     }
 }
 
 
 fn parse_attribute_selector<'i, 't, P, E, Impl>(parser: &P, input: &mut CssParser<'i, 't>)
                                                 -> Result<Component<Impl>,
@@ -1422,19 +1422,19 @@ fn parse_negation<'i, 't, P, E, Impl>(pa
                                                 ParseError<'i, SelectorParseError<'i, E>>>
     where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl
 {
     // We use a sequence because a type selector may be represented as two Components.
     let mut sequence = SmallVec::<[Component<Impl>; 2]>::new();
 
     // Consume any leading whitespace.
     loop {
-        let position = input.position();
+        let before_this_token = input.state();
         if !matches!(input.next_including_whitespace(), Ok(&Token::WhiteSpace(_))) {
-            input.reset(position);
+            input.reset(&before_this_token);
             break
         }
     }
 
     // Get exactly one simple selector. The parse logic in the caller will verify
     // that there are no trailing tokens after we're done.
     if !parse_type_selector(parser, input, &mut sequence)? {
         match parse_one_simple_selector(parser, input, /* inside_negation = */ true)? {
@@ -1465,19 +1465,19 @@ fn parse_compound_selector<'i, 't, P, E,
     parser: &P,
     input: &mut CssParser<'i, 't>,
     mut builder: &mut SelectorBuilder<Impl>)
     -> Result<bool, ParseError<'i, SelectorParseError<'i, E>>>
     where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl
 {
     // Consume any leading whitespace.
     loop {
-        let position = input.position();
+        let before_this_token = input.state();
         if !matches!(input.next_including_whitespace(), Ok(&Token::WhiteSpace(_))) {
-            input.reset(position);
+            input.reset(&before_this_token);
             break
         }
     }
     let mut empty = true;
     if !parse_type_selector(parser, input, builder)? {
         if let Some(url) = parser.default_namespace() {
             // If there was no explicit type selector, but there is a
             // default namespace, there is an implicit "<defaultns>|*" type
@@ -1599,17 +1599,17 @@ pub fn is_css2_pseudo_element<'i>(name: 
 /// * `Ok(Some(_))`: Parsed a simple selector or pseudo-element
 fn parse_one_simple_selector<'i, 't, P, E, Impl>(parser: &P,
                                                  input: &mut CssParser<'i, 't>,
                                                  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();
+    let start = input.state();
     // FIXME: remove clone() when lifetimes are non-lexical
     match input.next_including_whitespace().map(|t| t.clone()) {
         Ok(Token::IDHash(id)) => {
             let id = Component::ID(id.as_ref().into());
             Ok(Some(SimpleSelectorParseResult::SimpleSelector(id)))
         }
         Ok(Token::Delim('.')) => {
             match *input.next_including_whitespace()? {
@@ -1652,17 +1652,17 @@ fn parse_one_simple_selector<'i, 't, P, 
                     })?
                 } else {
                     parse_simple_pseudo_class(parser, name)?
                 };
                 Ok(Some(SimpleSelectorParseResult::SimpleSelector(pseudo_class)))
             }
         }
         _ => {
-            input.reset(start_position);
+            input.reset(&start);
             Ok(None)
         }
     }
 }
 
 fn parse_simple_pseudo_class<'i, P, E, Impl>(parser: &P, name: CowRcStr<'i>)
                                              -> Result<Component<Impl>,
                                                        ParseError<'i, SelectorParseError<'i, E>>>
--- a/servo/components/style/Cargo.toml
+++ b/servo/components/style/Cargo.toml
@@ -32,17 +32,17 @@ gecko_debug = ["nsstring_vendor/gecko_de
 app_units = "0.5.2"
 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.18"
+cssparser = "0.19"
 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}
 itertools = "0.5"
 itoa = "0.3"
 html5ever = {version = "0.18", optional = true}
--- a/servo/components/style/counter_style/mod.rs
+++ b/servo/components/style/counter_style/mod.rs
@@ -7,17 +7,17 @@
 //! [counter-style]: https://drafts.csswg.org/css-counter-styles/
 
 use Atom;
 use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser};
 use cssparser::{Parser, Token, serialize_identifier, BasicParseError, CowRcStr};
 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 parser::{ParserContext, Parse};
 use selectors::parser::SelectorParseError;
 use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
 use std::ascii::AsciiExt;
 use std::borrow::Cow;
 use std::fmt;
 use std::ops::Range;
 use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseError, ToCss};
 use values::CustomIdent;
@@ -47,30 +47,28 @@ pub fn parse_counter_style_name<'i, 't>(
         }
     }
     include!("predefined.rs")
 }
 
 /// Parse the body (inside `{}`) of an @counter-style rule
 pub fn parse_counter_style_body<'i, 't>(name: CustomIdent, context: &ParserContext, input: &mut Parser<'i, 't>)
                                         -> Result<CounterStyleRuleData, ParseError<'i>> {
-    let start = input.position();
+    let start = input.current_source_location();
     let mut rule = CounterStyleRuleData::empty(name);
     {
         let parser = CounterStyleRuleParser {
             context: context,
             rule: &mut rule,
         };
         let mut iter = DeclarationListParser::new(input, parser);
         while let Some(declaration) = iter.next() {
             if let Err(err) = declaration {
-                let pos = err.span.start;
-                let error = ContextualParseError::UnsupportedCounterStyleDescriptorDeclaration(
-                    iter.input.slice(err.span), err.error);
-                log_css_error(iter.input, pos, error, context);
+                let error = ContextualParseError::UnsupportedCounterStyleDescriptorDeclaration(err.slice, err.error);
+                context.log_css_error(err.location, error)
             }
         }
     }
     let error = match *rule.system() {
         ref system @ System::Cyclic |
         ref system @ System::Fixed { .. } |
         ref system @ System::Symbolic |
         ref system @ System::Alphabetic |
@@ -92,17 +90,17 @@ pub fn parse_counter_style_body<'i, 't>(
             Some(ContextualParseError::InvalidCounterStyleExtendsWithSymbols)
         }
         System::Extends(_) if rule.additive_symbols.is_some() => {
             Some(ContextualParseError::InvalidCounterStyleExtendsWithAdditiveSymbols)
         }
         _ => None
     };
     if let Some(error) = error {
-        log_css_error(input, start, error, context);
+        context.log_css_error(start, error);
         Err(StyleParseError::UnspecifiedError.into())
     } else {
         Ok(rule)
     }
 }
 
 struct CounterStyleRuleParser<'a, 'b: 'a> {
     context: &'a ParserContext<'b>,
--- a/servo/components/style/custom_properties.rs
+++ b/servo/components/style/custom_properties.rs
@@ -290,19 +290,19 @@ fn parse_self_contained_declaration_valu
 /// https://drafts.csswg.org/css-syntax-3/#typedef-declaration-value
 fn parse_declaration_value<'i, 't>
                           (input: &mut Parser<'i, 't>,
                            references: &mut Option<HashSet<Name>>,
                            missing_closing_characters: &mut String)
                           -> Result<(TokenSerializationType, TokenSerializationType), ParseError<'i>> {
     input.parse_until_before(Delimiter::Bang | Delimiter::Semicolon, |input| {
         // Need at least one token
-        let start_position = input.position();
+        let start = input.state();
         input.next_including_whitespace()?;
-        input.reset(start_position);
+        input.reset(&start);
 
         parse_declaration_value_block(input, references, missing_closing_characters)
     })
 }
 
 /// Like parse_declaration_value, but accept `!` and `;` since they are only
 /// invalid at the top level
 fn parse_declaration_value_block<'i, 't>
@@ -349,21 +349,21 @@ fn parse_declaration_value_block<'i, 't>
             Token::CloseParenthesis =>
                 return Err(StyleParseError::UnbalancedCloseParenthesisInDeclarationValueBlock.into()),
             Token::CloseSquareBracket =>
                 return Err(StyleParseError::UnbalancedCloseSquareBracketInDeclarationValueBlock.into()),
             Token::CloseCurlyBracket =>
                 return Err(StyleParseError::UnbalancedCloseCurlyBracketInDeclarationValueBlock.into()),
             Token::Function(ref name) => {
                 if name.eq_ignore_ascii_case("var") {
-                    let position = input.position();
+                    let args_start = input.state();
                     input.parse_nested_block(|input| {
                         parse_var_function(input, references)
                     })?;
-                    input.reset(position);
+                    input.reset(&args_start);
                 }
                 nested!();
                 check_closed!(")");
                 Token::CloseParenthesis.serialization_type()
             }
             Token::ParenthesisBlock => {
                 nested!();
                 check_closed!(")");
@@ -689,23 +689,23 @@ fn substitute_block<'i, 't, F>(input: &m
                     if let Ok(last) = substitute_one(&name, partial_computed_value) {
                         last_token_type = last;
                         // Skip over the fallback, as `parse_nested_block` would return `Err`
                         // if we don’t consume all of `input`.
                         // FIXME: Add a specialized method to cssparser to do this with less work.
                         while let Ok(_) = input.next() {}
                     } else {
                         input.expect_comma()?;
-                        let position = input.position();
+                        let after_comma = input.state();
                         let first_token_type = input.next_including_whitespace_and_comments()
                             // parse_var_function() ensures that .unwrap() will not fail.
                             .unwrap()
                             .serialization_type();
-                        input.reset(position);
-                        let mut position = (position, first_token_type);
+                        input.reset(&after_comma);
+                        let mut position = (after_comma.position(), first_token_type);
                         last_token_type = substitute_block(
                             input, &mut position, partial_computed_value, substitute_one)?;
                         partial_computed_value.push_from(position, input, last_token_type);
                     }
                     Ok(())
                 })?;
                 set_position_at_next_iteration = true
             }
--- 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};
+use cssparser::{BasicParseError, Token, SourceLocation};
 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.
@@ -147,54 +147,46 @@ impl<'a> ContextualParseError<'a> {
         }
     }
 }
 
 /// A generic trait for an error reporter.
 pub trait ParseErrorReporter {
     /// Called when the style engine detects an error.
     ///
-    /// Returns the current input being parsed, the source position it was
+    /// Returns the current input being parsed, the source location it was
     /// reported from, and a message.
-    fn report_error<'a>(&self,
-                        input: &mut Parser,
-                        position: SourcePosition,
-                        error: ContextualParseError<'a>,
-                        url: &UrlExtraData,
-                        line_number_offset: u64);
+    fn report_error(&self,
+                    url: &UrlExtraData,
+                    location: SourceLocation,
+                    error: ContextualParseError);
 }
 
 /// An error reporter that uses [the `log` crate](https://github.com/rust-lang-nursery/log)
 /// at `info` level.
 ///
 /// This logging is silent by default, and can be enabled with a `RUST_LOG=style=info`
 /// environment variable.
 /// (See [`env_logger`](https://rust-lang-nursery.github.io/log/env_logger/).)
 pub struct RustLogReporter;
 
 impl ParseErrorReporter for RustLogReporter {
-    fn report_error<'a>(&self,
-                        input: &mut Parser,
-                        position: SourcePosition,
-                        error: ContextualParseError<'a>,
-                        url: &UrlExtraData,
-                        line_number_offset: u64) {
+    fn report_error(&self,
+                    url: &UrlExtraData,
+                    location: SourceLocation,
+                    error: ContextualParseError) {
         if log_enabled!(log::LogLevel::Info) {
-            let location = input.source_location(position);
-            let line_offset = location.line + line_number_offset as u32;
-            info!("Url:\t{}\n{}:{} {}", url.as_str(), line_offset, location.column, error.to_string())
+            info!("Url:\t{}\n{}:{} {}", url.as_str(), location.line, location.column, error.to_string())
         }
     }
 }
 
 /// Error reporter which silently forgets errors
 pub struct NullReporter;
 
 impl ParseErrorReporter for NullReporter {
-    fn report_error<'a>(&self,
-            _: &mut Parser,
-            _: SourcePosition,
-            _: ContextualParseError<'a>,
-            _: &UrlExtraData,
-            _: u64) {
+    fn report_error(&self,
+                    _url: &UrlExtraData,
+                    _location: SourceLocation,
+                    _error: ContextualParseError) {
         // do nothing
     }
 }
--- a/servo/components/style/font_face.rs
+++ b/servo/components/style/font_face.rs
@@ -11,17 +11,17 @@
 #[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, CowRcStr};
 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 parser::{ParserContext, Parse};
 #[cfg(feature = "gecko")]
 use properties::longhands::font_language_override;
 use selectors::parser::SelectorParseError;
 use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
 use std::fmt;
 use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseError, ToCss};
 use values::specified::url::SpecifiedUrl;
 
@@ -114,20 +114,18 @@ pub fn parse_font_face_block(context: &P
     {
         let parser = FontFaceRuleParser {
             context: context,
             rule: &mut rule,
         };
         let mut iter = DeclarationListParser::new(input, parser);
         while let Some(declaration) = iter.next() {
             if let Err(err) = declaration {
-                let pos = err.span.start;
-                let error = ContextualParseError::UnsupportedFontFaceDescriptor(
-                    iter.input.slice(err.span), err.error);
-                log_css_error(iter.input, pos, error, context);
+                let error = ContextualParseError::UnsupportedFontFaceDescriptor(err.slice, err.error);
+                context.log_css_error(err.location, error)
             }
         }
     }
     rule
 }
 
 /// A @font-face rule that is known to have font-family and src declarations.
 #[cfg(feature = "servo")]
--- a/servo/components/style/parser.rs
+++ b/servo/components/style/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/. */
 
 //! The context within which CSS code is parsed.
 
 use context::QuirksMode;
-use cssparser::{Parser, SourcePosition, UnicodeRange};
+use cssparser::{Parser, SourceLocation, UnicodeRange};
 use error_reporting::{ParseErrorReporter, ContextualParseError};
 use style_traits::{OneOrMoreSeparated, ParseError, ParsingMode, Separator};
 #[cfg(feature = "gecko")]
 use style_traits::{PARSING_MODE_DEFAULT, PARSING_MODE_ALLOW_UNITLESS_LENGTH, PARSING_MODE_ALLOW_ALL_NUMERIC_VALUES};
 use stylesheets::{CssRuleType, Origin, UrlExtraData, Namespaces};
 
 /// Asserts that all ParsingMode flags have a matching ParsingMode value in gecko.
 #[cfg(feature = "gecko")]
@@ -128,30 +128,25 @@ impl<'a> ParserContext<'a> {
             namespaces: None,
         }
     }
 
     /// Get the rule type, which assumes that one is available.
     pub fn rule_type(&self) -> CssRuleType {
         self.rule_type.expect("Rule type expected, but none was found.")
     }
-}
 
-/// Defaults to a no-op.
-/// Set a `RUST_LOG=style::errors` environment variable
-/// to log CSS parse errors to stderr.
-pub fn log_css_error<'a>(input: &mut Parser,
-                         position: SourcePosition,
-                         error: ContextualParseError<'a>,
-                         parsercontext: &ParserContext) {
-    let url_data = parsercontext.url_data;
-    let line_number_offset = parsercontext.line_number_offset;
-    parsercontext.error_reporter.report_error(input, position,
-                                              error, url_data,
-                                              line_number_offset);
+    /// Record a CSS parse error with this context’s error reporting.
+    pub fn log_css_error(&self, location: SourceLocation, error: ContextualParseError) {
+        let location = SourceLocation {
+            line: location.line + self.line_number_offset as u32,
+            column: location.column,
+        };
+        self.error_reporter.report_error(self.url_data, location, error)
+    }
 }
 
 // XXXManishearth Replace all specified value parse impls with impls of this
 // trait. This will make it easy to write more generic values in the future.
 /// A trait to abstract parsing of a specified value given a `ParserContext` and
 /// CSS input.
 pub trait Parse : Sized {
     /// Parse a value of this type.
--- a/servo/components/style/properties/declaration_block.rs
+++ b/servo/components/style/properties/declaration_block.rs
@@ -5,17 +5,17 @@
 //! A property declaration block.
 
 #![deny(missing_docs)]
 
 use context::QuirksMode;
 use cssparser::{DeclarationListParser, parse_important, ParserInput, CowRcStr};
 use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter, ParseError as CssParseError};
 use error_reporting::{ParseErrorReporter, ContextualParseError};
-use parser::{ParserContext, log_css_error};
+use parser::ParserContext;
 use properties::animated_properties::AnimationValue;
 use selectors::parser::SelectorParseError;
 use shared_lock::Locked;
 use smallvec::SmallVec;
 use std::fmt;
 use std::slice::Iter;
 use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError, ParsingMode, StyleParseError};
 use stylesheets::{CssRuleType, Origin, UrlExtraData};
@@ -904,25 +904,25 @@ pub fn parse_one_declaration_into(declar
     let context = ParserContext::new(Origin::Author,
                                      url_data,
                                      error_reporter,
                                      Some(CssRuleType::Style),
                                      parsing_mode,
                                      quirks_mode);
     let mut input = ParserInput::new(input);
     let mut parser = Parser::new(&mut input);
-    let start = parser.position();
+    let start_position = parser.position();
+    let start_location = parser.current_source_location();
     parser.parse_entirely(|parser| {
         PropertyDeclaration::parse_into(declarations, id, &context, parser)
             .map_err(|e| e.into())
     }).map_err(|err| {
-        let end = parser.position();
         let error = ContextualParseError::UnsupportedPropertyDeclaration(
-            parser.slice(start..end), err);
-        log_css_error(&mut parser, start, error, &context);
+            parser.slice_from(start_position), err);
+        context.log_css_error(start_location, error);
     })
 }
 
 /// A struct to parse property declarations.
 struct PropertyDeclarationParser<'a, 'b: 'a> {
     context: &'a ParserContext<'b>,
     declarations: &'a mut SourcePropertyDeclaration,
 }
@@ -995,17 +995,15 @@ pub fn parse_property_declaration_list(c
                 // If the unrecognized property looks like a vendor-specific property,
                 // silently ignore it instead of polluting the error output.
                 if let CssParseError::Custom(SelectorParseError::Custom(
                     StyleParseError::PropertyDeclaration(
                         PropertyDeclarationParseError::UnknownVendorProperty))) = err.error {
                     continue;
                 }
 
-                let pos = err.span.start;
-                let error = ContextualParseError::UnsupportedPropertyDeclaration(
-                    iter.input.slice(err.span), err.error);
-                log_css_error(iter.input, pos, error, &context);
+                let error = ContextualParseError::UnsupportedPropertyDeclaration(err.slice, err.error);
+                context.log_css_error(err.location, error);
             }
         }
     }
     block
 }
--- a/servo/components/style/properties/properties.mako.rs
+++ b/servo/components/style/properties/properties.mako.rs
@@ -1497,22 +1497,22 @@ impl PropertyDeclaration {
                 declarations.push(PropertyDeclaration::Custom(name, value));
                 Ok(())
             }
             PropertyId::Longhand(id) => {
                 input.try(|i| CSSWideKeyword::parse(i)).map(|keyword| {
                     PropertyDeclaration::CSSWideKeyword(id, keyword)
                 }).or_else(|()| {
                     input.look_for_var_functions();
-                    let start = input.position();
+                    let start = input.state();
                     input.parse_entirely(|input| id.parse_value(context, input))
                     .or_else(|err| {
                         while let Ok(_) = input.next() {}  // Look for var() after the error.
                         if input.seen_var_functions() {
-                            input.reset(start);
+                            input.reset(&start);
                             let (first_token_type, css) =
                                 ::custom_properties::parse_non_custom_with_var(input).map_err(|e| {
                                     PropertyDeclarationParseError::InvalidValue(id.name().into(),
                                         ValueParseError::from_parse_error(e))
                                 })?;
                             Ok(PropertyDeclaration::WithVariables(id, Arc::new(UnparsedValue {
                                 css: css.into_owned(),
                                 first_token_type: first_token_type,
@@ -1535,23 +1535,23 @@ impl PropertyDeclaration {
                     } else {
                         for &longhand in id.longhands() {
                             declarations.push(PropertyDeclaration::CSSWideKeyword(longhand, keyword))
                         }
                     }
                     Ok(())
                 } else {
                     input.look_for_var_functions();
-                    let start = input.position();
+                    let start = input.state();
                     // Not using parse_entirely here: each ${shorthand.ident}::parse_into function
                     // needs to do so *before* pushing to `declarations`.
                     id.parse_into(declarations, context, input).or_else(|err| {
                         while let Ok(_) = input.next() {}  // Look for var() after the error.
                         if input.seen_var_functions() {
-                            input.reset(start);
+                            input.reset(&start);
                             let (first_token_type, css) =
                                 ::custom_properties::parse_non_custom_with_var(input).map_err(|e| {
                                     PropertyDeclarationParseError::InvalidValue(id.name().into(),
                                         ValueParseError::from_parse_error(e))
                                 })?;
                             let unparsed = Arc::new(UnparsedValue {
                                 css: css.into_owned(),
                                 first_token_type: first_token_type,
--- a/servo/components/style/stylesheets/font_feature_values_rule.rs
+++ b/servo/components/style/stylesheets/font_feature_values_rule.rs
@@ -6,17 +6,17 @@
 //!
 //! [font-feature-values]: https://drafts.csswg.org/css-fonts-3/#at-font-feature-values-rule
 
 use Atom;
 use computed_values::font_family::FamilyName;
 use cssparser::{AtRuleParser, AtRuleType, BasicParseError, DeclarationListParser, DeclarationParser, Parser};
 use cssparser::{CowRcStr, RuleListParser, SourceLocation, QualifiedRuleParser, Token, serialize_identifier};
 use error_reporting::ContextualParseError;
-use parser::{ParserContext, log_css_error, Parse};
+use parser::{ParserContext, Parse};
 use selectors::parser::SelectorParseError;
 use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
 use std::fmt;
 use style_traits::{ParseError, StyleParseError, ToCss};
 use stylesheets::CssRuleType;
 
 /// A @font-feature-values block declaration.
 /// It is `<ident>: <integer>+`.
@@ -217,20 +217,18 @@ macro_rules! font_feature_values_blocks 
 
                 {
                     let mut iter = RuleListParser::new_for_nested_rule(input, FontFeatureValuesRuleParser {
                         context: context,
                         rule: &mut rule,
                     });
                     while let Some(result) = iter.next() {
                         if let Err(err) = result {
-                            let pos = err.span.start;
-                            let error = ContextualParseError::UnsupportedRule(
-                                iter.input.slice(err.span), err.error);
-                            log_css_error(iter.input, pos, error, context);
+                            let error = ContextualParseError::UnsupportedRule(err.slice, err.error);
+                            context.log_css_error(err.location, error);
                         }
                     }
                 }
                 rule
             }
 
             /// Prints font family names.
             pub fn font_family_to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
@@ -333,20 +331,19 @@ macro_rules! font_feature_values_blocks 
                             let parser = FFVDeclarationsParser {
                                 context: &context,
                                 declarations: &mut self.rule.$ident,
                             };
 
                             let mut iter = DeclarationListParser::new(input, parser);
                             while let Some(declaration) = iter.next() {
                                 if let Err(err) = declaration {
-                                    let pos = err.span.start;
                                     let error = ContextualParseError::UnsupportedKeyframePropertyDeclaration(
-                                        iter.input.slice(err.span), err.error);
-                                    log_css_error(iter.input, pos, error, &context);
+                                        err.slice, err.error);
+                                    context.log_css_error(err.location, error);
                                 }
                             }
                         },
                     )*
                 }
 
                 Ok(())
             }
--- a/servo/components/style/stylesheets/keyframes_rule.rs
+++ b/servo/components/style/stylesheets/keyframes_rule.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/. */
 
 //! Keyframes: https://drafts.csswg.org/css-animations/#keyframes
 
 use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, RuleListParser, ParserInput, CowRcStr};
 use cssparser::{DeclarationListParser, DeclarationParser, parse_one_rule, SourceLocation};
 use error_reporting::{NullReporter, ContextualParseError};
-use parser::{ParserContext, log_css_error};
+use parser::ParserContext;
 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 servo_arc::Arc;
 use shared_lock::{DeepCloneParams, DeepCloneWithLock, SharedRwLock, SharedRwLockReadGuard, Locked, ToCssWithGuard};
@@ -468,22 +468,23 @@ impl<'a, 'i> AtRuleParser<'i> for Keyfra
 }
 
 impl<'a, 'i> QualifiedRuleParser<'i> for KeyframeListParser<'a> {
     type Prelude = KeyframeSelector;
     type QualifiedRule = Arc<Locked<Keyframe>>;
     type Error = SelectorParseError<'i, StyleParseError<'i>>;
 
     fn parse_prelude<'t>(&mut self, input: &mut Parser<'i, 't>) -> Result<Self::Prelude, ParseError<'i>> {
-        let start = input.position();
+        let start_position = input.position();
+        let start_location = input.current_source_location();
         match KeyframeSelector::parse(input) {
             Ok(sel) => Ok(sel),
             Err(e) => {
-                let error = ContextualParseError::InvalidKeyframeRule(input.slice_from(start), e.clone());
-                log_css_error(input, start, error, self.context);
+                let error = ContextualParseError::InvalidKeyframeRule(input.slice_from(start_position), e.clone());
+                self.context.log_css_error(start_location, error);
                 Err(e)
             }
         }
     }
 
     fn parse_block<'t>(&mut self, prelude: Self::Prelude, input: &mut Parser<'i, 't>)
                        -> Result<Self::QualifiedRule, ParseError<'i>> {
         let context = ParserContext::new_with_rule_type(self.context, Some(CssRuleType::Keyframe));
@@ -495,20 +496,18 @@ impl<'a, 'i> QualifiedRuleParser<'i> for
         let mut block = PropertyDeclarationBlock::new();
         while let Some(declaration) = iter.next() {
             match declaration {
                 Ok(()) => {
                     block.extend(iter.parser.declarations.drain(), Importance::Normal);
                 }
                 Err(err) => {
                     iter.parser.declarations.clear();
-                    let pos = err.span.start;
-                    let error = ContextualParseError::UnsupportedKeyframePropertyDeclaration(
-                        iter.input.slice(err.span), err.error);
-                    log_css_error(iter.input, pos, error, &context);
+                    let error = ContextualParseError::UnsupportedKeyframePropertyDeclaration(err.slice, err.error);
+                    context.log_css_error(err.location, error);
                 }
             }
             // `parse_important` is not called here, `!important` is not allowed in keyframe blocks.
         }
         Ok(Arc::new(self.shared_lock.wrap(Keyframe {
             selector: prelude,
             block: Arc::new(self.shared_lock.wrap(block)),
         })))
--- a/servo/components/style/stylesheets/rule_parser.rs
+++ b/servo/components/style/stylesheets/rule_parser.rs
@@ -7,17 +7,17 @@
 use {Namespace, Prefix};
 use computed_values::font_family::FamilyName;
 use counter_style::{parse_counter_style_body, parse_counter_style_name};
 use cssparser::{AtRuleParser, AtRuleType, Parser, QualifiedRuleParser, RuleListParser};
 use cssparser::{CowRcStr, SourceLocation, BasicParseError};
 use error_reporting::ContextualParseError;
 use font_face::parse_font_face_block;
 use media_queries::{parse_media_query_list, MediaList};
-use parser::{Parse, ParserContext, log_css_error};
+use parser::{Parse, ParserContext};
 use properties::parse_property_declaration_list;
 use selector_parser::{SelectorImpl, SelectorParser};
 use selectors::SelectorList;
 use selectors::parser::SelectorParseError;
 use servo_arc::Arc;
 use shared_lock::{Locked, SharedRwLock};
 use str::starts_with_ignore_ascii_case;
 use style_traits::{StyleParseError, ParseError};
@@ -313,20 +313,18 @@ impl<'a, 'b> NestedRuleParser<'a, 'b> {
         };
 
         let mut iter = RuleListParser::new_for_nested_rule(input, nested_parser);
         let mut rules = Vec::new();
         while let Some(result) = iter.next() {
             match result {
                 Ok(rule) => rules.push(rule),
                 Err(err) => {
-                    let pos = err.span.start;
-                    let error = ContextualParseError::UnsupportedRule(
-                        iter.input.slice(err.span), err.error);
-                    log_css_error(iter.input, pos, error, self.context);
+                    let error = ContextualParseError::UnsupportedRule(err.slice, err.error);
+                    self.context.log_css_error(err.location, error);
                 }
             }
         }
         CssRules::new(rules, self.shared_lock)
     }
 }
 
 impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
--- a/servo/components/style/stylesheets/stylesheet.rs
+++ b/servo/components/style/stylesheets/stylesheet.rs
@@ -4,17 +4,17 @@
 
 use {Prefix, Namespace};
 use context::QuirksMode;
 use cssparser::{Parser, RuleListParser, ParserInput};
 use error_reporting::{ParseErrorReporter, ContextualParseError};
 use fnv::FnvHashMap;
 use media_queries::{MediaList, Device};
 use parking_lot::RwLock;
-use parser::{ParserContext, log_css_error};
+use parser::ParserContext;
 use servo_arc::Arc;
 use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard};
 use std::mem;
 use std::sync::atomic::{AtomicBool, Ordering};
 use style_traits::PARSING_MODE_DEFAULT;
 use stylesheets::{CssRule, CssRules, Origin, UrlExtraData};
 use stylesheets::loader::StylesheetLoader;
 use stylesheets::memory::{MallocSizeOfFn, MallocSizeOfWithGuard};
@@ -346,20 +346,18 @@ impl Stylesheet {
         {
             let mut iter =
                 RuleListParser::new_for_stylesheet(&mut input, rule_parser);
 
             while let Some(result) = iter.next() {
                 match result {
                     Ok(rule) => rules.push(rule),
                     Err(err) => {
-                        let pos = err.span.start;
-                        let error = ContextualParseError::InvalidRule(
-                            iter.input.slice(err.span), err.error);
-                        log_css_error(iter.input, pos, error, iter.parser.context());
+                        let error = ContextualParseError::InvalidRule(err.slice, err.error);
+                        iter.parser.context().log_css_error(err.location, error);
                     }
                 }
             }
         }
 
         (rules, input.seen_viewport_percentages())
     }
 
--- a/servo/components/style/stylesheets/viewport_rule.rs
+++ b/servo/components/style/stylesheets/viewport_rule.rs
@@ -10,17 +10,17 @@
 use app_units::Au;
 use context::QuirksMode;
 use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser, parse_important};
 use cssparser::{CowRcStr, 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 parser::{Parse, ParserContext};
 use properties::StyleBuilder;
 use selectors::parser::SelectorParseError;
 use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
 use std::ascii::AsciiExt;
 use std::borrow::Cow;
 use std::fmt;
 use std::iter::Enumerate;
 use std::str::Chars;
@@ -355,20 +355,18 @@ impl Parse for ViewportRule {
         while let Some(result) = parser.next() {
             match result {
                 Ok(declarations) => {
                     for declarations in declarations {
                         cascade.add(Cow::Owned(declarations))
                     }
                 }
                 Err(err) => {
-                    let pos = err.span.start;
-                    let error = ContextualParseError::UnsupportedViewportDescriptorDeclaration(
-                        parser.input.slice(err.span), err.error);
-                    log_css_error(parser.input, pos, error, &context);
+                    let error = ContextualParseError::UnsupportedViewportDescriptorDeclaration(err.slice, err.error);
+                    context.log_css_error(err.location, error);
                 }
             }
         }
         Ok(ViewportRule { declarations: cascade.finish() })
     }
 }
 
 impl ViewportRule {
--- a/servo/components/style/values/specified/calc.rs
+++ b/servo/components/style/values/specified/calc.rs
@@ -189,17 +189,17 @@ impl CalcNode {
         context: &ParserContext,
         input: &mut Parser<'i, 't>,
         expected_unit: CalcUnit)
         -> Result<Self, ParseError<'i>>
     {
         let mut root = Self::parse_product(context, input, expected_unit)?;
 
         loop {
-            let position = input.position();
+            let start = input.state();
             match input.next_including_whitespace() {
                 Ok(&Token::WhiteSpace(_)) => {
                     if input.is_exhausted() {
                         break; // allow trailing whitespace
                     }
                     // FIXME: remove clone() when lifetimes are non-lexical
                     match input.next()?.clone() {
                         Token::Delim('+') => {
@@ -215,17 +215,17 @@ impl CalcNode {
                             let new_root =
                                 CalcNode::Sub(Box::new(root), Box::new(rhs));
                             root = new_root;
                         }
                         t => return Err(BasicParseError::UnexpectedToken(t).into()),
                     }
                 }
                 _ => {
-                    input.reset(position);
+                    input.reset(&start);
                     break
                 }
             }
         }
 
         Ok(root)
     }
 
@@ -242,31 +242,31 @@ impl CalcNode {
         context: &ParserContext,
         input: &mut Parser<'i, 't>,
         expected_unit: CalcUnit)
         -> Result<Self, ParseError<'i>>
     {
         let mut root = Self::parse_one(context, input, expected_unit)?;
 
         loop {
-            let position = input.position();
+            let start = input.state();
             match input.next() {
                 Ok(&Token::Delim('*')) => {
                     let rhs = Self::parse_one(context, input, expected_unit)?;
                     let new_root = CalcNode::Mul(Box::new(root), Box::new(rhs));
                     root = new_root;
                 }
                 // TODO(emilio): Figure out why the `Integer` check.
                 Ok(&Token::Delim('/')) if expected_unit != CalcUnit::Integer => {
                     let rhs = Self::parse_one(context, input, expected_unit)?;
                     let new_root = CalcNode::Div(Box::new(root), Box::new(rhs));
                     root = new_root;
                 }
                 _ => {
-                    input.reset(position);
+                    input.reset(&start);
                     break
                 }
             }
         }
 
         Ok(root)
     }
 
--- a/servo/components/style/values/specified/color.rs
+++ b/servo/components/style/values/specified/color.rs
@@ -65,22 +65,22 @@ impl From<RGBA> for Color {
     }
 }
 
 impl Parse for Color {
     fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
         // Currently we only store authored value for color keywords,
         // because all browsers serialize those values as keywords for
         // specified value.
-        let start_position = input.position();
+        let start = input.state();
         let authored = match input.next() {
             Ok(&Token::Ident(ref s)) => Some(s.to_lowercase().into_boxed_str()),
             _ => None,
         };
-        input.reset(start_position);
+        input.reset(&start);
         match input.try(CSSParserColor::parse) {
             Ok(value) =>
                 Ok(match value {
                     CSSParserColor::CurrentColor => Color::CurrentColor,
                     CSSParserColor::RGBA(rgba) => Color::Numeric {
                         parsed: rgba,
                         authored: authored,
                     },
--- a/servo/components/style_traits/Cargo.toml
+++ b/servo/components/style_traits/Cargo.toml
@@ -11,16 +11,16 @@ path = "lib.rs"
 
 [features]
 servo = ["heapsize", "heapsize_derive", "serde", "servo_atoms", "cssparser/heapsize", "cssparser/serde", "webrender_api"]
 gecko = []
 
 [dependencies]
 app_units = "0.5"
 bitflags = "0.7"
-cssparser = "0.18"
+cssparser = "0.19"
 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}
 webrender_api = {git = "https://github.com/servo/webrender", optional = true}
 servo_atoms = {path = "../atoms", optional = true}
--- a/servo/ports/geckolib/Cargo.toml
+++ b/servo/ports/geckolib/Cargo.toml
@@ -10,17 +10,17 @@ path = "lib.rs"
 crate-type = ["staticlib", "rlib"]
 
 [features]
 bindgen = ["style/use_bindgen"]
 gecko_debug = ["style/gecko_debug"]
 
 [dependencies]
 atomic_refcell = "0.1"
-cssparser = "0.18"
+cssparser = "0.19"
 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.4"
 selectors = {path = "../../components/selectors"}
 servo_arc = {path = "../../components/servo_arc"}
 style = {path = "../../components/style", features = ["gecko"]}
--- a/servo/ports/geckolib/error_reporter.rs
+++ b/servo/ports/geckolib/error_reporter.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/. */
 
 //! Wrapper around Gecko's CSS error reporting mechanism.
 
 #![allow(unsafe_code)]
 
-use cssparser::{Parser, SourcePosition, ParseError as CssParseError, Token, BasicParseError};
+use cssparser::{SourceLocation, ParseError as CssParseError, Token, BasicParseError};
 use cssparser::CowRcStr;
 use selectors::parser::SelectorParseError;
 use std::ptr;
 use style::error_reporting::{ParseErrorReporter, ContextualParseError};
 use style::gecko_bindings::bindings::{Gecko_CreateCSSErrorReporter, Gecko_DestroyCSSErrorReporter};
 use style::gecko_bindings::bindings::Gecko_ReportUnexpectedCSSError;
 use style::gecko_bindings::structs::{Loader, ServoStyleSheet, nsIURI};
 use style::gecko_bindings::structs::ErrorReporter as GeckoErrorReporter;
@@ -325,25 +325,20 @@ impl<'a> ErrorHelpers<'a> for Contextual
             ContextualParseError::InvalidFontFeatureValuesRule(..) =>
                 (b"PEUnknownAtRule\0", Action::Skip),
         };
         (None, msg, action)
     }
 }
 
 impl ParseErrorReporter for ErrorReporter {
-    fn report_error<'a>(&self,
-                        input: &mut Parser,
-                        position: SourcePosition,
-                        error: ContextualParseError<'a>,
-                        _url: &UrlExtraData,
-                        line_number_offset: u64) {
-        let location = input.source_location(position);
-        let line_number = location.line + line_number_offset as u32;
-
+    fn report_error(&self,
+                    _url: &UrlExtraData,
+                    location: SourceLocation,
+                    error: ContextualParseError) {
         let (pre, name, action) = error.to_gecko_message();
         let suffix = match action {
             Action::Nothing => ptr::null(),
             Action::Skip => b"PEDeclSkipped\0".as_ptr(),
             Action::Drop => b"PEDeclDropped\0".as_ptr(),
         };
         let (param, pre_param) = error.error_params();
         let param = param.into_str();
@@ -357,13 +352,13 @@ impl ParseErrorReporter for ErrorReporte
                                            param.as_ptr() as *const _,
                                            param.len() as u32,
                                            pre.map_or(ptr::null(), |p| p.as_ptr()) as *const _,
                                            pre_param_ptr as *const _,
                                            pre_param.as_ref().map_or(0, |p| p.len()) as u32,
                                            suffix as *const _,
                                            source.as_ptr() as *const _,
                                            source.len() as u32,
-                                           line_number as u32,
-                                           location.column as u32);
+                                           location.line,
+                                           location.column);
         }
     }
 }
--- 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.18"
+cssparser = "0.19"
 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
@@ -7,17 +7,17 @@ license = "MPL-2.0"
 [lib]
 name = "style_tests"
 path = "lib.rs"
 doctest = false
 
 [dependencies]
 byteorder = "1.0"
 app_units = "0.5"
-cssparser = "0.18"
+cssparser = "0.19"
 euclid = "0.15"
 html5ever = "0.18"
 parking_lot = "0.4"
 rayon = "0.8"
 rustc-serialize = "0.3"
 selectors = {path = "../../../components/selectors"}
 servo_arc = {path = "../../../components/servo_arc"}
 servo_atoms = {path = "../../../components/atoms"}
--- a/servo/tests/unit/style/media_queries.rs
+++ b/servo/tests/unit/style/media_queries.rs
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-use cssparser::{Parser, SourcePosition};
+use cssparser::SourceLocation;
 use euclid::ScaleFactor;
 use euclid::TypedSize2D;
 use servo_arc::Arc;
 use servo_url::ServoUrl;
 use std::borrow::ToOwned;
 use style::Atom;
 use style::context::QuirksMode;
 use style::error_reporting::{ParseErrorReporter, ContextualParseError};
@@ -16,22 +16,20 @@ use style::servo::media_queries::*;
 use style::shared_lock::SharedRwLock;
 use style::stylesheets::{AllRules, Stylesheet, StylesheetInDocument, Origin, CssRule};
 use style::values::specified;
 use style_traits::ToCss;
 
 pub struct CSSErrorReporterTest;
 
 impl ParseErrorReporter for CSSErrorReporterTest {
-    fn report_error<'a>(&self,
-                        _input: &mut Parser,
-                        _position: SourcePosition,
-                        _error: ContextualParseError<'a>,
-                        _url: &ServoUrl,
-                        _line_number_offset: u64) {
+    fn report_error(&self,
+                    _url: &ServoUrl,
+                    _location: SourceLocation,
+                    _error: ContextualParseError) {
     }
 }
 
 fn test_media_rule<F>(css: &str, callback: F)
     where F: Fn(&MediaList, &str),
 {
     let url = ServoUrl::parse("http://localhost").unwrap();
     let css_str = css.to_owned();
--- a/servo/tests/unit/style/rule_tree/bench.rs
+++ b/servo/tests/unit/style/rule_tree/bench.rs
@@ -1,37 +1,33 @@
 /* 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 cssparser::{Parser, SourcePosition};
+use cssparser::SourceLocation;
 use rayon;
 use servo_arc::Arc;
 use servo_url::ServoUrl;
 use style::context::QuirksMode;
 use style::error_reporting::{ParseErrorReporter, ContextualParseError};
 use style::media_queries::MediaList;
 use style::properties::{longhands, Importance, PropertyDeclaration, PropertyDeclarationBlock};
 use style::rule_tree::{CascadeLevel, RuleTree, StrongRuleNode, StyleSource};
 use style::shared_lock::SharedRwLock;
 use style::stylesheets::{Origin, Stylesheet, CssRule};
 use style::thread_state;
 use test::{self, Bencher};
 
 struct ErrorringErrorReporter;
 impl ParseErrorReporter for ErrorringErrorReporter {
-    fn report_error<'a>(&self,
-                        input: &mut Parser,
-                        position: SourcePosition,
-                        error: ContextualParseError<'a>,
-                        url: &ServoUrl,
-                        line_number_offset: u64) {
-        let location = input.source_location(position);
-        let line_offset = location.line + line_number_offset as u32;
-        panic!("CSS error: {}\t\n{}:{} {}", url.as_str(), line_offset, location.column, error.to_string());
+    fn report_error(&self,
+                    url: &ServoUrl,
+                    location: SourceLocation,
+                    error: ContextualParseError) {
+        panic!("CSS error: {}\t\n{}:{} {}", url.as_str(), location.line, location.column, error.to_string());
     }
 }
 
 struct AutoGCRuleTree<'a>(&'a RuleTree);
 
 impl<'a> AutoGCRuleTree<'a> {
     fn new(r: &'a RuleTree) -> Self {
         AutoGCRuleTree(r)
--- a/servo/tests/unit/style/stylesheets.rs
+++ b/servo/tests/unit/style/stylesheets.rs
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-use cssparser::{self, Parser as CssParser, SourcePosition, SourceLocation};
+use cssparser::{self, SourceLocation};
 use html5ever::{Namespace as NsAtom};
 use media_queries::CSSErrorReporterTest;
 use parking_lot::RwLock;
 use selectors::attr::*;
 use selectors::parser::*;
 use servo_arc::Arc;
 use servo_atoms::Atom;
 use servo_url::ServoUrl;
@@ -265,31 +265,25 @@ impl CSSInvalidErrorReporterTest {
     pub fn new() -> CSSInvalidErrorReporterTest {
         return CSSInvalidErrorReporterTest{
             errors: Arc::new(Mutex::new(Vec::new()))
         }
     }
 }
 
 impl ParseErrorReporter for CSSInvalidErrorReporterTest {
-    fn report_error<'a>(&self,
-                        input: &mut CssParser,
-                        position: SourcePosition,
-                        error: ContextualParseError<'a>,
-                        url: &ServoUrl,
-                        line_number_offset: u64) {
-
-        let location = input.source_location(position);
-        let line_offset = location.line + line_number_offset as u32;
-
+    fn report_error(&self,
+                    url: &ServoUrl,
+                    location: SourceLocation,
+                    error: ContextualParseError) {
         let mut errors = self.errors.lock().unwrap();
         errors.push(
             CSSError{
                 url: url.clone(),
-                line: line_offset,
+                line: location.line,
                 column: location.column,
                 message: error.to_string()
             }
         );
     }
 }
 
 
--- a/servo/tests/unit/style/stylist.rs
+++ b/servo/tests/unit/style/stylist.rs
@@ -9,17 +9,16 @@ use html5ever::LocalName;
 use selectors::parser::{AncestorHashes, Selector};
 use selectors::parser::LocalName as LocalNameSelector;
 use servo_arc::Arc;
 use servo_atoms::Atom;
 use style::context::QuirksMode;
 use style::media_queries::{Device, MediaType};
 use style::properties::{PropertyDeclarationBlock, PropertyDeclaration};
 use style::properties::{longhands, Importance};
-use style::rule_tree::CascadeLevel;
 use style::selector_map::{self, SelectorMap};
 use style::selector_parser::{SelectorImpl, SelectorParser};
 use style::shared_lock::SharedRwLock;
 use style::stylesheets::StyleRule;
 use style::stylist::{Stylist, Rule};
 use style::stylist::needs_revalidation_for_testing;
 use style::thread_state;
 
--- a/servo/tests/unit/stylo/Cargo.toml
+++ b/servo/tests/unit/stylo/Cargo.toml
@@ -8,17 +8,17 @@ build = "build.rs"
 
 [lib]
 name = "stylo_tests"
 path = "lib.rs"
 doctest = false
 
 [dependencies]
 atomic_refcell = "0.1"
-cssparser = "0.18"
+cssparser = "0.19"
 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"}