about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorCorey Farwell <coreyf@rwell.org>2017-03-19 20:51:10 -0400
committerGitHub <noreply@github.com>2017-03-19 20:51:10 -0400
commitdedf9d3593632faea7ccb2f78bd6517ce56bb06d (patch)
tree4dce9ecd354050500f5b8f63c3a9fc97f0f17bfc /src
parent7471d9793cf21f89f672eff14e6c529e286c2d30 (diff)
parent1d93a6cce0119dfb1248643c7fb701ff1f8d4a50 (diff)
downloadrust-dedf9d3593632faea7ccb2f78bd6517ce56bb06d.tar.gz
rust-dedf9d3593632faea7ccb2f78bd6517ce56bb06d.zip
Rollup merge of #40554 - nrc:rls-data, r=alexcrichton
Use rls-data crate

This basically pulls out a bunch of data structures used by save-analysis for serialization into an external crate, and pulls that crate in using Rustbuild. The RLS can then share these data structures with the compiler which in some cases will allow more efficient communication between the compiler and the RLS (i.e., without serialisation).

Along the way, I have to pull in rls-span, which is the RLS's way of defining spans (more type-safe than the compiler's built-in way). This is basically just to convert from compiler spans to RLS spans.

I also pull in the crates.io version of rustc-serialize, which is a bit annoying, but seems to be the only way to have serialisable data in an external crate. To make this work, all of the save-analysis crate has to use this version too (cc #40527).

Finally I pull in a line from #40347 to make the unstable crate checking stuff working.

There are a lot of changes to save-analysis but they are all mechanical and trivial - changing from using `From` to `Into` (because of orphan rules) being the main thing.

r? @alexcrichton
Diffstat (limited to 'src')
-rw-r--r--src/Cargo.lock90
-rw-r--r--src/bootstrap/bin/rustc.rs7
-rw-r--r--src/bootstrap/lib.rs25
-rw-r--r--src/librustc_save_analysis/Cargo.toml7
-rw-r--r--src/librustc_save_analysis/csv_dumper.rs6
-rw-r--r--src/librustc_save_analysis/data.rs70
-rw-r--r--src/librustc_save_analysis/dump.rs2
-rw-r--r--src/librustc_save_analysis/dump_visitor.rs6
-rw-r--r--src/librustc_save_analysis/external_data.rs159
-rw-r--r--src/librustc_save_analysis/json_api_dumper.rs459
-rw-r--r--src/librustc_save_analysis/json_dumper.rs535
-rw-r--r--src/librustc_save_analysis/lib.rs5
12 files changed, 558 insertions, 813 deletions
diff --git a/src/Cargo.lock b/src/Cargo.lock
index b34007db8ac..a9a6fabb5b2 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -27,7 +27,7 @@ version = "0.0.0"
 dependencies = [
  "build_helper 0.1.0",
  "core 0.0.0",
- "gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.0.0",
 ]
 
@@ -49,13 +49,23 @@ name = "arena"
 version = "0.0.0"
 
 [[package]]
+name = "atty"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "bitflags"
 version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "bitflags"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -65,11 +75,11 @@ dependencies = [
  "build_helper 0.1.0",
  "cmake 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -77,7 +87,7 @@ dependencies = [
 name = "build-manifest"
 version = "0.1.0"
 dependencies = [
- "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -94,17 +104,17 @@ version = "0.1.0"
 
 [[package]]
 name = "clap"
-version = "2.20.5"
+version = "2.21.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "vec_map 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "vec_map 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -112,7 +122,7 @@ name = "cmake"
 version = "0.1.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -130,7 +140,7 @@ version = "0.0.0"
 dependencies = [
  "build_helper 0.1.0",
  "core 0.0.0",
- "gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -140,7 +150,7 @@ dependencies = [
  "env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -186,7 +196,7 @@ name = "flate"
 version = "0.0.0"
 dependencies = [
  "build_helper 0.1.0",
- "gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -195,7 +205,7 @@ version = "0.0.0"
 
 [[package]]
 name = "gcc"
-version = "0.3.43"
+version = "0.3.44"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -221,7 +231,7 @@ dependencies = [
  "pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "quick-error 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -274,7 +284,7 @@ name = "mdbook"
 version = "0.0.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clap 2.21.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "handlebars 0.25.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -398,10 +408,27 @@ version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "rls-data"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rls-span 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rls-span"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "rustbook"
 version = "0.1.0"
 dependencies = [
- "clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clap 2.21.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "mdbook 0.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -435,7 +462,7 @@ dependencies = [
 
 [[package]]
 name = "rustc-serialize"
-version = "0.3.22"
+version = "0.3.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -577,7 +604,7 @@ name = "rustc_llvm"
 version = "0.0.0"
 dependencies = [
  "build_helper 0.1.0",
- "gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_bitflags 0.0.0",
 ]
 
@@ -690,8 +717,10 @@ name = "rustc_save_analysis"
 version = "0.0.0"
 dependencies = [
  "log 0.0.0",
+ "rls-data 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rls-span 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
- "serialize 0.0.0",
+ "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "syntax 0.0.0",
  "syntax_pos 0.0.0",
 ]
@@ -751,7 +780,7 @@ version = "0.0.0"
 dependencies = [
  "arena 0.0.0",
  "build_helper 0.1.0",
- "gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.0.0",
  "rustc 0.0.0",
  "rustc_back 0.0.0",
@@ -799,7 +828,7 @@ dependencies = [
  "collections 0.0.0",
  "compiler_builtins 0.0.0",
  "core 0.0.0",
- "gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.0.0",
  "panic_abort 0.0.0",
  "panic_unwind 0.0.0",
@@ -904,7 +933,7 @@ name = "toml"
 version = "0.1.30"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -940,7 +969,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "vec_map"
-version = "0.6.0"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -961,15 +990,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 [metadata]
 "checksum aho-corasick 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0638fd549427caa90c499814196d1b9e3725eb4d15d7339d6de073a680ed0ca2"
 "checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
+"checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"
 "checksum bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4f67931368edf3a9a51d29886d245f1c3db2f1ef0dcc9e35ff70341b78c10d23"
-"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
-"checksum clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7db281b0520e97fbd15cd615dcd8f8bcad0c26f5f7d5effe705f090f39e9a758"
+"checksum bitflags 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e1ab483fc81a8143faa7203c4a3c02888ebd1a782e37e41fa34753ba9a162"
+"checksum clap 2.21.1 (registry+https://github.com/rust-lang/crates.io-index)" = "74a80f603221c9cd9aa27a28f52af452850051598537bb6b359c38a7d61e5cda"
 "checksum cmake 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "e1acc68a3f714627af38f9f5d09706a28584ba60dfe2cca68f40bf779f941b25"
 "checksum dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80c8b71fd71146990a9742fc06dcbbde19161a267e0ad4e572c35162f4578c90"
 "checksum env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f"
 "checksum env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e3856f1697098606fc6cb97a93de88ca3f3bc35bb878c725920e6e82ecf05e83"
 "checksum filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "5363ab8e4139b8568a6237db5248646e5a8a2f89bd5ccb02092182b11fd3e922"
-"checksum gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)" = "c07c758b972368e703a562686adb39125707cc1ef3399da8c019fc6c2498a75d"
+"checksum gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)" = "a32cd40070d7611ab76343dcb3204b2bb28c8a9450989a83a3d590248142f439"
 "checksum getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685"
 "checksum handlebars 0.25.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b2249f6f0dc5a3bb2b3b1a8f797dfccbc4b053344d773d654ad565e51427d335"
 "checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c"
@@ -987,7 +1017,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum quick-error 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0aad603e8d7fb67da22dbdf1f4b826ce8829e406124109e73cf1b2454b93a71c"
 "checksum regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4278c17d0f6d62dfef0ab00028feb45bd7d2102843f80763474eeb1be8a10c01"
 "checksum regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9191b1f57603095f105d317e375d19b1c9c5c3185ea9633a99a6dcbed04457"
-"checksum rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "237546c689f20bb44980270c73c3b9edd0891c1be49cc1274406134a66d3957b"
+"checksum rls-data 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "af1dfff00189fd7b78edb9af131b0de703676c04fa8126aed77fd2c586775a4d"
+"checksum rls-span 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8656f7b850ac85fb204ef94318c641bbb15a32766e12f9a589a23e4c0fbc38db"
+"checksum rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "684ce48436d6465300c9ea783b6b14c4361d6b8dcbb1375b486a69cc19e2dfb0"
 "checksum serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)" = "a702319c807c016e51f672e5c77d6f0b46afddd744b5e437d6b8436b888b458f"
 "checksum serde_json 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)" = "dbc45439552eb8fb86907a2c41c1fd0ef97458efb87ff7f878db466eb581824e"
 "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
@@ -1000,7 +1032,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
 "checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91"
 "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
-"checksum vec_map 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cac5efe5cb0fa14ec2f84f83c701c562ee63f6dcc680861b21d65c682adfb05f"
+"checksum vec_map 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8cdc8b93bd0198ed872357fb2e667f7125646b1762f16d60b2c96350d361897"
 "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
 "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
 "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs
index ba85e81ff4f..62b7f6cb72e 100644
--- a/src/bootstrap/bin/rustc.rs
+++ b/src/bootstrap/bin/rustc.rs
@@ -94,6 +94,13 @@ fn main() {
             cmd.arg("-Cprefer-dynamic");
         }
 
+        // Pass the `rustbuild` feature flag to crates which rustbuild is
+        // building. See the comment in bootstrap/lib.rs where this env var is
+        // set for more details.
+        if env::var_os("RUSTBUILD_UNSTABLE").is_some() {
+            cmd.arg("--cfg").arg("rustbuild");
+        }
+
         // Help the libc crate compile by assisting it in finding the MUSL
         // native libraries.
         if let Some(s) = env::var_os("MUSL_ROOT") {
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 270cb8490d9..26f3c063061 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -180,7 +180,7 @@ struct Crate {
 ///
 /// These entries currently correspond to the various output directories of the
 /// build system, with each mod generating output in a different directory.
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, PartialEq, Eq)]
 pub enum Mode {
     /// This cargo is going to build the standard library, placing output in the
     /// "stageN-std" directory.
@@ -491,7 +491,7 @@ impl Build {
         // For other crates, however, we know that we've already got a standard
         // library up and running, so we can use the normal compiler to compile
         // build scripts in that situation.
-        if let Mode::Libstd = mode {
+        if mode == Mode::Libstd {
             cargo.env("RUSTC_SNAPSHOT", &self.rustc)
                  .env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_snapshot_libdir());
         } else {
@@ -499,6 +499,27 @@ impl Build {
                  .env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_libdir(compiler));
         }
 
+        // There are two invariants we try must maintain:
+        // * stable crates cannot depend on unstable crates (general Rust rule),
+        // * crates that end up in the sysroot must be unstable (rustbuild rule).
+        //
+        // In order to do enforce the latter, we pass the env var
+        // `RUSTBUILD_UNSTABLE` down the line for any crates which will end up
+        // in the sysroot. We read this in bootstrap/bin/rustc.rs and if it is
+        // set, then we pass the `rustbuild` feature to rustc when building the
+        // the crate.
+        //
+        // In turn, crates that can be used here should recognise the `rustbuild`
+        // feature and opt-in to `rustc_private`.
+        //
+        // We can't always pass `rustbuild` because crates which are outside of
+        // the comipiler, libs, and tests are stable and we don't want to make
+        // their deps unstable (since this would break the first invariant
+        // above).
+        if mode != Mode::Tool {
+            cargo.env("RUSTBUILD_UNSTABLE", "1");
+        }
+
         // Ignore incremental modes except for stage0, since we're
         // not guaranteeing correctness acros builds if the compiler
         // is changing under your feet.`
diff --git a/src/librustc_save_analysis/Cargo.toml b/src/librustc_save_analysis/Cargo.toml
index 3d66e5a3007..06c5150fd13 100644
--- a/src/librustc_save_analysis/Cargo.toml
+++ b/src/librustc_save_analysis/Cargo.toml
@@ -12,5 +12,8 @@ crate-type = ["dylib"]
 log = { path = "../liblog" }
 rustc = { path = "../librustc" }
 syntax = { path = "../libsyntax" }
-serialize = { path = "../libserialize" }
-syntax_pos = { path = "../libsyntax_pos" }
\ No newline at end of file
+syntax_pos = { path = "../libsyntax_pos" }
+rls-data = "0.1"
+rls-span = "0.1"
+# FIXME(#40527) should move rustc serialize out of tree
+rustc-serialize = "0.3"
diff --git a/src/librustc_save_analysis/csv_dumper.rs b/src/librustc_save_analysis/csv_dumper.rs
index 0fd95500422..59340ae87ee 100644
--- a/src/librustc_save_analysis/csv_dumper.rs
+++ b/src/librustc_save_analysis/csv_dumper.rs
@@ -13,6 +13,8 @@ use std::io::Write;
 use super::external_data::*;
 use super::dump::Dump;
 
+use rls_data::{SpanData, CratePreludeData};
+
 pub struct CsvDumper<'b, W: 'b> {
     output: &'b mut W
 }
@@ -429,6 +431,6 @@ fn make_values_str(pairs: &[(&'static str, &str)]) -> String {
 fn span_extent_str(span: SpanData) -> String {
     format!("file_name,\"{}\",file_line,{},file_col,{},byte_start,{},\
              file_line_end,{},file_col_end,{},byte_end,{}",
-             span.file_name, span.line_start, span.column_start, span.byte_start,
-             span.line_end, span.column_end, span.byte_end)
+             span.file_name.to_str().unwrap(), span.line_start.0, span.column_start.0,
+             span.byte_start, span.line_end.0, span.column_end.0, span.byte_end)
 }
diff --git a/src/librustc_save_analysis/data.rs b/src/librustc_save_analysis/data.rs
index 6caf81380e4..d4ded71a333 100644
--- a/src/librustc_save_analysis/data.rs
+++ b/src/librustc_save_analysis/data.rs
@@ -18,6 +18,8 @@ use rustc::hir::def_id::{CrateNum, DefId};
 use syntax::ast::{self, Attribute, NodeId};
 use syntax_pos::Span;
 
+use rls_data::ExternalCrateData;
+
 pub struct CrateData {
     pub name: String,
     pub number: u32,
@@ -26,7 +28,7 @@ pub struct CrateData {
 
 /// Data for any entity in the Rust language. The actual data contained varies
 /// with the kind of entity being queried. See the nested structs for details.
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub enum Data {
     /// Data for Enums.
     EnumData(EnumData),
@@ -77,7 +79,7 @@ pub enum Data {
     VariableRefData(VariableRefData),
 }
 
-#[derive(Eq, PartialEq, Clone, Copy, Debug, RustcEncodable)]
+#[derive(Eq, PartialEq, Clone, Copy, Debug)]
 pub enum Visibility {
     Public,
     Restricted,
@@ -107,7 +109,7 @@ impl<'a> From<&'a hir::Visibility> for Visibility {
 }
 
 /// Data for the prelude of a crate.
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct CratePreludeData {
     pub crate_name: String,
     pub crate_root: String,
@@ -115,16 +117,8 @@ pub struct CratePreludeData {
     pub span: Span,
 }
 
-/// Data for external crates in the prelude of a crate.
-#[derive(Debug, RustcEncodable)]
-pub struct ExternalCrateData {
-    pub name: String,
-    pub num: CrateNum,
-    pub file_name: String,
-}
-
 /// Data for enum declarations.
-#[derive(Clone, Debug, RustcEncodable)]
+#[derive(Clone, Debug)]
 pub struct EnumData {
     pub id: NodeId,
     pub name: String,
@@ -140,7 +134,7 @@ pub struct EnumData {
 }
 
 /// Data for extern crates.
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct ExternCrateData {
     pub id: NodeId,
     pub name: String,
@@ -151,7 +145,7 @@ pub struct ExternCrateData {
 }
 
 /// Data about a function call.
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct FunctionCallData {
     pub span: Span,
     pub scope: NodeId,
@@ -159,7 +153,7 @@ pub struct FunctionCallData {
 }
 
 /// Data for all kinds of functions and methods.
-#[derive(Clone, Debug, RustcEncodable)]
+#[derive(Clone, Debug)]
 pub struct FunctionData {
     pub id: NodeId,
     pub name: String,
@@ -176,14 +170,14 @@ pub struct FunctionData {
 }
 
 /// Data about a function call.
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct FunctionRefData {
     pub span: Span,
     pub scope: NodeId,
     pub ref_id: DefId,
 }
 
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct ImplData {
     pub id: NodeId,
     pub span: Span,
@@ -192,7 +186,7 @@ pub struct ImplData {
     pub self_ref: Option<DefId>,
 }
 
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 // FIXME: this struct should not exist. However, removing it requires heavy
 // refactoring of dump_visitor.rs. See PR 31838 for more info.
 pub struct ImplData2 {
@@ -206,7 +200,7 @@ pub struct ImplData2 {
     pub self_ref: Option<TypeRefData>,
 }
 
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct InheritanceData {
     pub span: Span,
     pub base_id: DefId,
@@ -214,7 +208,7 @@ pub struct InheritanceData {
 }
 
 /// Data about a macro declaration.
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct MacroData {
     pub span: Span,
     pub name: String,
@@ -223,7 +217,7 @@ pub struct MacroData {
 }
 
 /// Data about a macro use.
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct MacroUseData {
     pub span: Span,
     pub name: String,
@@ -236,7 +230,7 @@ pub struct MacroUseData {
 }
 
 /// Data about a method call.
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct MethodCallData {
     pub span: Span,
     pub scope: NodeId,
@@ -245,7 +239,7 @@ pub struct MethodCallData {
 }
 
 /// Data for method declarations (methods with a body are treated as functions).
-#[derive(Clone, Debug, RustcEncodable)]
+#[derive(Clone, Debug)]
 pub struct MethodData {
     pub id: NodeId,
     pub name: String,
@@ -262,7 +256,7 @@ pub struct MethodData {
 }
 
 /// Data for modules.
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct ModData {
     pub id: NodeId,
     pub name: String,
@@ -278,7 +272,7 @@ pub struct ModData {
 }
 
 /// Data for a reference to a module.
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct ModRefData {
     pub span: Span,
     pub scope: NodeId,
@@ -286,7 +280,7 @@ pub struct ModRefData {
     pub qualname: String
 }
 
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct StructData {
     pub span: Span,
     pub name: String,
@@ -302,7 +296,7 @@ pub struct StructData {
     pub attributes: Vec<Attribute>,
 }
 
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct StructVariantData {
     pub span: Span,
     pub name: String,
@@ -317,7 +311,7 @@ pub struct StructVariantData {
     pub attributes: Vec<Attribute>,
 }
 
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct TraitData {
     pub span: Span,
     pub id: NodeId,
@@ -332,7 +326,7 @@ pub struct TraitData {
     pub attributes: Vec<Attribute>,
 }
 
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct TupleVariantData {
     pub span: Span,
     pub id: NodeId,
@@ -348,7 +342,7 @@ pub struct TupleVariantData {
 }
 
 /// Data for a typedef.
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct TypeDefData {
     pub id: NodeId,
     pub name: String,
@@ -363,7 +357,7 @@ pub struct TypeDefData {
 }
 
 /// Data for a reference to a type or trait.
-#[derive(Clone, Debug, RustcEncodable)]
+#[derive(Clone, Debug)]
 pub struct TypeRefData {
     pub span: Span,
     pub scope: NodeId,
@@ -371,7 +365,7 @@ pub struct TypeRefData {
     pub qualname: String,
 }
 
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct UseData {
     pub id: NodeId,
     pub span: Span,
@@ -381,7 +375,7 @@ pub struct UseData {
     pub visibility: Visibility,
 }
 
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct UseGlobData {
     pub id: NodeId,
     pub span: Span,
@@ -391,7 +385,7 @@ pub struct UseGlobData {
 }
 
 /// Data for local and global variables (consts and statics).
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct VariableData {
     pub id: NodeId,
     pub kind: VariableKind,
@@ -408,7 +402,7 @@ pub struct VariableData {
     pub attributes: Vec<Attribute>,
 }
 
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub enum VariableKind {
     Static,
     Const,
@@ -418,7 +412,7 @@ pub enum VariableKind {
 
 /// Data for the use of some item (e.g., the use of a local variable, which
 /// will refer to that variables declaration (by ref_id)).
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct VariableRefData {
     pub name: String,
     pub span: Span,
@@ -430,7 +424,7 @@ pub struct VariableRefData {
 /// Encodes information about the signature of a definition. This should have
 /// enough information to create a nice display about a definition without
 /// access to the source code.
-#[derive(Clone, Debug, RustcEncodable)]
+#[derive(Clone, Debug)]
 pub struct Signature {
     pub span: Span,
     pub text: String,
@@ -444,7 +438,7 @@ pub struct Signature {
 
 /// An element of a signature. `start` and `end` are byte offsets into the `text`
 /// of the parent `Signature`.
-#[derive(Clone, Debug, RustcEncodable)]
+#[derive(Clone, Debug)]
 pub struct SigElement {
     pub id: DefId,
     pub start: usize,
diff --git a/src/librustc_save_analysis/dump.rs b/src/librustc_save_analysis/dump.rs
index 18241b394cc..84e1fb03f62 100644
--- a/src/librustc_save_analysis/dump.rs
+++ b/src/librustc_save_analysis/dump.rs
@@ -10,6 +10,8 @@
 
 use super::external_data::*;
 
+use rls_data::CratePreludeData;
+
 pub trait Dump {
     fn crate_prelude(&mut self, CratePreludeData) {}
     fn enum_data(&mut self, EnumData) {}
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index 61956e5cd9d..f2aa89ba4b6 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -29,7 +29,7 @@
 
 use rustc::hir;
 use rustc::hir::def::Def;
-use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
+use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::hir::map::{Node, NodeItem};
 use rustc::session::Session;
 use rustc::ty::{self, TyCtxt, AssociatedItemContainer};
@@ -54,6 +54,8 @@ use super::external_data::{Lower, make_def_id};
 use super::span_utils::SpanUtils;
 use super::recorder;
 
+use rls_data::ExternalCrateData;
+
 macro_rules! down_cast_data {
     ($id:ident, $kind:ident, $sp:expr) => {
         let $id = if let super::Data::$kind(data) = $id {
@@ -137,7 +139,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
             let lo_loc = self.span.sess.codemap().lookup_char_pos(c.span.lo);
             ExternalCrateData {
                 name: c.name,
-                num: CrateNum::from_u32(c.number),
+                num: c.number,
                 file_name: SpanUtils::make_path_string(&lo_loc.file.name),
             }
         }).collect();
diff --git a/src/librustc_save_analysis/external_data.rs b/src/librustc_save_analysis/external_data.rs
index f038c2dc298..6fd2de97767 100644
--- a/src/librustc_save_analysis/external_data.rs
+++ b/src/librustc_save_analysis/external_data.rs
@@ -18,6 +18,9 @@ use syntax_pos::Span;
 
 use data::{self, Visibility, SigElement};
 
+use rls_data::{SpanData, CratePreludeData, Attribute};
+use rls_span::{Column, Row};
+
 // FIXME: this should be pub(crate), but the current snapshot doesn't allow it yet
 pub trait Lower {
     type Target;
@@ -35,41 +38,19 @@ pub fn null_def_id() -> DefId {
     }
 }
 
-#[derive(Clone, Debug, RustcEncodable)]
-pub struct SpanData {
-    pub file_name: String,
-    pub byte_start: u32,
-    pub byte_end: u32,
-    /// 1-based.
-    pub line_start: usize,
-    pub line_end: usize,
-    /// 1-based, character offset.
-    pub column_start: usize,
-    pub column_end: usize,
-}
-
-impl SpanData {
-    pub fn from_span(span: Span, cm: &CodeMap) -> SpanData {
-        let start = cm.lookup_char_pos(span.lo);
-        let end = cm.lookup_char_pos(span.hi);
-
-        SpanData {
-            file_name: start.file.name.clone(),
-            byte_start: span.lo.0,
-            byte_end: span.hi.0,
-            line_start: start.line,
-            line_end: end.line,
-            column_start: start.col.0 + 1,
-            column_end: end.col.0 + 1,
-        }
-    }
-}
+pub fn span_from_span(span: Span, cm: &CodeMap) -> SpanData {
+    let start = cm.lookup_char_pos(span.lo);
+    let end = cm.lookup_char_pos(span.hi);
 
-/// Represent an arbitrary attribute on a code element
-#[derive(Clone, Debug, RustcEncodable)]
-pub struct Attribute {
-    value: String,
-    span: SpanData,
+    SpanData {
+        file_name: start.file.name.clone().into(),
+        byte_start: span.lo.0,
+        byte_end: span.hi.0,
+        line_start: Row::new_one_indexed(start.line as u32),
+        line_end: Row::new_one_indexed(end.line as u32),
+        column_start: Column::new_one_indexed(start.col.0 as u32 + 1),
+        column_end: Column::new_one_indexed(end.col.0 as u32 + 1),
+    }
 }
 
 impl Lower for Vec<ast::Attribute> {
@@ -91,20 +72,12 @@ impl Lower for Vec<ast::Attribute> {
 
             Attribute {
                 value: value,
-                span: SpanData::from_span(attr.span, tcx.sess.codemap()),
+                span: span_from_span(attr.span, tcx.sess.codemap()),
             }
         }).collect()
     }
 }
 
-#[derive(Debug, RustcEncodable)]
-pub struct CratePreludeData {
-    pub crate_name: String,
-    pub crate_root: String,
-    pub external_crates: Vec<data::ExternalCrateData>,
-    pub span: SpanData,
-}
-
 impl Lower for data::CratePreludeData {
     type Target = CratePreludeData;
 
@@ -113,13 +86,13 @@ impl Lower for data::CratePreludeData {
             crate_name: self.crate_name,
             crate_root: self.crate_root,
             external_crates: self.external_crates,
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
         }
     }
 }
 
 /// Data for enum declarations.
-#[derive(Clone, Debug, RustcEncodable)]
+#[derive(Clone, Debug)]
 pub struct EnumData {
     pub id: DefId,
     pub value: String,
@@ -143,7 +116,7 @@ impl Lower for data::EnumData {
             name: self.name,
             value: self.value,
             qualname: self.qualname,
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.hir),
             variants: self.variants.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(),
             visibility: self.visibility,
@@ -155,7 +128,7 @@ impl Lower for data::EnumData {
 }
 
 /// Data for extern crates.
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct ExternCrateData {
     pub id: DefId,
     pub name: String,
@@ -174,14 +147,14 @@ impl Lower for data::ExternCrateData {
             name: self.name,
             crate_num: self.crate_num,
             location: self.location,
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.hir),
         }
     }
 }
 
 /// Data about a function call.
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct FunctionCallData {
     pub span: SpanData,
     pub scope: DefId,
@@ -193,7 +166,7 @@ impl Lower for data::FunctionCallData {
 
     fn lower(self, tcx: TyCtxt) -> FunctionCallData {
         FunctionCallData {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.hir),
             ref_id: self.ref_id,
         }
@@ -201,7 +174,7 @@ impl Lower for data::FunctionCallData {
 }
 
 /// Data for all kinds of functions and methods.
-#[derive(Clone, Debug, RustcEncodable)]
+#[derive(Clone, Debug)]
 pub struct FunctionData {
     pub id: DefId,
     pub name: String,
@@ -226,7 +199,7 @@ impl Lower for data::FunctionData {
             name: self.name,
             qualname: self.qualname,
             declaration: self.declaration,
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.hir),
             value: self.value,
             visibility: self.visibility,
@@ -239,7 +212,7 @@ impl Lower for data::FunctionData {
 }
 
 /// Data about a function call.
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct FunctionRefData {
     pub span: SpanData,
     pub scope: DefId,
@@ -251,13 +224,13 @@ impl Lower for data::FunctionRefData {
 
     fn lower(self, tcx: TyCtxt) -> FunctionRefData {
         FunctionRefData {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.hir),
             ref_id: self.ref_id,
         }
     }
 }
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct ImplData {
     pub id: DefId,
     pub span: SpanData,
@@ -272,7 +245,7 @@ impl Lower for data::ImplData {
     fn lower(self, tcx: TyCtxt) -> ImplData {
         ImplData {
             id: make_def_id(self.id, &tcx.hir),
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.hir),
             trait_ref: self.trait_ref,
             self_ref: self.self_ref,
@@ -280,7 +253,7 @@ impl Lower for data::ImplData {
     }
 }
 
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct InheritanceData {
     pub span: SpanData,
     pub base_id: DefId,
@@ -292,7 +265,7 @@ impl Lower for data::InheritanceData {
 
     fn lower(self, tcx: TyCtxt) -> InheritanceData {
         InheritanceData {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             base_id: self.base_id,
             deriv_id: make_def_id(self.deriv_id, &tcx.hir)
         }
@@ -300,7 +273,7 @@ impl Lower for data::InheritanceData {
 }
 
 /// Data about a macro declaration.
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct MacroData {
     pub span: SpanData,
     pub name: String,
@@ -313,7 +286,7 @@ impl Lower for data::MacroData {
 
     fn lower(self, tcx: TyCtxt) -> MacroData {
         MacroData {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             name: self.name,
             qualname: self.qualname,
             docs: self.docs,
@@ -322,7 +295,7 @@ impl Lower for data::MacroData {
 }
 
 /// Data about a macro use.
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct MacroUseData {
     pub span: SpanData,
     pub name: String,
@@ -338,17 +311,17 @@ impl Lower for data::MacroUseData {
 
     fn lower(self, tcx: TyCtxt) -> MacroUseData {
         MacroUseData {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             name: self.name,
             qualname: self.qualname,
-            callee_span: SpanData::from_span(self.callee_span, tcx.sess.codemap()),
+            callee_span: span_from_span(self.callee_span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.hir),
         }
     }
 }
 
 /// Data about a method call.
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct MethodCallData {
     pub span: SpanData,
     pub scope: DefId,
@@ -361,7 +334,7 @@ impl Lower for data::MethodCallData {
 
     fn lower(self, tcx: TyCtxt) -> MethodCallData {
         MethodCallData {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.hir),
             ref_id: self.ref_id,
             decl_id: self.decl_id,
@@ -370,7 +343,7 @@ impl Lower for data::MethodCallData {
 }
 
 /// Data for method declarations (methods with a body are treated as functions).
-#[derive(Clone, Debug, RustcEncodable)]
+#[derive(Clone, Debug)]
 pub struct MethodData {
     pub id: DefId,
     pub name: String,
@@ -391,7 +364,7 @@ impl Lower for data::MethodData {
 
     fn lower(self, tcx: TyCtxt) -> MethodData {
         MethodData {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             name: self.name,
             scope: make_def_id(self.scope, &tcx.hir),
             id: make_def_id(self.id, &tcx.hir),
@@ -408,7 +381,7 @@ impl Lower for data::MethodData {
 }
 
 /// Data for modules.
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct ModData {
     pub id: DefId,
     pub name: String,
@@ -431,7 +404,7 @@ impl Lower for data::ModData {
             id: make_def_id(self.id, &tcx.hir),
             name: self.name,
             qualname: self.qualname,
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.hir),
             filename: self.filename,
             items: self.items.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(),
@@ -444,7 +417,7 @@ impl Lower for data::ModData {
 }
 
 /// Data for a reference to a module.
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct ModRefData {
     pub span: SpanData,
     pub scope: DefId,
@@ -457,7 +430,7 @@ impl Lower for data::ModRefData {
 
     fn lower(self, tcx: TyCtxt) -> ModRefData {
         ModRefData {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.hir),
             ref_id: self.ref_id,
             qualname: self.qualname,
@@ -465,7 +438,7 @@ impl Lower for data::ModRefData {
     }
 }
 
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct StructData {
     pub span: SpanData,
     pub name: String,
@@ -486,7 +459,7 @@ impl Lower for data::StructData {
 
     fn lower(self, tcx: TyCtxt) -> StructData {
         StructData {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             name: self.name,
             id: make_def_id(self.id, &tcx.hir),
             ctor_id: make_def_id(self.ctor_id, &tcx.hir),
@@ -502,7 +475,7 @@ impl Lower for data::StructData {
     }
 }
 
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct StructVariantData {
     pub span: SpanData,
     pub name: String,
@@ -522,7 +495,7 @@ impl Lower for data::StructVariantData {
 
     fn lower(self, tcx: TyCtxt) -> StructVariantData {
         StructVariantData {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             name: self.name,
             id: make_def_id(self.id, &tcx.hir),
             qualname: self.qualname,
@@ -537,7 +510,7 @@ impl Lower for data::StructVariantData {
     }
 }
 
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct TraitData {
     pub span: SpanData,
     pub name: String,
@@ -557,7 +530,7 @@ impl Lower for data::TraitData {
 
     fn lower(self, tcx: TyCtxt) -> TraitData {
         TraitData {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             name: self.name,
             id: make_def_id(self.id, &tcx.hir),
             qualname: self.qualname,
@@ -572,7 +545,7 @@ impl Lower for data::TraitData {
     }
 }
 
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct TupleVariantData {
     pub span: SpanData,
     pub id: DefId,
@@ -592,7 +565,7 @@ impl Lower for data::TupleVariantData {
 
     fn lower(self, tcx: TyCtxt) -> TupleVariantData {
         TupleVariantData {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             id: make_def_id(self.id, &tcx.hir),
             name: self.name,
             qualname: self.qualname,
@@ -608,7 +581,7 @@ impl Lower for data::TupleVariantData {
 }
 
 /// Data for a typedef.
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct TypeDefData {
     pub id: DefId,
     pub name: String,
@@ -629,7 +602,7 @@ impl Lower for data::TypeDefData {
         TypeDefData {
             id: make_def_id(self.id, &tcx.hir),
             name: self.name,
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             qualname: self.qualname,
             value: self.value,
             visibility: self.visibility,
@@ -642,7 +615,7 @@ impl Lower for data::TypeDefData {
 }
 
 /// Data for a reference to a type or trait.
-#[derive(Clone, Debug, RustcEncodable)]
+#[derive(Clone, Debug)]
 pub struct TypeRefData {
     pub span: SpanData,
     pub scope: DefId,
@@ -655,7 +628,7 @@ impl Lower for data::TypeRefData {
 
     fn lower(self, tcx: TyCtxt) -> TypeRefData {
         TypeRefData {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.hir),
             ref_id: self.ref_id,
             qualname: self.qualname,
@@ -663,7 +636,7 @@ impl Lower for data::TypeRefData {
     }
 }
 
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct UseData {
     pub id: DefId,
     pub span: SpanData,
@@ -679,7 +652,7 @@ impl Lower for data::UseData {
     fn lower(self, tcx: TyCtxt) -> UseData {
         UseData {
             id: make_def_id(self.id, &tcx.hir),
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             name: self.name,
             mod_id: self.mod_id,
             scope: make_def_id(self.scope, &tcx.hir),
@@ -688,7 +661,7 @@ impl Lower for data::UseData {
     }
 }
 
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct UseGlobData {
     pub id: DefId,
     pub span: SpanData,
@@ -703,7 +676,7 @@ impl Lower for data::UseGlobData {
     fn lower(self, tcx: TyCtxt) -> UseGlobData {
         UseGlobData {
             id: make_def_id(self.id, &tcx.hir),
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             names: self.names,
             scope: make_def_id(self.scope, &tcx.hir),
             visibility: self.visibility,
@@ -712,7 +685,7 @@ impl Lower for data::UseGlobData {
 }
 
 /// Data for local and global variables (consts and statics).
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct VariableData {
     pub id: DefId,
     pub name: String,
@@ -738,7 +711,7 @@ impl Lower for data::VariableData {
             kind: self.kind,
             name: self.name,
             qualname: self.qualname,
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.hir),
             value: self.value,
             type_value: self.type_value,
@@ -753,7 +726,7 @@ impl Lower for data::VariableData {
 
 /// Data for the use of some item (e.g., the use of a local variable, which
 /// will refer to that variables declaration (by ref_id)).
-#[derive(Debug, RustcEncodable)]
+#[derive(Debug)]
 pub struct VariableRefData {
     pub name: String,
     pub span: SpanData,
@@ -767,14 +740,14 @@ impl Lower for data::VariableRefData {
     fn lower(self, tcx: TyCtxt) -> VariableRefData {
         VariableRefData {
             name: self.name,
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.hir),
             ref_id: self.ref_id,
         }
     }
 }
 
-#[derive(Clone, Debug, RustcEncodable)]
+#[derive(Clone, Debug)]
 pub struct Signature {
     pub span: SpanData,
     pub text: String,
@@ -791,7 +764,7 @@ impl Lower for data::Signature {
 
     fn lower(self, tcx: TyCtxt) -> Signature {
         Signature {
-            span: SpanData::from_span(self.span, tcx.sess.codemap()),
+            span: span_from_span(self.span, tcx.sess.codemap()),
             text: self.text,
             ident_start: self.ident_start,
             ident_end: self.ident_end,
diff --git a/src/librustc_save_analysis/json_api_dumper.rs b/src/librustc_save_analysis/json_api_dumper.rs
index 277535f9e65..41221ad9863 100644
--- a/src/librustc_save_analysis/json_api_dumper.rs
+++ b/src/librustc_save_analysis/json_api_dumper.rs
@@ -10,13 +10,14 @@
 
 use std::io::Write;
 
-use rustc::hir::def_id::DefId;
 use rustc_serialize::json::as_json;
 
 use external_data::*;
-use data::{VariableKind, Visibility, SigElement};
+use data::{VariableKind, Visibility};
 use dump::Dump;
-use super::Format;
+use json_dumper::id_from_def_id;
+
+use rls_data::{Analysis, Import, ImportKind, Def, DefKind, CratePreludeData};
 
 
 // A dumper to dump a restricted set of JSON information, designed for use with
@@ -24,8 +25,7 @@ use super::Format;
 // information here, and (for example) generate Rustdoc URLs, but don't need
 // information for navigating the source of the crate.
 // Relative to the regular JSON save-analysis info, this form is filtered to
-// remove non-visible items, but includes some extra info for items (e.g., the
-// parent field for finding the struct to which a field belongs).
+// remove non-visible items.
 pub struct JsonApiDumper<'b, W: Write + 'b> {
     output: &'b mut W,
     result: Analysis,
@@ -48,7 +48,7 @@ impl<'b, W: Write> Drop for JsonApiDumper<'b, W> {
 macro_rules! impl_fn {
     ($fn_name: ident, $data_type: ident, $bucket: ident) => {
         fn $fn_name(&mut self, data: $data_type) {
-            if let Some(datum) = From::from(data) {
+            if let Some(datum) = data.into() {
                 self.result.$bucket.push(datum);
             }
         }
@@ -77,11 +77,11 @@ impl<'b, W: Write + 'b> Dump for JsonApiDumper<'b, W> {
 
     fn impl_data(&mut self, data: ImplData) {
         if data.self_ref.is_some() {
-            self.result.relations.push(From::from(data));
+            self.result.relations.push(data.into());
         }
     }
     fn inheritance(&mut self, data: InheritanceData) {
-        self.result.relations.push(From::from(data));
+        self.result.relations.push(data.into());
     }
 }
 
@@ -90,426 +90,261 @@ impl<'b, W: Write + 'b> Dump for JsonApiDumper<'b, W> {
 // method, but not the supplied method). In both cases, we are currently
 // ignoring it.
 
-#[derive(Debug, RustcEncodable)]
-struct Analysis {
-    kind: Format,
-    prelude: Option<CratePreludeData>,
-    imports: Vec<Import>,
-    defs: Vec<Def>,
-    relations: Vec<Relation>,
-    // These two fields are dummies so that clients can parse the two kinds of
-    // JSON data in the same way.
-    refs: Vec<()>,
-    macro_refs: Vec<()>,
-}
-
-impl Analysis {
-    fn new() -> Analysis {
-        Analysis {
-            kind: Format::JsonApi,
-            prelude: None,
-            imports: vec![],
-            defs: vec![],
-            relations: vec![],
-            refs: vec![],
-            macro_refs: vec![],
-        }
-    }
-}
-
-// DefId::index is a newtype and so the JSON serialisation is ugly. Therefore
-// we use our own Id which is the same, but without the newtype.
-#[derive(Debug, RustcEncodable)]
-struct Id {
-    krate: u32,
-    index: u32,
-}
-
-impl From<DefId> for Id {
-    fn from(id: DefId) -> Id {
-        Id {
-            krate: id.krate.as_u32(),
-            index: id.index.as_u32(),
-        }
-    }
-}
-
-#[derive(Debug, RustcEncodable)]
-struct Import {
-    kind: ImportKind,
-    id: Id,
-    span: SpanData,
-    name: String,
-    value: String,
-}
-
-#[derive(Debug, RustcEncodable)]
-enum ImportKind {
-    Use,
-    GlobUse,
-}
-
-impl From<UseData> for Option<Import> {
-    fn from(data: UseData) -> Option<Import> {
-        match data.visibility {
+impl Into<Option<Import>> for UseData {
+    fn into(self) -> Option<Import> {
+        match self.visibility {
             Visibility::Public => Some(Import {
                 kind: ImportKind::Use,
-                id: From::from(data.id),
-                span: data.span,
-                name: data.name,
+                ref_id: self.mod_id.map(|id| id_from_def_id(id)),
+                span: self.span,
+                name: self.name,
                 value: String::new(),
             }),
             _ => None,
         }
     }
 }
-impl From<UseGlobData> for Option<Import> {
-    fn from(data: UseGlobData) -> Option<Import> {
-        match data.visibility {
+impl Into<Option<Import>> for UseGlobData {
+    fn into(self) -> Option<Import> {
+        match self.visibility {
             Visibility::Public => Some(Import {
                 kind: ImportKind::GlobUse,
-                id: From::from(data.id),
-                span: data.span,
+                ref_id: None,
+                span: self.span,
                 name: "*".to_owned(),
-                value: data.names.join(", "),
+                value: self.names.join(", "),
             }),
             _ => None,
         }
     }
 }
 
-#[derive(Debug, RustcEncodable)]
-struct Def {
-    kind: DefKind,
-    id: Id,
-    span: SpanData,
-    name: String,
-    qualname: String,
-    value: String,
-    parent: Option<Id>,
-    children: Vec<Id>,
-    decl_id: Option<Id>,
-    docs: String,
-    sig: Option<JsonSignature>,
-}
-
-#[derive(Debug, RustcEncodable)]
-enum DefKind {
-    // value = variant names
-    Enum,
-    // value = enum name + variant name + types
-    Tuple,
-    // value = [enum name +] name + fields
-    Struct,
-    // value = signature
-    Trait,
-    // value = type + generics
-    Function,
-    // value = type + generics
-    Method,
-    // No id, no value.
-    Macro,
-    // value = file_name
-    Mod,
-    // value = aliased type
-    Type,
-    // value = type and init expression (for all variable kinds).
-    Static,
-    Const,
-    Field,
-}
-
-impl From<EnumData> for Option<Def> {
-    fn from(data: EnumData) -> Option<Def> {
-        match data.visibility {
+impl Into<Option<Def>> for EnumData {
+    fn into(self) -> Option<Def> {
+        match self.visibility {
             Visibility::Public => Some(Def {
                 kind: DefKind::Enum,
-                id: From::from(data.id),
-                span: data.span,
-                name: data.name,
-                qualname: data.qualname,
-                value: data.value,
+                id: id_from_def_id(self.id),
+                span: self.span,
+                name: self.name,
+                qualname: self.qualname,
+                value: self.value,
                 parent: None,
-                children: data.variants.into_iter().map(|id| From::from(id)).collect(),
+                children: self.variants.into_iter().map(|id| id_from_def_id(id)).collect(),
                 decl_id: None,
-                docs: data.docs,
-                sig: Some(From::from(data.sig)),
+                docs: self.docs,
+                sig: Some(self.sig.into()),
+                attributes: vec![],
             }),
             _ => None,
         }
     }
 }
 
-impl From<TupleVariantData> for Option<Def> {
-    fn from(data: TupleVariantData) -> Option<Def> {
+impl Into<Option<Def>> for TupleVariantData {
+    fn into(self) -> Option<Def> {
         Some(Def {
             kind: DefKind::Tuple,
-            id: From::from(data.id),
-            span: data.span,
-            name: data.name,
-            qualname: data.qualname,
-            value: data.value,
-            parent: data.parent.map(|id| From::from(id)),
+            id: id_from_def_id(self.id),
+            span: self.span,
+            name: self.name,
+            qualname: self.qualname,
+            value: self.value,
+            parent: self.parent.map(|id| id_from_def_id(id)),
             children: vec![],
             decl_id: None,
-            docs: data.docs,
-            sig: Some(From::from(data.sig)),
+            docs: self.docs,
+            sig: Some(self.sig.into()),
+            attributes: vec![],
         })
     }
 }
-impl From<StructVariantData> for Option<Def> {
-    fn from(data: StructVariantData) -> Option<Def> {
+impl Into<Option<Def>> for StructVariantData {
+    fn into(self) -> Option<Def> {
         Some(Def {
             kind: DefKind::Struct,
-            id: From::from(data.id),
-            span: data.span,
-            name: data.name,
-            qualname: data.qualname,
-            value: data.value,
-            parent: data.parent.map(|id| From::from(id)),
+            id: id_from_def_id(self.id),
+            span: self.span,
+            name: self.name,
+            qualname: self.qualname,
+            value: self.value,
+            parent: self.parent.map(|id| id_from_def_id(id)),
             children: vec![],
             decl_id: None,
-            docs: data.docs,
-            sig: Some(From::from(data.sig)),
+            docs: self.docs,
+            sig: Some(self.sig.into()),
+            attributes: vec![],
         })
     }
 }
-impl From<StructData> for Option<Def> {
-    fn from(data: StructData) -> Option<Def> {
-        match data.visibility {
+impl Into<Option<Def>> for StructData {
+    fn into(self) -> Option<Def> {
+        match self.visibility {
             Visibility::Public => Some(Def {
             kind: DefKind::Struct,
-            id: From::from(data.id),
-            span: data.span,
-            name: data.name,
-            qualname: data.qualname,
-            value: data.value,
+            id: id_from_def_id(self.id),
+            span: self.span,
+            name: self.name,
+            qualname: self.qualname,
+            value: self.value,
             parent: None,
-            children: data.fields.into_iter().map(|id| From::from(id)).collect(),
+            children: self.fields.into_iter().map(|id| id_from_def_id(id)).collect(),
             decl_id: None,
-            docs: data.docs,
-            sig: Some(From::from(data.sig)),
+            docs: self.docs,
+            sig: Some(self.sig.into()),
+            attributes: vec![],
         }),
             _ => None,
         }
     }
 }
-impl From<TraitData> for Option<Def> {
-    fn from(data: TraitData) -> Option<Def> {
-        match data.visibility {
+impl Into<Option<Def>> for TraitData {
+    fn into(self) -> Option<Def> {
+        match self.visibility {
             Visibility::Public => Some(Def {
                 kind: DefKind::Trait,
-                id: From::from(data.id),
-                span: data.span,
-                name: data.name,
-                qualname: data.qualname,
-                value: data.value,
-                children: data.items.into_iter().map(|id| From::from(id)).collect(),
+                id: id_from_def_id(self.id),
+                span: self.span,
+                name: self.name,
+                qualname: self.qualname,
+                value: self.value,
+                children: self.items.into_iter().map(|id| id_from_def_id(id)).collect(),
                 parent: None,
                 decl_id: None,
-                docs: data.docs,
-                sig: Some(From::from(data.sig)),
+                docs: self.docs,
+                sig: Some(self.sig.into()),
+                attributes: vec![],
             }),
             _ => None,
         }
     }
 }
-impl From<FunctionData> for Option<Def> {
-    fn from(data: FunctionData) -> Option<Def> {
-        match data.visibility {
+impl Into<Option<Def>> for FunctionData {
+    fn into(self) -> Option<Def> {
+        match self.visibility {
             Visibility::Public => Some(Def {
                 kind: DefKind::Function,
-                id: From::from(data.id),
-                span: data.span,
-                name: data.name,
-                qualname: data.qualname,
-                value: data.value,
+                id: id_from_def_id(self.id),
+                span: self.span,
+                name: self.name,
+                qualname: self.qualname,
+                value: self.value,
                 children: vec![],
-                parent: data.parent.map(|id| From::from(id)),
+                parent: self.parent.map(|id| id_from_def_id(id)),
                 decl_id: None,
-                docs: data.docs,
-                sig: Some(From::from(data.sig)),
+                docs: self.docs,
+                sig: Some(self.sig.into()),
+                attributes: vec![],
             }),
             _ => None,
         }
     }
 }
-impl From<MethodData> for Option<Def> {
-    fn from(data: MethodData) -> Option<Def> {
-        match data.visibility {
+impl Into<Option<Def>> for MethodData {
+    fn into(self) -> Option<Def> {
+        match self.visibility {
             Visibility::Public => Some(Def {
                 kind: DefKind::Method,
-                id: From::from(data.id),
-                span: data.span,
-                name: data.name,
-                qualname: data.qualname,
-                value: data.value,
+                id: id_from_def_id(self.id),
+                span: self.span,
+                name: self.name,
+                qualname: self.qualname,
+                value: self.value,
                 children: vec![],
-                parent: data.parent.map(|id| From::from(id)),
-                decl_id: data.decl_id.map(|id| From::from(id)),
-                docs: data.docs,
-                sig: Some(From::from(data.sig)),
+                parent: self.parent.map(|id| id_from_def_id(id)),
+                decl_id: self.decl_id.map(|id| id_from_def_id(id)),
+                docs: self.docs,
+                sig: Some(self.sig.into()),
+                attributes: vec![],
             }),
             _ => None,
         }
     }
 }
-impl From<MacroData> for Option<Def> {
-    fn from(data: MacroData) -> Option<Def> {
+impl Into<Option<Def>> for MacroData {
+    fn into(self) -> Option<Def> {
         Some(Def {
             kind: DefKind::Macro,
-            id: From::from(null_def_id()),
-            span: data.span,
-            name: data.name,
-            qualname: data.qualname,
+            id: id_from_def_id(null_def_id()),
+            span: self.span,
+            name: self.name,
+            qualname: self.qualname,
             value: String::new(),
             children: vec![],
             parent: None,
             decl_id: None,
-            docs: data.docs,
+            docs: self.docs,
             sig: None,
+            attributes: vec![],
         })
     }
 }
-impl From<ModData> for Option<Def> {
-    fn from(data:ModData) -> Option<Def> {
-        match data.visibility {
+impl Into<Option<Def>> for ModData {
+    fn into(self) -> Option<Def> {
+        match self.visibility {
             Visibility::Public => Some(Def {
                 kind: DefKind::Mod,
-                id: From::from(data.id),
-                span: data.span,
-                name: data.name,
-                qualname: data.qualname,
-                value: data.filename,
-                children: data.items.into_iter().map(|id| From::from(id)).collect(),
+                id: id_from_def_id(self.id),
+                span: self.span,
+                name: self.name,
+                qualname: self.qualname,
+                value: self.filename,
+                children: self.items.into_iter().map(|id| id_from_def_id(id)).collect(),
                 parent: None,
                 decl_id: None,
-                docs: data.docs,
-                sig: Some(From::from(data.sig)),
+                docs: self.docs,
+                sig: Some(self.sig.into()),
+                attributes: vec![],
             }),
             _ => None,
         }
     }
 }
-impl From<TypeDefData> for Option<Def> {
-    fn from(data: TypeDefData) -> Option<Def> {
-        match data.visibility {
+impl Into<Option<Def>> for TypeDefData {
+    fn into(self) -> Option<Def> {
+        match self.visibility {
             Visibility::Public => Some(Def {
                 kind: DefKind::Type,
-                id: From::from(data.id),
-                span: data.span,
-                name: data.name,
-                qualname: data.qualname,
-                value: data.value,
+                id: id_from_def_id(self.id),
+                span: self.span,
+                name: self.name,
+                qualname: self.qualname,
+                value: self.value,
                 children: vec![],
-                parent: data.parent.map(|id| From::from(id)),
+                parent: self.parent.map(|id| id_from_def_id(id)),
                 decl_id: None,
                 docs: String::new(),
-                sig: data.sig.map(|s| From::from(s)),
+                sig: self.sig.map(|s| s.into()),
+                attributes: vec![],
             }),
             _ => None,
         }
     }
 }
 
-impl From<VariableData> for Option<Def> {
-    fn from(data: VariableData) -> Option<Def> {
-        match data.visibility {
+impl Into<Option<Def>> for VariableData {
+    fn into(self) -> Option<Def> {
+        match self.visibility {
             Visibility::Public => Some(Def {
-                kind: match data.kind {
+                kind: match self.kind {
                     VariableKind::Static => DefKind::Static,
                     VariableKind::Const => DefKind::Const,
                     VariableKind::Local => { return None }
                     VariableKind::Field => DefKind::Field,
                 },
-                id: From::from(data.id),
-                span: data.span,
-                name: data.name,
-                qualname: data.qualname,
-                value: data.value,
+                id: id_from_def_id(self.id),
+                span: self.span,
+                name: self.name,
+                qualname: self.qualname,
+                value: self.value,
                 children: vec![],
-                parent: data.parent.map(|id| From::from(id)),
+                parent: self.parent.map(|id| id_from_def_id(id)),
                 decl_id: None,
-                docs: data.docs,
-                sig: data.sig.map(|s| From::from(s)),
+                docs: self.docs,
+                sig: self.sig.map(|s| s.into()),
+                attributes: vec![],
             }),
             _ => None,
         }
     }
 }
-
-#[derive(Debug, RustcEncodable)]
-struct Relation {
-    span: SpanData,
-    kind: RelationKind,
-    from: Id,
-    to: Id,
-}
-
-#[derive(Debug, RustcEncodable)]
-enum RelationKind {
-    Impl,
-    SuperTrait,
-}
-
-impl From<ImplData> for Relation {
-    fn from(data: ImplData) -> Relation {
-        Relation {
-            span: data.span,
-            kind: RelationKind::Impl,
-            from: From::from(data.self_ref.unwrap_or(null_def_id())),
-            to: From::from(data.trait_ref.unwrap_or(null_def_id())),
-        }
-    }
-}
-
-impl From<InheritanceData> for Relation {
-    fn from(data: InheritanceData) -> Relation {
-        Relation {
-            span: data.span,
-            kind: RelationKind::SuperTrait,
-            from: From::from(data.base_id),
-            to: From::from(data.deriv_id),
-        }
-    }
-}
-
-#[derive(Debug, RustcEncodable)]
-pub struct JsonSignature {
-    span: SpanData,
-    text: String,
-    ident_start: usize,
-    ident_end: usize,
-    defs: Vec<JsonSigElement>,
-    refs: Vec<JsonSigElement>,
-}
-
-impl From<Signature> for JsonSignature {
-    fn from(data: Signature) -> JsonSignature {
-        JsonSignature {
-            span: data.span,
-            text: data.text,
-            ident_start: data.ident_start,
-            ident_end: data.ident_end,
-            defs: data.defs.into_iter().map(|s| From::from(s)).collect(),
-            refs: data.refs.into_iter().map(|s| From::from(s)).collect(),
-        }
-    }
-}
-
-#[derive(Debug, RustcEncodable)]
-pub struct JsonSigElement {
-    id: Id,
-    start: usize,
-    end: usize,
-}
-
-impl From<SigElement> for JsonSigElement {
-    fn from(data: SigElement) -> JsonSigElement {
-        JsonSigElement {
-            id: From::from(data.id),
-            start: data.start,
-            end: data.end,
-        }
-    }
-}
diff --git a/src/librustc_save_analysis/json_dumper.rs b/src/librustc_save_analysis/json_dumper.rs
index 1b72489f83c..acc877d3947 100644
--- a/src/librustc_save_analysis/json_dumper.rs
+++ b/src/librustc_save_analysis/json_dumper.rs
@@ -13,10 +13,14 @@ use std::io::Write;
 use rustc::hir::def_id::DefId;
 use rustc_serialize::json::as_json;
 
+use rls_data::{self, Id, Analysis, Import, ImportKind, Def, DefKind, Ref, RefKind, MacroRef,
+               Relation, RelationKind, Signature, SigElement, CratePreludeData};
+use rls_span::{Column, Row};
+
+use external_data;
 use external_data::*;
-use data::{VariableKind, SigElement};
+use data::{self, VariableKind};
 use dump::Dump;
-use super::Format;
 
 pub struct JsonDumper<'b, W: Write + 'b> {
     output: &'b mut W,
@@ -40,7 +44,7 @@ impl<'b, W: Write> Drop for JsonDumper<'b, W> {
 macro_rules! impl_fn {
     ($fn_name: ident, $data_type: ident, $bucket: ident) => {
         fn $fn_name(&mut self, data: $data_type) {
-            self.result.$bucket.push(From::from(data));
+            self.result.$bucket.push(data.into());
         }
     }
 }
@@ -75,21 +79,22 @@ impl<'b, W: Write + 'b> Dump for JsonDumper<'b, W> {
     impl_fn!(macro_use, MacroUseData, macro_refs);
 
     fn mod_data(&mut self, data: ModData) {
-        let id: Id = From::from(data.id);
+        let id: Id = id_from_def_id(data.id);
         let mut def = Def {
             kind: DefKind::Mod,
             id: id,
-            span: data.span,
+            span: data.span.into(),
             name: data.name,
             qualname: data.qualname,
             value: data.filename,
-            children: data.items.into_iter().map(|id| From::from(id)).collect(),
+            parent: None,
+            children: data.items.into_iter().map(|id| id_from_def_id(id)).collect(),
             decl_id: None,
             docs: data.docs,
-            sig: Some(From::from(data.sig)),
-            attributes: data.attributes,
+            sig: Some(data.sig.into()),
+            attributes: data.attributes.into_iter().map(|a| a.into()).collect(),
         };
-        if def.span.file_name != def.value {
+        if def.span.file_name.to_str().unwrap() != def.value {
             // If the module is an out-of-line defintion, then we'll make the
             // defintion the first character in the module's file and turn the
             // the declaration into a reference to it.
@@ -99,14 +104,14 @@ impl<'b, W: Write + 'b> Dump for JsonDumper<'b, W> {
                 ref_id: id,
             };
             self.result.refs.push(rf);
-            def.span = SpanData {
-                file_name: def.value.clone(),
+            def.span = rls_data::SpanData {
+                file_name: def.value.clone().into(),
                 byte_start: 0,
                 byte_end: 0,
-                line_start: 1,
-                line_end: 1,
-                column_start: 1,
-                column_end: 1,
+                line_start: Row::new_one_indexed(1),
+                line_end: Row::new_one_indexed(1),
+                column_start: Column::new_one_indexed(1),
+                column_end: Column::new_one_indexed(1),
             }
         }
 
@@ -115,11 +120,11 @@ impl<'b, W: Write + 'b> Dump for JsonDumper<'b, W> {
 
     fn impl_data(&mut self, data: ImplData) {
         if data.self_ref.is_some() {
-            self.result.relations.push(From::from(data));
+            self.result.relations.push(data.into());
         }
     }
     fn inheritance(&mut self, data: InheritanceData) {
-        self.result.relations.push(From::from(data));
+        self.result.relations.push(data.into());
     }
 }
 
@@ -129,476 +134,342 @@ impl<'b, W: Write + 'b> Dump for JsonDumper<'b, W> {
 // method, but not the supplied method). In both cases, we are currently
 // ignoring it.
 
-#[derive(Debug, RustcEncodable)]
-struct Analysis {
-    kind: Format,
-    prelude: Option<CratePreludeData>,
-    imports: Vec<Import>,
-    defs: Vec<Def>,
-    refs: Vec<Ref>,
-    macro_refs: Vec<MacroRef>,
-    relations: Vec<Relation>,
-}
-
-impl Analysis {
-    fn new() -> Analysis {
-        Analysis {
-            kind: Format::Json,
-            prelude: None,
-            imports: vec![],
-            defs: vec![],
-            refs: vec![],
-            macro_refs: vec![],
-            relations: vec![],
-        }
-    }
-}
-
 // DefId::index is a newtype and so the JSON serialisation is ugly. Therefore
 // we use our own Id which is the same, but without the newtype.
-#[derive(Clone, Copy, Debug, RustcEncodable)]
-struct Id {
-    krate: u32,
-    index: u32,
-}
-
-impl From<DefId> for Id {
-    fn from(id: DefId) -> Id {
-        Id {
-            krate: id.krate.as_u32(),
-            index: id.index.as_u32(),
-        }
+pub fn id_from_def_id(id: DefId) -> Id {
+    Id {
+        krate: id.krate.as_u32(),
+        index: id.index.as_u32(),
     }
 }
 
-#[derive(Debug, RustcEncodable)]
-struct Import {
-    kind: ImportKind,
-    ref_id: Option<Id>,
-    span: SpanData,
-    name: String,
-    value: String,
-}
-
-#[derive(Debug, RustcEncodable)]
-enum ImportKind {
-    ExternCrate,
-    Use,
-    GlobUse,
-}
-
-impl From<ExternCrateData> for Import {
-    fn from(data: ExternCrateData) -> Import {
+impl Into<Import> for ExternCrateData {
+    fn into(self) -> Import {
         Import {
             kind: ImportKind::ExternCrate,
             ref_id: None,
-            span: data.span,
-            name: data.name,
+            span: self.span,
+            name: self.name,
             value: String::new(),
         }
     }
 }
-impl From<UseData> for Import {
-    fn from(data: UseData) -> Import {
+impl Into<Import> for UseData {
+    fn into(self) -> Import {
         Import {
             kind: ImportKind::Use,
-            ref_id: data.mod_id.map(|id| From::from(id)),
-            span: data.span,
-            name: data.name,
+            ref_id: self.mod_id.map(|id| id_from_def_id(id)),
+            span: self.span,
+            name: self.name,
             value: String::new(),
         }
     }
 }
-impl From<UseGlobData> for Import {
-    fn from(data: UseGlobData) -> Import {
+impl Into<Import> for UseGlobData {
+    fn into(self) -> Import {
         Import {
             kind: ImportKind::GlobUse,
             ref_id: None,
-            span: data.span,
+            span: self.span,
             name: "*".to_owned(),
-            value: data.names.join(", "),
+            value: self.names.join(", "),
         }
     }
 }
 
-#[derive(Debug, RustcEncodable)]
-struct Def {
-    kind: DefKind,
-    id: Id,
-    span: SpanData,
-    name: String,
-    qualname: String,
-    value: String,
-    children: Vec<Id>,
-    decl_id: Option<Id>,
-    docs: String,
-    sig: Option<JsonSignature>,
-    attributes: Vec<Attribute>,
-}
-
-#[derive(Debug, RustcEncodable)]
-enum DefKind {
-    // value = variant names
-    Enum,
-    // value = enum name + variant name + types
-    Tuple,
-    // value = [enum name +] name + fields
-    Struct,
-    // value = signature
-    Trait,
-    // value = type + generics
-    Function,
-    // value = type + generics
-    Method,
-    // No id, no value.
-    Macro,
-    // value = file_name
-    Mod,
-    // value = aliased type
-    Type,
-    // value = type and init expression (for all variable kinds).
-    Local,
-    Static,
-    Const,
-    Field,
-}
-
-impl From<EnumData> for Def {
-    fn from(data: EnumData) -> Def {
+impl Into<Def> for EnumData {
+    fn into(self) -> Def {
         Def {
             kind: DefKind::Enum,
-            id: From::from(data.id),
-            span: data.span,
-            name: data.name,
-            qualname: data.qualname,
-            value: data.value,
-            children: data.variants.into_iter().map(|id| From::from(id)).collect(),
+            id: id_from_def_id(self.id),
+            span: self.span,
+            name: self.name,
+            qualname: self.qualname,
+            value: self.value,
+            parent: None,
+            children: self.variants.into_iter().map(|id| id_from_def_id(id)).collect(),
             decl_id: None,
-            docs: data.docs,
-            sig: Some(From::from(data.sig)),
-            attributes: data.attributes,
+            docs: self.docs,
+            sig: Some(self.sig.into()),
+            attributes: self.attributes,
         }
     }
 }
 
-impl From<TupleVariantData> for Def {
-    fn from(data: TupleVariantData) -> Def {
+impl Into<Def> for TupleVariantData {
+    fn into(self) -> Def {
         Def {
             kind: DefKind::Tuple,
-            id: From::from(data.id),
-            span: data.span,
-            name: data.name,
-            qualname: data.qualname,
-            value: data.value,
+            id: id_from_def_id(self.id),
+            span: self.span,
+            name: self.name,
+            qualname: self.qualname,
+            value: self.value,
+            parent: None,
             children: vec![],
             decl_id: None,
-            docs: data.docs,
-            sig: Some(From::from(data.sig)),
-            attributes: data.attributes,
+            docs: self.docs,
+            sig: Some(self.sig.into()),
+            attributes: self.attributes,
         }
     }
 }
-impl From<StructVariantData> for Def {
-    fn from(data: StructVariantData) -> Def {
+impl Into<Def> for StructVariantData {
+    fn into(self) -> Def {
         Def {
             kind: DefKind::Struct,
-            id: From::from(data.id),
-            span: data.span,
-            name: data.name,
-            qualname: data.qualname,
-            value: data.value,
+            id: id_from_def_id(self.id),
+            span: self.span,
+            name: self.name,
+            qualname: self.qualname,
+            value: self.value,
+            parent: None,
             children: vec![],
             decl_id: None,
-            docs: data.docs,
-            sig: Some(From::from(data.sig)),
-            attributes: data.attributes,
+            docs: self.docs,
+            sig: Some(self.sig.into()),
+            attributes: self.attributes,
         }
     }
 }
-impl From<StructData> for Def {
-    fn from(data: StructData) -> Def {
+impl Into<Def> for StructData {
+    fn into(self) -> Def {
         Def {
             kind: DefKind::Struct,
-            id: From::from(data.id),
-            span: data.span,
-            name: data.name,
-            qualname: data.qualname,
-            value: data.value,
-            children: data.fields.into_iter().map(|id| From::from(id)).collect(),
+            id: id_from_def_id(self.id),
+            span: self.span,
+            name: self.name,
+            qualname: self.qualname,
+            value: self.value,
+            parent: None,
+            children: self.fields.into_iter().map(|id| id_from_def_id(id)).collect(),
             decl_id: None,
-            docs: data.docs,
-            sig: Some(From::from(data.sig)),
-            attributes: data.attributes,
+            docs: self.docs,
+            sig: Some(self.sig.into()),
+            attributes: self.attributes,
         }
     }
 }
-impl From<TraitData> for Def {
-    fn from(data: TraitData) -> Def {
+impl Into<Def> for TraitData {
+    fn into(self) -> Def {
         Def {
             kind: DefKind::Trait,
-            id: From::from(data.id),
-            span: data.span,
-            name: data.name,
-            qualname: data.qualname,
-            value: data.value,
-            children: data.items.into_iter().map(|id| From::from(id)).collect(),
+            id: id_from_def_id(self.id),
+            span: self.span,
+            name: self.name,
+            qualname: self.qualname,
+            value: self.value,
+            parent: None,
+            children: self.items.into_iter().map(|id| id_from_def_id(id)).collect(),
             decl_id: None,
-            docs: data.docs,
-            sig: Some(From::from(data.sig)),
-            attributes: data.attributes,
+            docs: self.docs,
+            sig: Some(self.sig.into()),
+            attributes: self.attributes,
         }
     }
 }
-impl From<FunctionData> for Def {
-    fn from(data: FunctionData) -> Def {
+impl Into<Def> for FunctionData {
+    fn into(self) -> Def {
         Def {
             kind: DefKind::Function,
-            id: From::from(data.id),
-            span: data.span,
-            name: data.name,
-            qualname: data.qualname,
-            value: data.value,
+            id: id_from_def_id(self.id),
+            span: self.span,
+            name: self.name,
+            qualname: self.qualname,
+            value: self.value,
+            parent: None,
             children: vec![],
             decl_id: None,
-            docs: data.docs,
-            sig: Some(From::from(data.sig)),
-            attributes: data.attributes,
+            docs: self.docs,
+            sig: Some(self.sig.into()),
+            attributes: self.attributes,
         }
     }
 }
-impl From<MethodData> for Def {
-    fn from(data: MethodData) -> Def {
+impl Into<Def> for MethodData {
+    fn into(self) -> Def {
         Def {
             kind: DefKind::Method,
-            id: From::from(data.id),
-            span: data.span,
-            name: data.name,
-            qualname: data.qualname,
-            value: data.value,
+            id: id_from_def_id(self.id),
+            span: self.span,
+            name: self.name,
+            qualname: self.qualname,
+            value: self.value,
+            parent: None,
             children: vec![],
-            decl_id: data.decl_id.map(|id| From::from(id)),
-            docs: data.docs,
-            sig: Some(From::from(data.sig)),
-            attributes: data.attributes,
+            decl_id: self.decl_id.map(|id| id_from_def_id(id)),
+            docs: self.docs,
+            sig: Some(self.sig.into()),
+            attributes: self.attributes,
         }
     }
 }
-impl From<MacroData> for Def {
-    fn from(data: MacroData) -> Def {
+impl Into<Def> for MacroData {
+    fn into(self) -> Def {
         Def {
             kind: DefKind::Macro,
-            id: From::from(null_def_id()),
-            span: data.span,
-            name: data.name,
-            qualname: data.qualname,
+            id: id_from_def_id(null_def_id()),
+            span: self.span,
+            name: self.name,
+            qualname: self.qualname,
             value: String::new(),
+            parent: None,
             children: vec![],
             decl_id: None,
-            docs: data.docs,
+            docs: self.docs,
             sig: None,
             attributes: vec![],
         }
     }
 }
-impl From<TypeDefData> for Def {
-    fn from(data: TypeDefData) -> Def {
+impl Into<Def> for TypeDefData {
+    fn into(self) -> Def {
         Def {
             kind: DefKind::Type,
-            id: From::from(data.id),
-            span: data.span,
-            name: data.name,
-            qualname: data.qualname,
-            value: data.value,
+            id: id_from_def_id(self.id),
+            span: self.span,
+            name: self.name,
+            qualname: self.qualname,
+            value: self.value,
+            parent: None,
             children: vec![],
             decl_id: None,
             docs: String::new(),
-            sig: data.sig.map(|s| From::from(s)),
-            attributes: data.attributes,
+            sig: self.sig.map(|s| s.into()),
+            attributes: self.attributes,
         }
     }
 }
-impl From<VariableData> for Def {
-    fn from(data: VariableData) -> Def {
+impl Into<Def> for VariableData {
+    fn into(self) -> Def {
         Def {
-            kind: match data.kind {
+            kind: match self.kind {
                 VariableKind::Static => DefKind::Static,
                 VariableKind::Const => DefKind::Const,
                 VariableKind::Local => DefKind::Local,
                 VariableKind::Field => DefKind::Field,
             },
-            id: From::from(data.id),
-            span: data.span,
-            name: data.name,
-            qualname: data.qualname,
-            value: data.type_value,
+            id: id_from_def_id(self.id),
+            span: self.span,
+            name: self.name,
+            qualname: self.qualname,
+            value: self.type_value,
+            parent: None,
             children: vec![],
             decl_id: None,
-            docs: data.docs,
+            docs: self.docs,
             sig: None,
-            attributes: data.attributes,
+            attributes: self.attributes,
         }
     }
 }
 
-#[derive(Debug, RustcEncodable)]
-enum RefKind {
-    Function,
-    Mod,
-    Type,
-    Variable,
-}
-
-#[derive(Debug, RustcEncodable)]
-struct Ref {
-    kind: RefKind,
-    span: SpanData,
-    ref_id: Id,
-}
-
-impl From<FunctionRefData> for Ref {
-    fn from(data: FunctionRefData) -> Ref {
+impl Into<Ref> for FunctionRefData {
+    fn into(self) -> Ref {
         Ref {
             kind: RefKind::Function,
-            span: data.span,
-            ref_id: From::from(data.ref_id),
+            span: self.span,
+            ref_id: id_from_def_id(self.ref_id),
         }
     }
 }
-impl From<FunctionCallData> for Ref {
-    fn from(data: FunctionCallData) -> Ref {
+impl Into<Ref> for FunctionCallData {
+    fn into(self) -> Ref {
         Ref {
             kind: RefKind::Function,
-            span: data.span,
-            ref_id: From::from(data.ref_id),
+            span: self.span,
+            ref_id: id_from_def_id(self.ref_id),
         }
     }
 }
-impl From<MethodCallData> for Ref {
-    fn from(data: MethodCallData) -> Ref {
+impl Into<Ref> for MethodCallData {
+    fn into(self) -> Ref {
         Ref {
             kind: RefKind::Function,
-            span: data.span,
-            ref_id: From::from(data.ref_id.or(data.decl_id).unwrap_or(null_def_id())),
+            span: self.span,
+            ref_id: id_from_def_id(self.ref_id.or(self.decl_id).unwrap_or(null_def_id())),
         }
     }
 }
-impl From<ModRefData> for Ref {
-    fn from(data: ModRefData) -> Ref {
+impl Into<Ref> for ModRefData {
+    fn into(self) -> Ref {
         Ref {
             kind: RefKind::Mod,
-            span: data.span,
-            ref_id: From::from(data.ref_id.unwrap_or(null_def_id())),
+            span: self.span,
+            ref_id: id_from_def_id(self.ref_id.unwrap_or(null_def_id())),
         }
     }
 }
-impl From<TypeRefData> for Ref {
-    fn from(data: TypeRefData) -> Ref {
+impl Into<Ref> for TypeRefData {
+    fn into(self) -> Ref {
         Ref {
             kind: RefKind::Type,
-            span: data.span,
-            ref_id: From::from(data.ref_id.unwrap_or(null_def_id())),
+            span: self.span,
+            ref_id: id_from_def_id(self.ref_id.unwrap_or(null_def_id())),
         }
     }
 }
-impl From<VariableRefData> for Ref {
-    fn from(data: VariableRefData) -> Ref {
+impl Into<Ref> for VariableRefData {
+    fn into(self) -> Ref {
         Ref {
             kind: RefKind::Variable,
-            span: data.span,
-            ref_id: From::from(data.ref_id),
+            span: self.span,
+            ref_id: id_from_def_id(self.ref_id),
         }
     }
 }
 
-#[derive(Debug, RustcEncodable)]
-struct MacroRef {
-    span: SpanData,
-    qualname: String,
-    callee_span: SpanData,
-}
-
-impl From<MacroUseData> for MacroRef {
-    fn from(data: MacroUseData) -> MacroRef {
+impl Into<MacroRef> for MacroUseData {
+    fn into(self) -> MacroRef {
         MacroRef {
-            span: data.span,
-            qualname: data.qualname,
-            callee_span: data.callee_span,
+            span: self.span,
+            qualname: self.qualname,
+            callee_span: self.callee_span.into(),
         }
     }
 }
 
-#[derive(Debug, RustcEncodable)]
-struct Relation {
-    span: SpanData,
-    kind: RelationKind,
-    from: Id,
-    to: Id,
-}
-
-#[derive(Debug, RustcEncodable)]
-enum RelationKind {
-    Impl,
-    SuperTrait,
-}
-
-impl From<ImplData> for Relation {
-    fn from(data: ImplData) -> Relation {
+impl Into<Relation> for ImplData {
+    fn into(self) -> Relation {
         Relation {
-            span: data.span,
+            span: self.span,
             kind: RelationKind::Impl,
-            from: From::from(data.self_ref.unwrap_or(null_def_id())),
-            to: From::from(data.trait_ref.unwrap_or(null_def_id())),
+            from: id_from_def_id(self.self_ref.unwrap_or(null_def_id())),
+            to: id_from_def_id(self.trait_ref.unwrap_or(null_def_id())),
         }
     }
 }
 
-impl From<InheritanceData> for Relation {
-    fn from(data: InheritanceData) -> Relation {
+impl Into<Relation> for InheritanceData {
+    fn into(self) -> Relation {
         Relation {
-            span: data.span,
+            span: self.span,
             kind: RelationKind::SuperTrait,
-            from: From::from(data.base_id),
-            to: From::from(data.deriv_id),
+            from: id_from_def_id(self.base_id),
+            to: id_from_def_id(self.deriv_id),
         }
     }
 }
 
-#[derive(Debug, RustcEncodable)]
-pub struct JsonSignature {
-    span: SpanData,
-    text: String,
-    ident_start: usize,
-    ident_end: usize,
-    defs: Vec<JsonSigElement>,
-    refs: Vec<JsonSigElement>,
-}
-
-impl From<Signature> for JsonSignature {
-    fn from(data: Signature) -> JsonSignature {
-        JsonSignature {
-            span: data.span,
-            text: data.text,
-            ident_start: data.ident_start,
-            ident_end: data.ident_end,
-            defs: data.defs.into_iter().map(|s| From::from(s)).collect(),
-            refs: data.refs.into_iter().map(|s| From::from(s)).collect(),
+impl Into<Signature> for external_data::Signature {
+    fn into(self) -> Signature {
+        Signature {
+            span: self.span,
+            text: self.text,
+            ident_start: self.ident_start,
+            ident_end: self.ident_end,
+            defs: self.defs.into_iter().map(|s| s.into()).collect(),
+            refs: self.refs.into_iter().map(|s| s.into()).collect(),
         }
     }
 }
 
-#[derive(Debug, RustcEncodable)]
-pub struct JsonSigElement {
-    id: Id,
-    start: usize,
-    end: usize,
-}
-
-impl From<SigElement> for JsonSigElement {
-    fn from(data: SigElement) -> JsonSigElement {
-        JsonSigElement {
-            id: From::from(data.id),
-            start: data.start,
-            end: data.end,
+impl Into<SigElement> for data::SigElement {
+    fn into(self) -> SigElement {
+        SigElement {
+            id: id_from_def_id(self.id),
+            start: self.start,
+            end: self.end,
         }
     }
 }
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 581b23d5214..5e2b1df9d34 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -26,9 +26,12 @@
 
 #[macro_use] extern crate log;
 #[macro_use] extern crate syntax;
-extern crate serialize as rustc_serialize;
+extern crate rustc_serialize;
 extern crate syntax_pos;
 
+extern crate rls_data;
+extern crate rls_span;
+
 
 mod csv_dumper;
 mod json_api_dumper;