Repository: rust-analyzer/rust-analyzer
Pull request #1328 (2019-05-25 12:59:55)

Change TokenSource to iteration based
This PR change the `TokenSource` trait from random access to be an iteration based trait:
```rust

/// `TokenSource` abstracts the source of the tokens parser operates one.
///
/// Hopefully this will allow us to treat text and token trees in the same way!
pub trait TokenSource {
    fn current(&self) -> Token;

    /// Lookahead n token
    fn lookahead_nth(&self, n: usize) -> Token;

    /// bump cursor to next token
    fn bump(&mut self);

    /// Is the current token a specified keyword?
    fn is_keyword(&self, kw: &str) -> bool;
}

/// `TokenCursor` abstracts the cursor of `TokenSource` operates one.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct Token {
    /// What is the current token?
    pub kind: SyntaxKind,

    /// Is the current token joined to the next one (`> >` vs `>>`).
    pub is_jointed_to_next: bool,
}
```

Note that the refactoring based on this new trait will be separated to incoming PRs


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index a61aec4e12..9502fed45c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -29,26 +29,27 @@ name = "atty"
 version = "0.2.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "autocfg"
-version = "0.1.4"
+version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "backtrace"
-version = "0.3.20"
+version = "0.3.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
- "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-demangle 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -56,8 +57,8 @@ name = "backtrace-sys"
 version = "0.1.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -120,7 +121,7 @@ name = "cargo_metadata"
 version = "0.7.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -129,12 +130,12 @@ dependencies = [
 
 [[package]]
 name = "cc"
-version = "1.0.37"
+version = "1.0.36"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "cfg-if"
-version = "0.1.9"
+version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -197,8 +198,8 @@ name = "chrono"
 version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -229,7 +230,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -255,8 +256,8 @@ dependencies = [
  "clicolors-control 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "encode_unicode 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
- "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -287,7 +288,7 @@ version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -300,7 +301,7 @@ name = "crossbeam-utils"
 version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -308,7 +309,7 @@ name = "crossbeam-utils"
 version = "0.6.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -378,11 +379,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "error-chain"
-version = "0.12.1"
+version = "0.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "backtrace 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
- "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -390,7 +390,7 @@ name = "failure"
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "backtrace 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -402,7 +402,7 @@ dependencies = [
  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)",
- "synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -415,8 +415,8 @@ name = "filetime"
 version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -427,7 +427,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "flexi_logger"
-version = "0.11.5"
+version = "0.11.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -455,7 +455,7 @@ name = "fsevent-sys"
 version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -491,7 +491,7 @@ version = "0.2.0"
 dependencies = [
  "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "flexi_logger 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "flexi_logger 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "lsp-types 0.57.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -521,7 +521,7 @@ name = "heck"
 version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -552,7 +552,7 @@ dependencies = [
  "console 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "number_prefix 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -563,7 +563,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -571,7 +571,7 @@ name = "inotify-sys"
 version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -599,7 +599,7 @@ name = "iovec"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -630,7 +630,7 @@ version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -638,9 +638,9 @@ name = "jemalloc-sys"
 version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -649,7 +649,7 @@ version = "0.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -683,7 +683,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "libc"
-version = "0.2.55"
+version = "0.2.54"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -713,7 +713,7 @@ name = "log"
 version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -723,7 +723,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -753,14 +753,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "mio"
-version = "0.6.17"
+version = "0.6.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -775,7 +776,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "mio 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -795,8 +796,8 @@ name = "net2"
 version = "0.2.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -807,7 +808,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "notify"
-version = "4.0.12"
+version = "4.0.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -816,8 +817,8 @@ dependencies = [
  "fsevent-sys 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
- "mio 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -835,27 +836,23 @@ dependencies = [
 
 [[package]]
 name = "num-integer"
-version = "0.1.41"
+version = "0.1.39"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "num-traits"
-version = "0.2.8"
+version = "0.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
-]
 
 [[package]]
 name = "num_cpus"
 version = "1.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -863,7 +860,7 @@ name = "number_prefix"
 version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -921,7 +918,7 @@ name = "parking_lot_core"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -933,9 +930,9 @@ name = "parking_lot_core"
 version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1013,7 +1010,7 @@ dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1075,7 +1072,7 @@ version = "0.1.0"
 dependencies = [
  "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "flexi_logger 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "flexi_logger 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "indicatif 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "ra_batch 0.1.0",
@@ -1118,7 +1115,7 @@ dependencies = [
  "chalk-rust-ir 0.1.0 (git+https://github.com/flodiebold/chalk.git?branch=fuel)",
  "chalk-solve 0.1.0 (git+https://github.com/flodiebold/chalk.git?branch=fuel)",
  "ena 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "flexi_logger 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "flexi_logger 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "insta 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1169,7 +1166,7 @@ dependencies = [
  "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "flexi_logger 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "flexi_logger 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "gen_lsp_server 0.2.0",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "lsp-types 0.57.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1185,7 +1182,7 @@ dependencies = [
  "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
- "tempfile 3.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tempfile 3.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "test_utils 0.1.0",
  "thread_worker 0.1.0",
  "threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1278,7 +1275,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "notify 4.0.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "notify 4.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1290,8 +1287,8 @@ name = "rand"
 version = "0.6.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
+ "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1308,7 +1305,7 @@ name = "rand_chacha"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1346,7 +1343,7 @@ name = "rand_jitter"
 version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1358,7 +1355,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1369,7 +1366,7 @@ name = "rand_pcg"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1398,7 +1395,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1647,9 +1644,9 @@ name = "stacker"
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
- "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1675,7 +1672,7 @@ dependencies = [
 
 [[package]]
 name = "synstructure"
-version = "0.10.2"
+version = "0.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1686,11 +1683,11 @@ dependencies = [
 
 [[package]]
 name = "tempfile"
-version = "3.0.8"
+version = "3.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1703,7 +1700,7 @@ version = "0.11.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1733,7 +1730,7 @@ name = "termion"
 version = "1.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1744,7 +1741,7 @@ name = "termios"
 version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1802,7 +1799,7 @@ name = "time"
 version = "0.1.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1903,7 +1900,7 @@ dependencies = [
 
 [[package]]
 name = "unicode-segmentation"
-version = "1.3.0"
+version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -2028,8 +2025,8 @@ dependencies = [
 "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
 "checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71"
 "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
-"checksum autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0e49efa51329a5fd37e7c79db4621af617cd4e3e5bc224939808d076077077bf"
-"checksum backtrace 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "45934a579eff9fd0ff637ac376a4bd134f47f8fc603f0b211d696b54d61e35f1"
+"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799"
+"checksum backtrace 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f106c02a3604afcdc0df5d36cc47b44b55917dbaf3d808f71c163a0ddba64637"
 "checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6"
 "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
 "checksum bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e84c238982c4b1e1ee668d136c510c67a13465279c0cb367ea6baf6310620a80"
@@ -2040,8 +2037,8 @@ dependencies = [
 "checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
 "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
 "checksum cargo_metadata 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "178d62b240c34223f265a4c1e275e37d62da163d421fc8d7f7e3ee340f803c57"
-"checksum cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "39f75544d7bbaf57560d2168f28fd649ff9c76153874db88bdbdfd839b1a7e7d"
-"checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33"
+"checksum cc 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)" = "a0c56216487bb80eec9c4516337b2588a4f2a2290d72a1416d930e4dcdb0c90d"
+"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4"
 "checksum chalk-engine 0.9.0 (git+https://github.com/flodiebold/chalk.git?branch=fuel)" = "<none>"
 "checksum chalk-ir 0.1.0 (git+https://github.com/flodiebold/chalk.git?branch=fuel)" = "<none>"
 "checksum chalk-macros 0.1.1 (git+https://github.com/flodiebold/chalk.git?branch=fuel)" = "<none>"
@@ -2069,13 +2066,13 @@ dependencies = [
 "checksum ena 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "25b4e5febb25f08c49f1b07dc33a182729a6b21edfb562b5aef95f78e0dbe5bb"
 "checksum ena 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f56c93cc076508c549d9bb747f79aa9b4eb098be7b8cad8830c3137ef52d1e00"
 "checksum encode_unicode 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "90b2c9496c001e8cb61827acdefad780795c42264c137744cae6f7d9e3450abd"
-"checksum error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9"
+"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02"
 "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
 "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
 "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
 "checksum filetime 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2f8c63033fcba1f51ef744505b3cad42510432b904c062afa67ad7ece008429d"
 "checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
-"checksum flexi_logger 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ce5e9a2e15c8eb8dcf35565b92b9548e4787b9990528f1ef49d09e20bbeee5a7"
+"checksum flexi_logger 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)" = "73de04baa435682b03677bb28f7b3e9d72b0489a551da5ba413c9b29f7979a19"
 "checksum fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674"
 "checksum fsevent 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6"
 "checksum fsevent-sys 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0"
@@ -2106,7 +2103,7 @@ dependencies = [
 "checksum lalrpop-intern 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cc4fd87be4a815fd373e02773983940f0d75fb26fde8c098e9e45f7af03154c0"
 "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
 "checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
-"checksum libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)" = "42914d39aad277d9e176efbdad68acb1d5443ab65afe0e0e4f0d49352a950880"
+"checksum libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)" = "c6785aa7dd976f5fbf3b71cfd9cd49d7f783c1ff565a858d71031c6c313aa5c6"
 "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83"
 "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
 "checksum lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff"
@@ -2116,15 +2113,15 @@ dependencies = [
 "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
 "checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39"
 "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
-"checksum mio 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)" = "049ba5ca2b63e837adeee724aa9e36b408ed593529dcc802aa96ca14bd329bdf"
+"checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432"
 "checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40"
 "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
 "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
 "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
-"checksum notify 4.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "3572d71f13ea8ed41867accd971fd564aa75934cf7a1fae03ddb8c74a8a49943"
+"checksum notify 4.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ceb1a496a81dd6125f68ce772b41b83efe89a54d21768ed6d0c33c95832604e6"
 "checksum num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "eafd0b45c5537c3ba526f79d3e75120036502bebacbb3f3220914067ce39dbf2"
-"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
-"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
+"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
+"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
 "checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba"
 "checksum number_prefix 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dbf9993e59c894e3c08aa1c2712914e9e6bf1fcbfc6bef283e2183df345a4fee"
 "checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
@@ -2193,8 +2190,8 @@ dependencies = [
 "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
 "checksum superslice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f"
 "checksum syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)" = "a1393e4a97a19c01e900df2aec855a29f71cf02c402e2f443b8d2747c25c5dbe"
-"checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f"
-"checksum tempfile 3.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7dc4738f2e68ed2855de5ac9cdbe05c9216773ecde4739b2f095002ab03a13ef"
+"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015"
+"checksum tempfile 3.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b86c784c88d98c801132806dadd3819ed29d8600836c4088e855cdf3e178ed8a"
 "checksum tera 0.11.20 (registry+https://github.com/rust-lang/crates.io-index)" = "4b505279e19d8f7d24b1a9dc58327c9c36174b1a2c7ebdeac70792d017cb64f3"
 "checksum teraron 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0d89ad4617d1dec55331067fadaa041e813479e1779616f3d3ce9308bf46184e"
 "checksum termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dde0593aeb8d47accea5392b39350015b5eccb12c0d98044d856983d89548dea"
@@ -2216,7 +2213,7 @@ dependencies = [
 "checksum unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a84e5511b2a947f3ae965dcb29b13b7b1691b6e7332cf5dbc1744138d5acb7f6"
 "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
 "checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426"
-"checksum unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9"
+"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1"
 "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
 "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
 "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
diff --git a/crates/ra_cli/src/main.rs b/crates/ra_cli/src/main.rs
index 93aba4c704..f11d0e6bd4 100644
--- a/crates/ra_cli/src/main.rs
+++ b/crates/ra_cli/src/main.rs
@@ -3,7 +3,7 @@ mod analysis_stats;
 use std::io::Read;
 
 use clap::{App, Arg, SubCommand};
-use ra_ide_api::{file_structure, Analysis};
+use ra_ide_api::file_structure;
 use ra_syntax::{SourceFile, TreeArc, AstNode};
 use flexi_logger::Logger;
 use ra_prof::profile;
@@ -16,7 +16,6 @@ fn main() -> Result<()> {
         .setting(clap::AppSettings::SubcommandRequiredElseHelp)
         .subcommand(SubCommand::with_name("parse").arg(Arg::with_name("no-dump").long("--no-dump")))
         .subcommand(SubCommand::with_name("symbols"))
-        .subcommand(SubCommand::with_name("highlight"))
         .subcommand(
             SubCommand::with_name("analysis-stats")
                 .arg(Arg::with_name("verbose").short("v").long("verbose"))
@@ -39,11 +38,6 @@ fn main() -> Result<()> {
                 println!("{:?}", s);
             }
         }
-        ("highlight", _) => {
-            let (analysis, file_id) = Analysis::from_single_file(read_stdin()?);
-            let html = analysis.highlight_as_html(file_id).unwrap();
-            println!("{}", html);
-        }
         ("analysis-stats", Some(matches)) => {
             let verbose = matches.is_present("verbose");
             let path = matches.value_of("path").unwrap_or("");
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs
index 5e5905f156..e027eedd9c 100644
--- a/crates/ra_hir/src/adt.rs
+++ b/crates/ra_hir/src/adt.rs
@@ -10,7 +10,7 @@ use ra_syntax::{
 };
 
 use crate::{
-    Name, AsName, Struct, Union, Enum, EnumVariant, Crate,
+    Name, AsName, Struct, Enum, EnumVariant, Crate,
     HirDatabase, HirFileId, StructField, FieldSource,
     type_ref::TypeRef, DefDatabase,
 };
@@ -18,16 +18,14 @@ use crate::{
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
 pub enum AdtDef {
     Struct(Struct),
-    Union(Union),
     Enum(Enum),
 }
-impl_froms!(AdtDef: Struct, Union, Enum);
+impl_froms!(AdtDef: Struct, Enum);
 
 impl AdtDef {
     pub(crate) fn krate(self, db: &impl HirDatabase) -> Option<Crate> {
         match self {
             AdtDef::Struct(s) => s.module(db),
-            AdtDef::Union(s) => s.module(db),
             AdtDef::Enum(e) => e.module(db),
         }
         .krate(db)
@@ -40,7 +38,6 @@ impl Struct {
     }
 }
 
-/// Note that we use `StructData` for unions as well!
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct StructData {
     pub(crate) name: Option<Name>,
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model_api.rs
similarity index 57%
rename from crates/ra_hir/src/code_model.rs
rename to crates/ra_hir/src/code_model_api.rs
index 49030ce676..0c4a80bfaa 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model_api.rs
@@ -1,15 +1,15 @@
 use std::sync::Arc;
 
-use ra_db::{CrateId, SourceRootId, Edition, FileId};
-use ra_syntax::{ast::{self, NameOwner, TypeAscriptionOwner}, TreeArc};
+use ra_db::{CrateId, SourceRootId, Edition};
+use ra_syntax::{ast::self, TreeArc};
 
 use crate::{
-    Name, AsName, AstId, Ty, HirFileId, Either,
+    Name, Ty, HirFileId, Either,
     HirDatabase, DefDatabase,
     type_ref::TypeRef,
     nameres::{ModuleScope, Namespace, ImportId, CrateModuleId},
     expr::{Body, BodySourceMap, validation::ExprValidator},
-    ty::{TraitRef, InferenceResult},
+    ty::{ TraitRef, InferenceResult},
     adt::{EnumVariantId, StructFieldId, VariantDef},
     generics::HasGenericParams,
     docs::{Documentation, Docs, docs_from_ast},
@@ -18,7 +18,6 @@ use crate::{
     resolve::Resolver,
     diagnostics::{DiagnosticSink},
     traits::{TraitItem, TraitData},
-    type_ref::Mutability,
 };
 
 /// hir::Crate describes a single crate. It's the main interface with which
@@ -36,28 +35,19 @@ pub struct CrateDependency {
 }
 
 impl Crate {
-    pub fn crate_id(self) -> CrateId {
+    pub fn crate_id(&self) -> CrateId {
         self.crate_id
     }
 
-    pub fn dependencies(self, db: &impl DefDatabase) -> Vec<CrateDependency> {
-        db.crate_graph()
-            .dependencies(self.crate_id)
-            .map(|dep| {
-                let krate = Crate { crate_id: dep.crate_id() };
-                let name = dep.as_name();
-                CrateDependency { krate, name }
-            })
-            .collect()
+    pub fn dependencies(&self, db: &impl DefDatabase) -> Vec<CrateDependency> {
+        self.dependencies_impl(db)
     }
 
-    pub fn root_module(self, db: &impl DefDatabase) -> Option<Module> {
-        let module_id = db.crate_def_map(self).root();
-        let module = Module { krate: self, module_id };
-        Some(module)
+    pub fn root_module(&self, db: &impl DefDatabase) -> Option<Module> {
+        self.root_module_impl(db)
     }
 
-    pub fn edition(self, db: &impl DefDatabase) -> Edition {
+    pub fn edition(&self, db: &impl DefDatabase) -> Edition {
         let crate_graph = db.crate_graph();
         crate_graph.edition(self.crate_id)
     }
@@ -81,7 +71,6 @@ pub enum ModuleDef {
     Module(Module),
     Function(Function),
     Struct(Struct),
-    Union(Union),
     Enum(Enum),
     // Can't be directly declared, but can be imported.
     EnumVariant(EnumVariant),
@@ -94,7 +83,6 @@ impl_froms!(
     ModuleDef: Module,
     Function,
     Struct,
-    Union,
     Enum,
     EnumVariant,
     Const,
@@ -108,66 +96,29 @@ pub enum ModuleSource {
     Module(TreeArc<ast::Module>),
 }
 
-impl ModuleSource {
-    pub(crate) fn new(
-        db: &impl DefDatabase,
-        file_id: Option<FileId>,
-        decl_id: Option<AstId<ast::Module>>,
-    ) -> ModuleSource {
-        match (file_id, decl_id) {
-            (Some(file_id), _) => {
-                let source_file = db.parse(file_id);
-                ModuleSource::SourceFile(source_file)
-            }
-            (None, Some(item_id)) => {
-                let module = item_id.to_node(db);
-                assert!(module.item_list().is_some(), "expected inline module");
-                ModuleSource::Module(module.to_owned())
-            }
-            (None, None) => panic!(),
-        }
-    }
-}
-
 impl Module {
     /// Name of this module.
-    pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
-        let def_map = db.crate_def_map(self.krate);
-        let parent = def_map[self.module_id].parent?;
-        def_map[parent].children.iter().find_map(|(name, module_id)| {
-            if *module_id == self.module_id {
-                Some(name.clone())
-            } else {
-                None
-            }
-        })
+    pub fn name(&self, db: &impl HirDatabase) -> Option<Name> {
+        self.name_impl(db)
     }
 
     /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items.
-    pub fn definition_source(self, db: &impl DefDatabase) -> (HirFileId, ModuleSource) {
-        let def_map = db.crate_def_map(self.krate);
-        let decl_id = def_map[self.module_id].declaration;
-        let file_id = def_map[self.module_id].definition;
-        let module_source = ModuleSource::new(db, file_id, decl_id);
-        let file_id = file_id.map(HirFileId::from).unwrap_or_else(|| decl_id.unwrap().file_id());
-        (file_id, module_source)
+    pub fn definition_source(&self, db: &impl DefDatabase) -> (HirFileId, ModuleSource) {
+        self.definition_source_impl(db)
     }
 
     /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`.
     /// `None` for the crate root.
     pub fn declaration_source(
-        self,
+        &self,
         db: &impl HirDatabase,
     ) -> Option<(HirFileId, TreeArc<ast::Module>)> {
-        let def_map = db.crate_def_map(self.krate);
-        let decl = def_map[self.module_id].declaration?;
-        let ast = decl.to_node(db);
-        Some((decl.file_id(), ast))
+        self.declaration_source_impl(db)
     }
 
     /// Returns the syntax of the last path segment corresponding to this import
     pub fn import_source(
-        self,
+        &self,
         db: &impl HirDatabase,
         import: ImportId,
     ) -> Either<TreeArc<ast::UseTree>, TreeArc<ast::ExternCrateItem>> {
@@ -177,44 +128,33 @@ impl Module {
     }
 
     /// Returns the crate this module is part of.
-    pub fn krate(self, _db: &impl DefDatabase) -> Option<Crate> {
+    pub fn krate(&self, _db: &impl DefDatabase) -> Option<Crate> {
         Some(self.krate)
     }
 
     /// Topmost parent of this module. Every module has a `crate_root`, but some
     /// might be missing `krate`. This can happen if a module's file is not included
     /// in the module tree of any target in `Cargo.toml`.
-    pub fn crate_root(self, db: &impl DefDatabase) -> Module {
-        let def_map = db.crate_def_map(self.krate);
-        self.with_module_id(def_map.root())
+    pub fn crate_root(&self, db: &impl DefDatabase) -> Module {
+        self.crate_root_impl(db)
     }
 
     /// Finds a child module with the specified name.
-    pub fn child(self, db: &impl HirDatabase, name: &Name) -> Option<Module> {
-        let def_map = db.crate_def_map(self.krate);
-        let child_id = def_map[self.module_id].children.get(name)?;
-        Some(self.with_module_id(*child_id))
+    pub fn child(&self, db: &impl HirDatabase, name: &Name) -> Option<Module> {
+        self.child_impl(db, name)
     }
 
     /// Iterates over all child modules.
-    pub fn children(self, db: &impl DefDatabase) -> impl Iterator<Item = Module> {
-        let def_map = db.crate_def_map(self.krate);
-        let children = def_map[self.module_id]
-            .children
-            .iter()
-            .map(|(_, module_id)| self.with_module_id(*module_id))
-            .collect::<Vec<_>>();
-        children.into_iter()
+    pub fn children(&self, db: &impl DefDatabase) -> impl Iterator<Item = Module> {
+        self.children_impl(db)
     }
 
     /// Finds a parent module.
-    pub fn parent(self, db: &impl DefDatabase) -> Option<Module> {
-        let def_map = db.crate_def_map(self.krate);
-        let parent_id = def_map[self.module_id].parent?;
-        Some(self.with_module_id(parent_id))
+    pub fn parent(&self, db: &impl DefDatabase) -> Option<Module> {
+        self.parent_impl(db)
     }
 
-    pub fn path_to_root(self, db: &impl HirDatabase) -> Vec<Module> {
+    pub fn path_to_root(&self, db: &impl HirDatabase) -> Vec<Module> {
         let mut res = vec![self.clone()];
         let mut curr = self.clone();
         while let Some(next) = curr.parent(db) {
@@ -225,11 +165,11 @@ impl Module {
     }
 
     /// Returns a `ModuleScope`: a set of items, visible in this module.
-    pub fn scope(self, db: &impl HirDatabase) -> ModuleScope {
+    pub fn scope(&self, db: &impl HirDatabase) -> ModuleScope {
         db.crate_def_map(self.krate)[self.module_id].scope.clone()
     }
 
-    pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) {
+    pub fn diagnostics(&self, db: &impl HirDatabase, sink: &mut DiagnosticSink) {
         db.crate_def_map(self.krate).add_diagnostics(db, self.module_id, sink);
         for decl in self.declarations(db) {
             match decl {
@@ -249,7 +189,7 @@ impl Module {
         }
     }
 
-    pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver {
+    pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver {
         let def_map = db.crate_def_map(self.krate);
         Resolver::default().push_module_scope(def_map, self.module_id)
     }
@@ -274,10 +214,6 @@ impl Module {
             .map(|(impl_id, _)| ImplBlock::from_id(self, impl_id))
             .collect()
     }
-
-    fn with_module_id(&self, module_id: CrateModuleId) -> Module {
-        Module { module_id, krate: self.krate }
-    }
 }
 
 impl Docs for Module {
@@ -331,49 +267,49 @@ pub struct Struct {
 }
 
 impl Struct {
-    pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::StructDef>) {
+    pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::StructDef>) {
         self.id.source(db)
     }
 
-    pub fn module(self, db: &impl HirDatabase) -> Module {
+    pub fn module(&self, db: &impl HirDatabase) -> Module {
         self.id.module(db)
     }
 
-    pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
-        db.struct_data(self).name.clone()
+    pub fn name(&self, db: &impl HirDatabase) -> Option<Name> {
+        db.struct_data(*self).name.clone()
     }
 
-    pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
-        db.struct_data(self)
+    pub fn fields(&self, db: &impl HirDatabase) -> Vec<StructField> {
+        db.struct_data(*self)
             .variant_data
             .fields()
             .into_iter()
             .flat_map(|it| it.iter())
-            .map(|(id, _)| StructField { parent: self.into(), id })
+            .map(|(id, _)| StructField { parent: (*self).into(), id })
             .collect()
     }
 
-    pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
-        db.struct_data(self)
+    pub fn field(&self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
+        db.struct_data(*self)
             .variant_data
             .fields()
             .into_iter()
             .flat_map(|it| it.iter())
             .find(|(_id, data)| data.name == *name)
-            .map(|(id, _)| StructField { parent: self.into(), id })
+            .map(|(id, _)| StructField { parent: (*self).into(), id })
     }
 
-    pub fn ty(self, db: &impl HirDatabase) -> Ty {
-        db.type_for_def(self.into(), Namespace::Types)
+    pub fn ty(&self, db: &impl HirDatabase) -> Ty {
+        db.type_for_def((*self).into(), Namespace::Types)
     }
 
-    pub fn constructor_ty(self, db: &impl HirDatabase) -> Ty {
-        db.type_for_def(self.into(), Namespace::Values)
+    pub fn constructor_ty(&self, db: &impl HirDatabase) -> Ty {
+        db.type_for_def((*self).into(), Namespace::Values)
     }
 
     // FIXME move to a more general type
     /// Builds a resolver for type references inside this struct.
-    pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver {
+    pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver {
         // take the outer scope...
         let r = self.module(db).resolver(db);
         // ...and add generic params, if present
@@ -389,79 +325,47 @@ impl Docs for Struct {
     }
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct Union {
-    pub(crate) id: StructId,
-}
-
-impl Union {
-    pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::StructDef>) {
-        self.id.source(db)
-    }
-
-    pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
-        db.struct_data(Struct { id: self.id }).name.clone()
-    }
-
-    pub fn module(self, db: &impl HirDatabase) -> Module {
-        self.id.module(db)
-    }
-
-    // FIXME move to a more general type
-    /// Builds a resolver for type references inside this union.
-    pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver {
-        // take the outer scope...
-        let r = self.module(db).resolver(db);
-        // ...and add generic params, if present
-        let p = self.generic_params(db);
-        let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r };
-        r
-    }
-}
-
-impl Docs for Union {
-    fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
-        docs_from_ast(&*self.source(db).1)
-    }
-}
-
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub struct Enum {
     pub(crate) id: EnumId,
 }
 
 impl Enum {
-    pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::EnumDef>) {
+    pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::EnumDef>) {
         self.id.source(db)
     }
 
-    pub fn module(self, db: &impl HirDatabase) -> Module {
+    pub fn module(&self, db: &impl HirDatabase) -> Module {
         self.id.module(db)
     }
 
-    pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
-        db.enum_data(self).name.clone()
+    pub fn name(&self, db: &impl HirDatabase) -> Option<Name> {
+        db.enum_data(*self).name.clone()
     }
 
-    pub fn variants(self, db: &impl DefDatabase) -> Vec<EnumVariant> {
-        db.enum_data(self).variants.iter().map(|(id, _)| EnumVariant { parent: self, id }).collect()
+    pub fn variants(&self, db: &impl DefDatabase) -> Vec<EnumVariant> {
+        db.enum_data(*self)
+            .variants
+            .iter()
+            .map(|(id, _)| EnumVariant { parent: *self, id })
+            .collect()
     }
 
-    pub fn variant(self, db: &impl DefDatabase, name: &Name) -> Option<EnumVariant> {
-        db.enum_data(self)
+    pub fn variant(&self, db: &impl DefDatabase, name: &Name) -> Option<EnumVariant> {
+        db.enum_data(*self)
             .variants
             .iter()
             .find(|(_id, data)| data.name.as_ref() == Some(name))
-            .map(|(id, _)| EnumVariant { parent: self, id })
+            .map(|(id, _)| EnumVariant { parent: *self, id })
     }
 
-    pub fn ty(self, db: &impl HirDatabase) -> Ty {
-        db.type_for_def(self.into(), Namespace::Types)
+    pub fn ty(&self, db: &impl HirDatabase) -> Ty {
+        db.type_for_def((*self).into(), Namespace::Types)
     }
 
     // FIXME: move to a more general type
     /// Builds a resolver for type references inside this struct.
-    pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver {
+    pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver {
         // take the outer scope...
         let r = self.module(db).resolver(db);
         // ...and add generic params, if present
@@ -534,16 +438,16 @@ pub enum DefWithBody {
 impl_froms!(DefWithBody: Function, Const, Static);
 
 impl DefWithBody {
-    pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
-        db.infer(self)
+    pub fn infer(&self, db: &impl HirDatabase) -> Arc<InferenceResult> {
+        db.infer(*self)
     }
 
-    pub fn body(self, db: &impl HirDatabase) -> Arc<Body> {
-        db.body_hir(self)
+    pub fn body(&self, db: &impl HirDatabase) -> Arc<Body> {
+        db.body_hir(*self)
     }
 
-    pub fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
-        db.body_with_source_map(self).1
+    pub fn body_source_map(&self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
+        db.body_with_source_map(*self).1
     }
 
     /// Builds a resolver for code inside this item.
@@ -573,44 +477,6 @@ pub struct FnSignature {
 }
 
 impl FnSignature {
-    pub(crate) fn fn_signature_query(db: &impl DefDatabase, func: Function) -> Arc<FnSignature> {
-        let (_, node) = func.source(db);
-        let name = node.name().map(|n| n.as_name()).unwrap_or_else(Name::missing);
-        let mut params = Vec::new();
-        let mut has_self_param = false;
-        if let Some(param_list) = node.param_list() {
-            if let Some(self_param) = param_list.self_param() {
-                let self_type = if let Some(type_ref) = self_param.ascribed_type() {
-                    TypeRef::from_ast(type_ref)
-                } else {
-                    let self_type = TypeRef::Path(Name::self_type().into());
-                    match self_param.kind() {
-                        ast::SelfParamKind::Owned => self_type,
-                        ast::SelfParamKind::Ref => {
-                            TypeRef::Reference(Box::new(self_type), Mutability::Shared)
-                        }
-                        ast::SelfParamKind::MutRef => {
-                            TypeRef::Reference(Box::new(self_type), Mutability::Mut)
-                        }
-                    }
-                };
-                params.push(self_type);
-                has_self_param = true;
-            }
-            for param in param_list.params() {
-                let type_ref = TypeRef::from_ast_opt(param.ascribed_type());
-                params.push(type_ref);
-            }
-        }
-        let ret_type = if let Some(type_ref) = node.ret_type().and_then(|rt| rt.type_ref()) {
-            TypeRef::from_ast(type_ref)
-        } else {
-            TypeRef::unit()
-        };
-
-        let sig = FnSignature { name, params, ret_type, has_self_param };
-        Arc::new(sig)
-    }
     pub fn name(&self) -> &Name {
         &self.name
     }
@@ -631,50 +497,50 @@ impl FnSignature {
 }
 
 impl Function {
-    pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::FnDef>) {
+    pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::FnDef>) {
         self.id.source(db)
     }
 
-    pub fn module(self, db: &impl DefDatabase) -> Module {
+    pub fn module(&self, db: &impl DefDatabase) -> Module {
         self.id.module(db)
     }
 
-    pub fn name(self, db: &impl HirDatabase) -> Name {
+    pub fn name(&self, db: &impl HirDatabase) -> Name {
         self.signature(db).name.clone()
     }
 
-    pub(crate) fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
-        db.body_with_source_map(self.into()).1
+    pub(crate) fn body_source_map(&self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
+        db.body_with_source_map((*self).into()).1
     }
 
-    pub fn body(self, db: &impl HirDatabase) -> Arc<Body> {
-        db.body_hir(self.into())
+    pub fn body(&self, db: &impl HirDatabase) -> Arc<Body> {
+        db.body_hir((*self).into())
     }
 
-    pub fn ty(self, db: &impl HirDatabase) -> Ty {
-        db.type_for_def(self.into(), Namespace::Values)
+    pub fn ty(&self, db: &impl HirDatabase) -> Ty {
+        db.type_for_def((*self).into(), Namespace::Values)
     }
 
-    pub fn signature(self, db: &impl HirDatabase) -> Arc<FnSignature> {
-        db.fn_signature(self)
+    pub fn signature(&self, db: &impl HirDatabase) -> Arc<FnSignature> {
+        db.fn_signature(*self)
     }
 
-    pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
-        db.infer(self.into())
+    pub fn infer(&self, db: &impl HirDatabase) -> Arc<InferenceResult> {
+        db.infer((*self).into())
     }
 
     /// The containing impl block, if this is a method.
-    pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> {
+    pub fn impl_block(&self, db: &impl DefDatabase) -> Option<ImplBlock> {
         let module_impls = db.impls_in_module(self.module(db));
-        ImplBlock::containing(module_impls, self.into())
+        ImplBlock::containing(module_impls, (*self).into())
     }
 
     /// The containing trait, if this is a trait method definition.
-    pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> {
-        db.trait_items_index(self.module(db)).get_parent_trait(self.into())
+    pub fn parent_trait(&self, db: &impl DefDatabase) -> Option<Trait> {
+        db.trait_items_index(self.module(db)).get_parent_trait((*self).into())
     }
 
-    pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
+    pub fn container(&self, db: &impl DefDatabase) -> Option<Container> {
         if let Some(impl_block) = self.impl_block(db) {
             Some(impl_block.into())
         } else if let Some(trait_) = self.parent_trait(db) {
@@ -686,7 +552,7 @@ impl Function {
 
     // FIXME: move to a more general type for 'body-having' items
     /// Builds a resolver for code inside this item.
-    pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver {
+    pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver {
         // take the outer scope...
         let r = self.container(db).map_or_else(|| self.module(db).resolver(db), |c| c.resolver(db));
         // ...and add generic params, if present
@@ -695,10 +561,10 @@ impl Function {
         r
     }
 
-    pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) {
+    pub fn diagnostics(&self, db: &impl HirDatabase, sink: &mut DiagnosticSink) {
         let infer = self.infer(db);
-        infer.add_diagnostics(db, self, sink);
-        let mut validator = ExprValidator::new(self, infer, sink);
+        infer.add_diagnostics(db, *self, sink);
+        let mut validator = ExprValidator::new(*self, infer, sink);
         validator.validate_body(db);
     }
 }
@@ -715,31 +581,31 @@ pub struct Const {
 }
 
 impl Const {
-    pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::ConstDef>) {
+    pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::ConstDef>) {
         self.id.source(db)
     }
 
-    pub fn module(self, db: &impl DefDatabase) -> Module {
+    pub fn module(&self, db: &impl DefDatabase) -> Module {
         self.id.module(db)
     }
 
-    pub fn signature(self, db: &impl HirDatabase) -> Arc<ConstSignature> {
-        db.const_signature(self)
+    pub fn signature(&self, db: &impl HirDatabase) -> Arc<ConstSignature> {
+        db.const_signature(*self)
     }
 
-    pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
-        db.infer(self.into())
+    pub fn infer(&self, db: &impl HirDatabase) -> Arc<InferenceResult> {
+        db.infer((*self).into())
     }
 
     /// The containing impl block, if this is a method.
-    pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> {
+    pub fn impl_block(&self, db: &impl DefDatabase) -> Option<ImplBlock> {
         let module_impls = db.impls_in_module(self.module(db));
-        ImplBlock::containing(module_impls, self.into())
+        ImplBlock::containing(module_impls, (*self).into())
     }
 
     // FIXME: move to a more general type for 'body-having' items
     /// Builds a resolver for code inside this item.
-    pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver {
+    pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver {
         // take the outer scope...
         let r = self
             .impl_block(db)
@@ -770,29 +636,6 @@ impl ConstSignature {
     pub fn type_ref(&self) -> &TypeRef {
         &self.type_ref
     }
-
-    pub(crate) fn const_signature_query(
-        db: &impl DefDatabase,
-        konst: Const,
-    ) -> Arc<ConstSignature> {
-        let (_, node) = konst.source(db);
-        const_signature_for(&*node)
-    }
-
-    pub(crate) fn static_signature_query(
-        db: &impl DefDatabase,
-        konst: Static,
-    ) -> Arc<ConstSignature> {
-        let (_, node) = konst.source(db);
-        const_signature_for(&*node)
-    }
-}
-
-fn const_signature_for<N: NameOwner + TypeAscriptionOwner>(node: &N) -> Arc<ConstSignature> {
-    let name = node.name().map(|n| n.as_name()).unwrap_or_else(Name::missing);
-    let type_ref = TypeRef::from_ast_opt(node.ascribed_type());
-    let sig = ConstSignature { name, type_ref };
-    Arc::new(sig)
 }
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -801,26 +644,26 @@ pub struct Static {
 }
 
 impl Static {
-    pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::StaticDef>) {
+    pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::StaticDef>) {
         self.id.source(db)
     }
 
-    pub fn module(self, db: &impl DefDatabase) -> Module {
+    pub fn module(&self, db: &impl DefDatabase) -> Module {
         self.id.module(db)
     }
 
-    pub fn signature(self, db: &impl HirDatabase) -> Arc<ConstSignature> {
-        db.static_signature(self)
+    pub fn signature(&self, db: &impl HirDatabase) -> Arc<ConstSignature> {
+        db.static_signature(*self)
     }
 
     /// Builds a resolver for code inside this item.
-    pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver {
+    pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver {
         // take the outer scope...
         self.module(db).resolver(db)
     }
 
-    pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
-        db.infer(self.into())
+    pub fn infer(&self, db: &impl HirDatabase) -> Arc<InferenceResult> {
+        db.infer((*self).into())
     }
 }
 
@@ -836,11 +679,11 @@ pub struct Trait {
 }
 
 impl Trait {
-    pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::TraitDef>) {
+    pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::TraitDef>) {
         self.id.source(db)
     }
 
-    pub fn module(self, db: &impl DefDatabase) -> Module {
+    pub fn module(&self, db: &impl DefDatabase) -> Module {
         self.id.module(db)
     }
 
@@ -864,7 +707,7 @@ impl Trait {
         self.trait_data(db).is_auto()
     }
 
-    pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver {
+    pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver {
         let r = self.module(db).resolver(db);
         // add generic params, if present
         let p = self.generic_params(db);
@@ -885,26 +728,26 @@ pub struct TypeAlias {
 }
 
 impl TypeAlias {
-    pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::TypeAliasDef>) {
+    pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::TypeAliasDef>) {
         self.id.source(db)
     }
 
-    pub fn module(self, db: &impl DefDatabase) -> Module {
+    pub fn module(&self, db: &impl DefDatabase) -> Module {
         self.id.module(db)
     }
 
     /// The containing impl block, if this is a method.
-    pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> {
+    pub fn impl_block(&self, db: &impl DefDatabase) -> Option<ImplBlock> {
         let module_impls = db.impls_in_module(self.module(db));
-        ImplBlock::containing(module_impls, self.into())
+        ImplBlock::containing(module_impls, (*self).into())
     }
 
     /// The containing trait, if this is a trait method definition.
-    pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> {
-        db.trait_items_index(self.module(db)).get_parent_trait(self.into())
+    pub fn parent_trait(&self, db: &impl DefDatabase) -> Option<Trait> {
+        db.trait_items_index(self.module(db)).get_parent_trait((*self).into())
     }
 
-    pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
+    pub fn container(&self, db: &impl DefDatabase) -> Option<Container> {
         if let Some(impl_block) = self.impl_block(db) {
             Some(impl_block.into())
         } else if let Some(trait_) = self.parent_trait(db) {
@@ -919,7 +762,7 @@ impl TypeAlias {
     }
 
     /// Builds a resolver for the type references in this type alias.
-    pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver {
+    pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver {
         // take the outer scope...
         let r = self
             .impl_block(db)
@@ -945,7 +788,7 @@ pub enum Container {
 impl_froms!(Container: Trait, ImplBlock);
 
 impl Container {
-    pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver {
+    pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver {
         match self {
             Container::Trait(trait_) => trait_.resolver(db),
             Container::ImplBlock(impl_block) => impl_block.resolver(db),
diff --git a/crates/ra_hir/src/code_model_impl.rs b/crates/ra_hir/src/code_model_impl.rs
new file mode 100644
index 0000000000..24df9a1138
--- /dev/null
+++ b/crates/ra_hir/src/code_model_impl.rs
@@ -0,0 +1,4 @@
+mod krate; // `crate` is invalid ident :(
+mod konst; // `const` is invalid ident :(
+mod module;
+pub(crate) mod function;
diff --git a/crates/ra_hir/src/code_model_impl/function.rs b/crates/ra_hir/src/code_model_impl/function.rs
new file mode 100644
index 0000000000..f8bd0f7847
--- /dev/null
+++ b/crates/ra_hir/src/code_model_impl/function.rs
@@ -0,0 +1,50 @@
+use std::sync::Arc;
+
+use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
+
+use crate::{
+    Name, AsName, Function, FnSignature,
+    type_ref::{TypeRef, Mutability},
+    DefDatabase,
+};
+
+impl FnSignature {
+    pub(crate) fn fn_signature_query(db: &impl DefDatabase, func: Function) -> Arc<FnSignature> {
+        let (_, node) = func.source(db);
+        let name = node.name().map(|n| n.as_name()).unwrap_or_else(Name::missing);
+        let mut params = Vec::new();
+        let mut has_self_param = false;
+        if let Some(param_list) = node.param_list() {
+            if let Some(self_param) = param_list.self_param() {
+                let self_type = if let Some(type_ref) = self_param.ascribed_type() {
+                    TypeRef::from_ast(type_ref)
+                } else {
+                    let self_type = TypeRef::Path(Name::self_type().into());
+                    match self_param.kind() {
+                        ast::SelfParamKind::Owned => self_type,
+                        ast::SelfParamKind::Ref => {
+                            TypeRef::Reference(Box::new(self_type), Mutability::Shared)
+                        }
+                        ast::SelfParamKind::MutRef => {
+                            TypeRef::Reference(Box::new(self_type), Mutability::Mut)
+                        }
+                    }
+                };
+                params.push(self_type);
+                has_self_param = true;
+            }
+            for param in param_list.params() {
+                let type_ref = TypeRef::from_ast_opt(param.ascribed_type());
+                params.push(type_ref);
+            }
+        }
+        let ret_type = if let Some(type_ref) = node.ret_type().and_then(|rt| rt.type_ref()) {
+            TypeRef::from_ast(type_ref)
+        } else {
+            TypeRef::unit()
+        };
+
+        let sig = FnSignature { name, params, ret_type, has_self_param };
+        Arc::new(sig)
+    }
+}
diff --git a/crates/ra_hir/src/code_model_impl/konst.rs b/crates/ra_hir/src/code_model_impl/konst.rs
new file mode 100644
index 0000000000..db4e5ce5cd
--- /dev/null
+++ b/crates/ra_hir/src/code_model_impl/konst.rs
@@ -0,0 +1,34 @@
+use std::sync::Arc;
+
+use ra_syntax::ast::{NameOwner, TypeAscriptionOwner};
+
+use crate::{
+    Name, AsName, Const, ConstSignature, Static,
+    type_ref::{TypeRef},
+    DefDatabase,
+};
+
+fn const_signature_for<N: NameOwner + TypeAscriptionOwner>(node: &N) -> Arc<ConstSignature> {
+    let name = node.name().map(|n| n.as_name()).unwrap_or_else(Name::missing);
+    let type_ref = TypeRef::from_ast_opt(node.ascribed_type());
+    let sig = ConstSignature { name, type_ref };
+    Arc::new(sig)
+}
+
+impl ConstSignature {
+    pub(crate) fn const_signature_query(
+        db: &impl DefDatabase,
+        konst: Const,
+    ) -> Arc<ConstSignature> {
+        let (_, node) = konst.source(db);
+        const_signature_for(&*node)
+    }
+
+    pub(crate) fn static_signature_query(
+        db: &impl DefDatabase,
+        konst: Static,
+    ) -> Arc<ConstSignature> {
+        let (_, node) = konst.source(db);
+        const_signature_for(&*node)
+    }
+}
diff --git a/crates/ra_hir/src/code_model_impl/krate.rs b/crates/ra_hir/src/code_model_impl/krate.rs
new file mode 100644
index 0000000000..914414fc3e
--- /dev/null
+++ b/crates/ra_hir/src/code_model_impl/krate.rs
@@ -0,0 +1,22 @@
+use crate::{
+    Crate, CrateDependency, AsName, Module, DefDatabase,
+};
+
+impl Crate {
+    pub(crate) fn dependencies_impl(&self, db: &impl DefDatabase) -> Vec<CrateDependency> {
+        let crate_graph = db.crate_graph();
+        crate_graph
+            .dependencies(self.crate_id)
+            .map(|dep| {
+                let krate = Crate { crate_id: dep.crate_id() };
+                let name = dep.as_name();
+                CrateDependency { krate, name }
+            })
+            .collect()
+    }
+    pub(crate) fn root_module_impl(&self, db: &impl DefDatabase) -> Option<Module> {
+        let module_id = db.crate_def_map(*self).root();
+        let module = Module { krate: *self, module_id };
+        Some(module)
+    }
+}
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs
new file mode 100644
index 0000000000..5c2ea73ce6
--- /dev/null
+++ b/crates/ra_hir/src/code_model_impl/module.rs
@@ -0,0 +1,99 @@
+use ra_db::FileId;
+use ra_syntax::{ast, TreeArc};
+
+use crate::{
+    Module, ModuleSource, Name, AstId,
+    nameres::CrateModuleId,
+    HirDatabase, DefDatabase,
+    HirFileId,
+};
+
+impl ModuleSource {
+    pub(crate) fn new(
+        db: &impl DefDatabase,
+        file_id: Option<FileId>,
+        decl_id: Option<AstId<ast::Module>>,
+    ) -> ModuleSource {
+        match (file_id, decl_id) {
+            (Some(file_id), _) => {
+                let source_file = db.parse(file_id);
+                ModuleSource::SourceFile(source_file)
+            }
+            (None, Some(item_id)) => {
+                let module = item_id.to_node(db);
+                assert!(module.item_list().is_some(), "expected inline module");
+                ModuleSource::Module(module.to_owned())
+            }
+            (None, None) => panic!(),
+        }
+    }
+}
+
+impl Module {
+    fn with_module_id(&self, module_id: CrateModuleId) -> Module {
+        Module { module_id, krate: self.krate }
+    }
+
+    pub(crate) fn name_impl(&self, db: &impl HirDatabase) -> Option<Name> {
+        let def_map = db.crate_def_map(self.krate);
+        let parent = def_map[self.module_id].parent?;
+        def_map[parent].children.iter().find_map(|(name, module_id)| {
+            if *module_id == self.module_id {
+                Some(name.clone())
+            } else {
+                None
+            }
+        })
+    }
+
+    pub(crate) fn definition_source_impl(
+        &self,
+        db: &impl DefDatabase,
+    ) -> (HirFileId, ModuleSource) {
+        let def_map = db.crate_def_map(self.krate);
+        let decl_id = def_map[self.module_id].declaration;
+        let file_id = def_map[self.module_id].definition;
+        let module_source = ModuleSource::new(db, file_id, decl_id);
+        let file_id = file_id.map(HirFileId::from).unwrap_or_else(|| decl_id.unwrap().file_id());
+        (file_id, module_source)
+    }
+
+    pub(crate) fn declaration_source_impl(
+        &self,
+        db: &impl HirDatabase,
+    ) -> Option<(HirFileId, TreeArc<ast::Module>)> {
+        let def_map = db.crate_def_map(self.krate);
+        let decl = def_map[self.module_id].declaration?;
+        let ast = decl.to_node(db);
+        Some((decl.file_id(), ast))
+    }
+
+    pub(crate) fn crate_root_impl(&self, db: &impl DefDatabase) -> Module {
+        let def_map = db.crate_def_map(self.krate);
+        self.with_module_id(def_map.root())
+    }
+
+    /// Finds a child module with the specified name.
+    pub(crate) fn child_impl(&self, db: &impl HirDatabase, name: &Name) -> Option<Module> {
+        let def_map = db.crate_def_map(self.krate);
+        let child_id = def_map[self.module_id].children.get(name)?;
+        Some(self.with_module_id(*child_id))
+    }
+
+    /// Iterates over all child modules.
+    pub(crate) fn children_impl(&self, db: &impl DefDatabase) -> impl Iterator<Item = Module> {
+        let def_map = db.crate_def_map(self.krate);
+        let children = def_map[self.module_id]
+            .children
+            .iter()
+            .map(|(_, module_id)| self.with_module_id(*module_id))
+            .collect::<Vec<_>>();
+        children.into_iter()
+    }
+
+    pub(crate) fn parent_impl(&self, db: &impl DefDatabase) -> Option<Module> {
+        let def_map = db.crate_def_map(self.krate);
+        let parent_id = def_map[self.module_id].parent?;
+        Some(self.with_module_id(parent_id))
+    }
+}
diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs
index 8effbbe35c..79a7fa23a9 100644
--- a/crates/ra_hir/src/generics.rs
+++ b/crates/ra_hir/src/generics.rs
@@ -9,7 +9,7 @@ use ra_syntax::ast::{self, NameOwner, TypeParamsOwner, TypeBoundsOwner, DefaultT
 
 use crate::{
     db::{ HirDatabase, DefDatabase},
-    Name, AsName, Function, Struct, Union, Enum, Trait, TypeAlias, ImplBlock, Container, path::Path, type_ref::TypeRef, AdtDef
+    Name, AsName, Function, Struct, Enum, Trait, TypeAlias, ImplBlock, Container, path::Path, type_ref::TypeRef, AdtDef
 };
 
 /// Data about a generic parameter (to a function, struct, impl, ...).
@@ -42,13 +42,12 @@ pub struct WherePredicate {
 pub enum GenericDef {
     Function(Function),
     Struct(Struct),
-    Union(Union),
     Enum(Enum),
     Trait(Trait),
     TypeAlias(TypeAlias),
     ImplBlock(ImplBlock),
 }
-impl_froms!(GenericDef: Function, Struct, Union, Enum, Trait, TypeAlias, ImplBlock);
+impl_froms!(GenericDef: Function, Struct, Enum, Trait, TypeAlias, ImplBlock);
 
 impl GenericParams {
     pub(crate) fn generic_params_query(
@@ -59,10 +58,7 @@ impl GenericParams {
         let parent = match def {
             GenericDef::Function(it) => it.container(db).map(GenericDef::from),
             GenericDef::TypeAlias(it) => it.container(db).map(GenericDef::from),
-            GenericDef::Struct(_)
-            | GenericDef::Union(_)
-            | GenericDef::Enum(_)
-            | GenericDef::Trait(_) => None,
+            GenericDef::Struct(_) | GenericDef::Enum(_) | GenericDef::Trait(_) => None,
             GenericDef::ImplBlock(_) => None,
         };
         generics.parent_params = parent.map(|p| db.generic_params(p));
@@ -70,7 +66,6 @@ impl GenericParams {
         match def {
             GenericDef::Function(it) => generics.fill(&*it.source(db).1, start),
             GenericDef::Struct(it) => generics.fill(&*it.source(db).1, start),
-            GenericDef::Union(it) => generics.fill(&*it.source(db).1, start),
             GenericDef::Enum(it) => generics.fill(&*it.source(db).1, start),
             GenericDef::Trait(it) => {
                 // traits get the Self type as an implicit first type parameter
@@ -176,7 +171,6 @@ impl GenericDef {
         match self {
             GenericDef::Function(inner) => inner.resolver(db),
             GenericDef::Struct(inner) => inner.resolver(db),
-            GenericDef::Union(inner) => inner.resolver(db),
             GenericDef::Enum(inner) => inner.resolver(db),
             GenericDef::Trait(inner) => inner.resolver(db),
             GenericDef::TypeAlias(inner) => inner.resolver(db),
@@ -198,7 +192,6 @@ impl From<crate::adt::AdtDef> for GenericDef {
     fn from(adt: crate::adt::AdtDef) -> Self {
         match adt {
             AdtDef::Struct(s) => s.into(),
-            AdtDef::Union(u) => u.into(),
             AdtDef::Enum(e) => e.into(),
         }
     }
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs
index 637f6ab835..51fa491c34 100644
--- a/crates/ra_hir/src/impl_block.rs
+++ b/crates/ra_hir/src/impl_block.rs
@@ -15,7 +15,7 @@ use crate::{
     resolve::Resolver,
     ty::Ty,
     generics::HasGenericParams,
-    code_model::{Module, ModuleSource}
+    code_model_api::{Module, ModuleSource}
 };
 
 #[derive(Debug, Default, PartialEq, Eq)]
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index fe2d4adeee..0c6d7c2b76 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -42,7 +42,8 @@ mod docs;
 mod resolve;
 pub mod diagnostics;
 
-mod code_model;
+mod code_model_api;
+mod code_model_impl;
 
 #[cfg(test)]
 mod marks;
@@ -72,11 +73,11 @@ pub use self::{
     source_binder::{SourceAnalyzer, PathResolution, ScopeEntryWithSyntax,MacroByExampleDef},
 };
 
-pub use self::code_model::{
+pub use self::code_model_api::{
     Crate, CrateDependency,
     DefWithBody,
     Module, ModuleDef, ModuleSource,
-    Struct, Union, Enum, EnumVariant,
+    Struct, Enum, EnumVariant,
     Function, FnSignature,
     StructField, FieldSource,
     Static, Const, ConstSignature,
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs
index 621236551e..c615d80c36 100644
--- a/crates/ra_hir/src/nameres/collector.rs
+++ b/crates/ra_hir/src/nameres/collector.rs
@@ -6,7 +6,7 @@ use ra_db::FileId;
 use ra_syntax::ast;
 
 use crate::{
-    Function, Module, Struct, Union, Enum, Const, Static, Trait, TypeAlias,
+    Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias,
     DefDatabase, HirFileId, Name, Path,
     KnownName,
     nameres::{
@@ -495,10 +495,6 @@ where
                 let s = def!(Struct, ast_id);
                 PerNs::both(s, s)
             }
-            raw::DefKind::Union(ast_id) => {
-                let s = def!(Union, ast_id);
-                PerNs::both(s, s)
-            }
             raw::DefKind::Enum(ast_id) => PerNs::types(def!(Enum, ast_id)),
             raw::DefKind::Const(ast_id) => PerNs::values(def!(Const, ast_id)),
             raw::DefKind::Static(ast_id) => PerNs::values(def!(Static, ast_id)),
diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs
index 1b4dcbb7a0..bd32b264be 100644
--- a/crates/ra_hir/src/nameres/raw.rs
+++ b/crates/ra_hir/src/nameres/raw.rs
@@ -1,4 +1,7 @@
-use std::{sync::Arc, ops::Index};
+use std::{
+    sync::Arc,
+    ops::Index,
+};
 
 use test_utils::tested_by;
 use ra_arena::{Arena, impl_arena_id, RawId, map::ArenaMap};
@@ -7,7 +10,10 @@ use ra_syntax::{
     ast::{self, NameOwner, AttrsOwner},
 };
 
-use crate::{DefDatabase, Name, AsName, Path, HirFileId, ModuleSource, AstIdMap, FileAstId, Either};
+use crate::{
+    DefDatabase, Name, AsName, Path, HirFileId, ModuleSource,
+    AstIdMap, FileAstId, Either,
+};
 
 /// `RawItems` is a set of top-level items in a file (except for impls).
 ///
@@ -155,7 +161,6 @@ pub(super) struct DefData {
 pub(super) enum DefKind {
     Function(FileAstId<ast::FnDef>),
     Struct(FileAstId<ast::StructDef>),
-    Union(FileAstId<ast::StructDef>),
     Enum(FileAstId<ast::EnumDef>),
     Const(FileAstId<ast::ConstDef>),
     Static(FileAstId<ast::StaticDef>),
@@ -210,13 +215,7 @@ impl RawItemsCollector {
                 return;
             }
             ast::ModuleItemKind::StructDef(it) => {
-                let id = self.source_ast_id_map.ast_id(it);
-                let name = it.name();
-                if it.is_union() {
-                    (DefKind::Union(id), name)
-                } else {
-                    (DefKind::Struct(id), name)
-                }
+                (DefKind::Struct(self.source_ast_id_map.ast_id(it)), it.name())
             }
             ast::ModuleItemKind::EnumDef(it) => {
                 (DefKind::Enum(self.source_ast_id_map.ast_id(it)), it.name())
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs
index fedfe2feeb..3874e28bf5 100644
--- a/crates/ra_hir/src/resolve.rs
+++ b/crates/ra_hir/src/resolve.rs
@@ -5,7 +5,7 @@ use rustc_hash::{FxHashMap, FxHashSet};
 
 use crate::{
     ModuleDef, Trait,
-    code_model::Crate,
+    code_model_api::Crate,
     MacroDefId,
     db::HirDatabase,
     name::{Name, KnownName},
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 76d34c12b6..3679a2242a 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -536,7 +536,6 @@ impl HirDisplay for ApplicationTy {
             TypeCtor::Adt(def_id) => {
                 let name = match def_id {
                     AdtDef::Struct(s) => s.name(f.db),
-                    AdtDef::Union(u) => u.name(f.db),
                     AdtDef::Enum(e) => e.name(f.db),
                 }
                 .unwrap_or_else(Name::missing);
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 7d8250292e..a48272981f 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -27,13 +27,13 @@ use ra_prof::profile;
 use test_utils::tested_by;
 
 use crate::{
-    Function, StructField, Path, Name, FnSignature, AdtDef, ConstSignature, HirDatabase,
-    DefWithBody, ImplItem,
+    Function, StructField, Path, Name,
+    FnSignature, AdtDef,ConstSignature,
+    HirDatabase,
+    DefWithBody,
+    ImplItem,
     type_ref::{TypeRef, Mutability},
-    expr::{
-        Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement,
-        FieldPat, Array, self,
-    },
+    expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat,Array, self},
     generics::{GenericParams, HasGenericParams},
     path::{GenericArgs, GenericArg},
     ModuleDef,
@@ -644,8 +644,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
                 let ty = self.insert_type_vars(ty.apply_substs(substs));
                 (ty, Some(var.into()))
             }
-            TypableDef::Union(_)
-            | TypableDef::TypeAlias(_)
+            TypableDef::TypeAlias(_)
             | TypableDef::Function(_)
             | TypableDef::Enum(_)
             | TypableDef::Const(_)
@@ -1408,11 +1407,7 @@ impl Expectation {
 }
 
 mod diagnostics {
-    use crate::{
-        expr::ExprId,
-        diagnostics::{DiagnosticSink, NoSuchField},
-        HirDatabase, Function,
-};
+    use crate::{expr::ExprId, diagnostics::{DiagnosticSink, NoSuchField}, HirDatabase, Function};
 
     #[derive(Debug, PartialEq, Eq, Clone)]
     pub(super) enum InferenceDiagnostic {
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs
index 7defa7a9b9..a1a2d0f6b1 100644
--- a/crates/ra_hir/src/ty/lower.rs
+++ b/crates/ra_hir/src/ty/lower.rs
@@ -9,7 +9,7 @@ use std::sync::Arc;
 use std::iter;
 
 use crate::{
-    Function, Struct, Union, StructField, Enum, EnumVariant, Path, ModuleDef, TypeAlias, Const, Static,
+    Function, Struct, StructField, Enum, EnumVariant, Path, ModuleDef, TypeAlias, Const, Static,
     HirDatabase,
     type_ref::TypeRef,
     name::KnownName,
@@ -124,7 +124,6 @@ impl Ty {
         let def_generic: Option<GenericDef> = match resolved {
             TypableDef::Function(func) => Some(func.into()),
             TypableDef::Struct(s) => Some(s.into()),
-            TypableDef::Union(u) => Some(u.into()),
             TypableDef::Enum(e) => Some(e.into()),
             TypableDef::EnumVariant(var) => Some(var.parent_enum(db).into()),
             TypableDef::TypeAlias(t) => Some(t.into()),
@@ -145,7 +144,6 @@ impl Ty {
         let segment = match resolved {
             TypableDef::Function(_)
             | TypableDef::Struct(_)
-            | TypableDef::Union(_)
             | TypableDef::Enum(_)
             | TypableDef::Const(_)
             | TypableDef::Static(_)
@@ -295,14 +293,12 @@ pub(crate) fn type_for_def(db: &impl HirDatabase, def: TypableDef, ns: Namespace
         (TypableDef::Struct(s), Namespace::Values) => type_for_struct_constructor(db, s),
         (TypableDef::Enum(e), Namespace::Types) => type_for_adt(db, e),
         (TypableDef::EnumVariant(v), Namespace::Values) => type_for_enum_variant_constructor(db, v),
-        (TypableDef::Union(u), Namespace::Types) => type_for_adt(db, u),
         (TypableDef::TypeAlias(t), Namespace::Types) => type_for_type_alias(db, t),
         (TypableDef::Const(c), Namespace::Values) => type_for_const(db, c),
         (TypableDef::Static(c), Namespace::Values) => type_for_static(db, c),
 
         // 'error' cases:
         (TypableDef::Function(_), Namespace::Types) => Ty::Unknown,
-        (TypableDef::Union(_), Namespace::Values) => Ty::Unknown,
         (TypableDef::Enum(_), Namespace::Values) => Ty::Unknown,
         (TypableDef::EnumVariant(_), Namespace::Types) => Ty::Unknown,
         (TypableDef::TypeAlias(_), Namespace::Values) => Ty::Unknown,
@@ -471,21 +467,19 @@ fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty {
 pub enum TypableDef {
     Function(Function),
     Struct(Struct),
-    Union(Union),
     Enum(Enum),
     EnumVariant(EnumVariant),
     TypeAlias(TypeAlias),
     Const(Const),
     Static(Static),
 }
-impl_froms!(TypableDef: Function, Struct, Union, Enum, EnumVariant, TypeAlias, Const, Static);
+impl_froms!(TypableDef: Function, Struct, Enum, EnumVariant, TypeAlias, Const, Static);
 
 impl From<ModuleDef> for Option<TypableDef> {
     fn from(def: ModuleDef) -> Option<TypableDef> {
         let res = match def {
             ModuleDef::Function(f) => f.into(),
             ModuleDef::Struct(s) => s.into(),
-            ModuleDef::Union(u) => u.into(),
             ModuleDef::Enum(e) => e.into(),
             ModuleDef::EnumVariant(v) => v.into(),
             ModuleDef::TypeAlias(t) => t.into(),
diff --git a/crates/ra_ide_api/src/completion/complete_dot.rs b/crates/ra_ide_api/src/completion/complete_dot.rs
index 5bf289c630..2e80846991 100644
--- a/crates/ra_ide_api/src/completion/complete_dot.rs
+++ b/crates/ra_ide_api/src/completion/complete_dot.rs
@@ -66,18 +66,16 @@ mod tests {
                 }
                 ",
         ),
-            @r###"
-       ⋮[
-       ⋮    CompletionItem {
-       ⋮        label: "the_field",
-       ⋮        source_range: [94; 94),
-       ⋮        delete: [94; 94),
-       ⋮        insert: "the_field",
-       ⋮        kind: Field,
-       ⋮        detail: "u32",
-       ⋮    },
-       ⋮]
-        "###
+            @r###"[
+    CompletionItem {
+        label: "the_field",
+        source_range: [94; 94),
+        delete: [94; 94),
+        insert: "the_field",
+        kind: Field,
+        detail: "u32"
+    }
+]"###
         );
     }
 
@@ -97,29 +95,27 @@ mod tests {
             }
             ",
         ),
-        @r###"
-       ⋮[
-       ⋮    CompletionItem {
-       ⋮        label: "foo",
-       ⋮        source_range: [187; 187),
-       ⋮        delete: [187; 187),
-       ⋮        insert: "foo()$0",
-       ⋮        kind: Method,
-       ⋮        detail: "fn foo(self)",
-       ⋮    },
-       ⋮    CompletionItem {
-       ⋮        label: "the_field",
-       ⋮        source_range: [187; 187),
-       ⋮        delete: [187; 187),
-       ⋮        insert: "the_field",
-       ⋮        kind: Field,
-       ⋮        detail: "(u32,)",
-       ⋮        documentation: Documentation(
-       ⋮            "This is the_field",
-       ⋮        ),
-       ⋮    },
-       ⋮]
-        "###
+        @r###"[
+    CompletionItem {
+        label: "foo",
+        source_range: [187; 187),
+        delete: [187; 187),
+        insert: "foo()$0",
+        kind: Method,
+        detail: "fn foo(self)"
+    },
+    CompletionItem {
+        label: "the_field",
+        source_range: [187; 187),
+        delete: [187; 187),
+        insert: "the_field",
+        kind: Field,
+        detail: "(u32,)",
+        documentation: Documentation(
+            "This is the_field"
+        )
+    }
+]"###
         );
     }
 
@@ -136,26 +132,24 @@ mod tests {
             }
             ",
         ),
-        @r###"
-       ⋮[
-       ⋮    CompletionItem {
-       ⋮        label: "foo",
-       ⋮        source_range: [126; 126),
-       ⋮        delete: [126; 126),
-       ⋮        insert: "foo()$0",
-       ⋮        kind: Method,
-       ⋮        detail: "fn foo(&self)",
-       ⋮    },
-       ⋮    CompletionItem {
-       ⋮        label: "the_field",
-       ⋮        source_range: [126; 126),
-       ⋮        delete: [126; 126),
-       ⋮        insert: "the_field",
-       ⋮        kind: Field,
-       ⋮        detail: "(u32, i32)",
-       ⋮    },
-       ⋮]
-        "###
+        @r###"[
+    CompletionItem {
+        label: "foo",
+        source_range: [126; 126),
+        delete: [126; 126),
+        insert: "foo()$0",
+        kind: Method,
+        detail: "fn foo(&self)"
+    },
+    CompletionItem {
+        label: "the_field",
+        source_range: [126; 126),
+        delete: [126; 126),
+        insert: "the_field",
+        kind: Field,
+        detail: "(u32, i32)"
+    }
+]"###
         );
     }
 
@@ -188,18 +182,16 @@ mod tests {
             }
             ",
         ),
-        @r###"
-       ⋮[
-       ⋮    CompletionItem {
-       ⋮        label: "the_method",
-       ⋮        source_range: [144; 144),
-       ⋮        delete: [144; 144),
-       ⋮        insert: "the_method()$0",
-       ⋮        kind: Method,
-       ⋮        detail: "fn the_method(&self)",
-       ⋮    },
-       ⋮]
-        "###
+        @r###"[
+    CompletionItem {
+        label: "the_method",
+        source_range: [144; 144),
+        delete: [144; 144),
+        insert: "the_method()$0",
+        kind: Method,
+        detail: "fn the_method(&self)"
+    }
+]"###
         );
     }
 
@@ -216,18 +208,16 @@ mod tests {
             }
             ",
             ),
-            @r###"
-       ⋮[
-       ⋮    CompletionItem {
-       ⋮        label: "the_method",
-       ⋮        source_range: [151; 151),
-       ⋮        delete: [151; 151),
-       ⋮        insert: "the_method()$0",
-       ⋮        kind: Method,
-       ⋮        detail: "fn the_method(&self)",
-       ⋮    },
-       ⋮]
-        "###
+            @r###"[
+    CompletionItem {
+        label: "the_method",
+        source_range: [151; 151),
+        delete: [151; 151),
+        insert: "the_method()$0",
+        kind: Method,
+        detail: "fn the_method(&self)"
+    }
+]"###
         );
     }
 
@@ -267,18 +257,16 @@ mod tests {
             }
             ",
         ),
-        @r###"
-       ⋮[
-       ⋮    CompletionItem {
-       ⋮        label: "the_method",
-       ⋮        source_range: [249; 249),
-       ⋮        delete: [249; 249),
-       ⋮        insert: "the_method()$0",
-       ⋮        kind: Method,
-       ⋮        detail: "fn the_method(&self)",
-       ⋮    },
-       ⋮]
-        "###
+        @r###"[
+    CompletionItem {
+        label: "the_method",
+        source_range: [249; 249),
+        delete: [249; 249),
+        insert: "the_method()$0",
+        kind: Method,
+        detail: "fn the_method(&self)"
+    }
+]"###
         );
     }
 
@@ -293,26 +281,24 @@ mod tests {
             }
             ",
         ),
-        @r###"
-       ⋮[
-       ⋮    CompletionItem {
-       ⋮        label: "0",
-       ⋮        source_range: [75; 75),
-       ⋮        delete: [75; 75),
-       ⋮        insert: "0",
-       ⋮        kind: Field,
-       ⋮        detail: "i32",
-       ⋮    },
-       ⋮    CompletionItem {
-       ⋮        label: "1",
-       ⋮        source_range: [75; 75),
-       ⋮        delete: [75; 75),
-       ⋮        insert: "1",
-       ⋮        kind: Field,
-       ⋮        detail: "f64",
-       ⋮    },
-       ⋮]
-        "###
+        @r###"[
+    CompletionItem {
+        label: "0",
+        source_range: [75; 75),
+        delete: [75; 75),
+        insert: "0",
+        kind: Field,
+        detail: "i32"
+    },
+    CompletionItem {
+        label: "1",
+        source_range: [75; 75),
+        delete: [75; 75),
+        insert: "1",
+        kind: Field,
+        detail: "f64"
+    }
+]"###
         );
     }
 
@@ -336,18 +322,16 @@ mod tests {
             }
             ",
         ),
-        @r###"
-       ⋮[
-       ⋮    CompletionItem {
-       ⋮        label: "blah",
-       ⋮        source_range: [299; 300),
-       ⋮        delete: [299; 300),
-       ⋮        insert: "blah()$0",
-       ⋮        kind: Method,
-       ⋮        detail: "pub fn blah(&self)",
-       ⋮    },
-       ⋮]
-        "###
+        @r###"[
+    CompletionItem {
+        label: "blah",
+        source_range: [299; 300),
+        delete: [299; 300),
+        insert: "blah()$0",
+        kind: Method,
+        detail: "pub fn blah(&self)"
+    }
+]"###
         );
     }
 
@@ -362,18 +346,16 @@ mod tests {
             };
             ",
         ),
-        @r###"
-       ⋮[
-       ⋮    CompletionItem {
-       ⋮        label: "the_field",
-       ⋮        source_range: [106; 106),
-       ⋮        delete: [106; 106),
-       ⋮        insert: "the_field",
-       ⋮        kind: Field,
-       ⋮        detail: "u32",
-       ⋮    },
-       ⋮]
-        "###
+        @r###"[
+    CompletionItem {
+        label: "the_field",
+        source_range: [106; 106),
+        delete: [106; 106),
+        insert: "the_field",
+        kind: Field,
+        detail: "u32"
+    }
+]"###
         );
     }
 }
diff --git a/crates/ra_ide_api/src/completion/complete_fn_param.rs b/crates/ra_ide_api/src/completion/complete_fn_param.rs
index d738ffc136..85ef62f52f 100644
--- a/crates/ra_ide_api/src/completion/complete_fn_param.rs
+++ b/crates/ra_ide_api/src/completion/complete_fn_param.rs
@@ -71,17 +71,15 @@ mod tests {
                 fn baz(file<|>) {}
                 ",
         ),
-            @r###"
-       ⋮[
-       ⋮    CompletionItem {
-       ⋮        label: "file_id: FileId",
-       ⋮        source_range: [110; 114),
-       ⋮        delete: [110; 114),
-       ⋮        insert: "file_id: FileId",
-       ⋮        lookup: "file_id",
-       ⋮    },
-       ⋮]
-        "###
+            @r###"[
+    CompletionItem {
+        label: "file_id: FileId",
+        source_range: [110; 114),
+        delete: [110; 114),
+        insert: "file_id: FileId",
+        lookup: "file_id"
+    }
+]"###
         );
     }
 
@@ -95,17 +93,15 @@ mod tests {
                 fn baz(file<|>, x: i32) {}
                 ",
         ),
-            @r###"
-       ⋮[
-       ⋮    CompletionItem {
-       ⋮        label: "file_id: FileId",
-       ⋮        source_range: [110; 114),
-       ⋮        delete: [110; 114),
-       ⋮        insert: "file_id: FileId",
-       ⋮        lookup: "file_id",
-       ⋮    },
-       ⋮]
-        "###
+            @r###"[
+    CompletionItem {
+        label: "file_id: FileId",
+        source_range: [110; 114),
+        delete: [110; 114),
+        insert: "file_id: FileId",
+        lookup: "file_id"
+    }
+]"###
         );
     }
 
@@ -122,17 +118,15 @@ mod tests {
                 }
                 ",
         ),
-            @r###"
-       ⋮[
-       ⋮    CompletionItem {
-       ⋮        label: "file_id: FileId",
-       ⋮        source_range: [289; 293),
-       ⋮        delete: [289; 293),
-       ⋮        insert: "file_id: FileId",
-       ⋮        lookup: "file_id",
-       ⋮    },
-       ⋮]
-        "###
+            @r###"[
+    CompletionItem {
+        label: "file_id: FileId",
+        source_range: [289; 293),
+        delete: [289; 293),
+        insert: "file_id: FileId",
+        lookup: "file_id"
+    }
+]"###
         );
     }
 }
diff --git a/crates/ra_ide_api/src/completion/complete_pattern.rs b/crates/ra_ide_api/src/completion/complete_pattern.rs
index 74833a7565..0ef2486879 100644
--- a/crates/ra_ide_api/src/completion/complete_pattern.rs
+++ b/crates/ra_ide_api/src/completion/complete_pattern.rs
@@ -53,37 +53,35 @@ mod tests {
             }
             ",
         );
-        assert_debug_snapshot_matches!(completions, @r###"
-       ⋮[
-       ⋮    CompletionItem {
-       ⋮        label: "E",
-       ⋮        source_range: [246; 246),
-       ⋮        delete: [246; 246),
-       ⋮        insert: "E",
-       ⋮        kind: Enum,
-       ⋮    },
-       ⋮    CompletionItem {
-       ⋮        label: "X",
-       ⋮        source_range: [246; 246),
-       ⋮        delete: [246; 246),
-       ⋮        insert: "X",
-       ⋮        kind: EnumVariant,
-       ⋮    },
-       ⋮    CompletionItem {
-       ⋮        label: "Z",
-       ⋮        source_range: [246; 246),
-       ⋮        delete: [246; 246),
-       ⋮        insert: "Z",
-       ⋮        kind: Const,
-       ⋮    },
-       ⋮    CompletionItem {
-       ⋮        label: "m",
-       ⋮        source_range: [246; 246),
-       ⋮        delete: [246; 246),
-       ⋮        insert: "m",
-       ⋮        kind: Module,
-       ⋮    },
-       ⋮]
-        "###);
+        assert_debug_snapshot_matches!(completions, @r###"[
+    CompletionItem {
+        label: "E",
+        source_range: [246; 246),
+        delete: [246; 246),
+        insert: "E",
+        kind: Enum
+    },
+    CompletionItem {
+        label: "X",
+        source_range: [246; 246),
+        delete: [246; 246),
+        insert: "X",
+        kind: EnumVariant
+    },
+    CompletionItem {
+        label: "Z",
+        source_range: [246; 246),
+        delete: [246; 246),
+        insert: "Z",
+        kind: Const
+    },
+    CompletionItem {
+        label: "m",
+        source_range: [246; 246),
+        delete: [246; 246),
+        insert: "m",
+        kind: Module
+    }
+]"###);
     }
 }
diff --git a/crates/ra_ide_api/src/completion/complete_struct_literal.rs b/crates/ra_ide_api/src/completion/complete_struct_literal.rs
index 1eeea58f64..48fbf67f74 100644
--- a/crates/ra_ide_api/src/completion/complete_struct_literal.rs
+++ b/crates/ra_ide_api/src/completion/complete_struct_literal.rs
@@ -20,7 +20,6 @@ pub(super) fn complete_struct_literal(acc: &mut Completions, ctx: &CompletionCon
         }
 
         // FIXME unions
-        AdtDef::Union(_) => (),
         AdtDef::Enum(_) => (),
     };
 }
@@ -44,17 +43,15 @@ mod tests {
             }
             ",
         );
-        assert_debug_snapshot_matches!(completions, @r###"
-       ⋮[
-       ⋮    CompletionItem {
-       ⋮        label: "the_field",
-       ⋮        source_range: [83; 86),
-       ⋮        delete: [83; 86),
-       ⋮        insert: "the_field",
-       ⋮        kind: Field,
-       ⋮        detail: "u32",
-       ⋮    },
-       ⋮]
-        "###);
+        assert_debug_snapshot_matches!(completions, @r###"[
+    CompletionItem {
+        label: "the_field",
+        source_range: [83; 86),
+        delete: [83; 86),
+        insert: "the_field",
+        kind: Field,
+        detail: "u32"
+    }
+]"###);
     }
 }
diff --git a/crates/ra_ide_api/src/completion/presentation.rs b/crates/ra_ide_api/src/completion/presentation.rs
index 064d379a4f..9aa3466887 100644
--- a/crates/ra_ide_api/src/completion/presentation.rs
+++ b/crates/ra_ide_api/src/completion/presentation.rs
@@ -63,7 +63,6 @@ impl Completions {
                 return self.add_function_with_name(ctx, Some(local_name), *func);
             }
             Resolution::Def(Struct(it)) => (CompletionItemKind::Struct, it.docs(ctx.db)),
-            Resolution::Def(Union(it)) => (CompletionItemKind::Struct, it.docs(ctx.db)),
             Resolution::Def(Enum(it)) => (CompletionItemKind::Enum, it.docs(ctx.db)),
             Resolution::Def(EnumVariant(it)) => (CompletionItemKind::EnumVariant, it.docs(ctx.db)),
             Resolution::Def(Const(it)) => (CompletionItemKind::Const, it.docs(ctx.db)),
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_for.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_for.snap
index e9b717a45b..bd7f99f712 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_for.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_for.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.119822026Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.132341107Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -11,13 +11,13 @@ expression: kind_completions
         delete: [83; 83),
         insert: "quux()$0",
         kind: Function,
-        detail: "fn quux()",
+        detail: "fn quux()"
     },
     CompletionItem {
         label: "x",
         source_range: [83; 83),
         delete: [83; 83),
         insert: "x",
-        kind: Binding,
-    },
+        kind: Binding
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_if_let.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_if_let.snap
index 2a22201ad3..3b374c4def 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_if_let.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_if_let.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.122168608Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.126809445Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,14 +10,14 @@ expression: kind_completions
         source_range: [214; 214),
         delete: [214; 214),
         insert: "a",
-        kind: Binding,
+        kind: Binding
     },
     CompletionItem {
         label: "b",
         source_range: [214; 214),
         delete: [214; 214),
         insert: "b",
-        kind: Binding,
+        kind: Binding
     },
     CompletionItem {
         label: "quux",
@@ -25,6 +25,6 @@ expression: kind_completions
         delete: [214; 214),
         insert: "quux()$0",
         kind: Function,
-        detail: "fn quux()",
-    },
+        detail: "fn quux()"
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_let.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_let.snap
index b9a5dc9c8f..173f5319ad 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_let.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_let.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.122797188Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.126696322Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -11,20 +11,20 @@ expression: kind_completions
         delete: [79; 79),
         insert: "quux($0)",
         kind: Function,
-        detail: "fn quux(x: i32)",
+        detail: "fn quux(x: i32)"
     },
     CompletionItem {
         label: "x",
         source_range: [79; 79),
         delete: [79; 79),
         insert: "x",
-        kind: Binding,
+        kind: Binding
     },
     CompletionItem {
         label: "y",
         source_range: [79; 79),
         delete: [79; 79),
         insert: "y",
-        kind: Binding,
-    },
+        kind: Binding
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_break_and_continue_in_loops1.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_break_and_continue_in_loops1.snap
index b6f95c1ff0..42ff024691 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_break_and_continue_in_loops1.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_break_and_continue_in_loops1.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.067956470Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:23.976673150Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,48 +10,48 @@ expression: kind_completions
         source_range: [55; 55),
         delete: [55; 55),
         insert: "break;",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "continue",
         source_range: [55; 55),
         delete: [55; 55),
         insert: "continue;",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "if",
         source_range: [55; 55),
         delete: [55; 55),
         insert: "if $0 {}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "loop",
         source_range: [55; 55),
         delete: [55; 55),
         insert: "loop {$0}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "match",
         source_range: [55; 55),
         delete: [55; 55),
         insert: "match $0 {}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "return",
         source_range: [55; 55),
         delete: [55; 55),
         insert: "return $0;",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "while",
         source_range: [55; 55),
         delete: [55; 55),
         insert: "while $0 {}",
-        kind: Keyword,
-    },
+        kind: Keyword
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_break_and_continue_in_loops2.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_break_and_continue_in_loops2.snap
index 9b37478efe..057ff8a7ac 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_break_and_continue_in_loops2.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_break_and_continue_in_loops2.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:44:10.859967190Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.068967569Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,34 +10,34 @@ expression: kind_completions
         source_range: [60; 60),
         delete: [60; 60),
         insert: "if $0 {}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "loop",
         source_range: [60; 60),
         delete: [60; 60),
         insert: "loop {$0}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "match",
         source_range: [60; 60),
         delete: [60; 60),
         insert: "match $0 {}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "return",
         source_range: [60; 60),
         delete: [60; 60),
         insert: "return $0;",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "while",
         source_range: [60; 60),
         delete: [60; 60),
         insert: "while $0 {}",
-        kind: Keyword,
-    },
+        kind: Keyword
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_prelude.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_prelude.snap
index b339c6c5f9..16126ee777 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_prelude.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_prelude.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.139262926Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.180517434Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,7 +10,7 @@ expression: kind_completions
         source_range: [18; 18),
         delete: [18; 18),
         insert: "Option",
-        kind: Struct,
+        kind: Struct
     },
     CompletionItem {
         label: "foo",
@@ -18,13 +18,13 @@ expression: kind_completions
         delete: [18; 18),
         insert: "foo()$0",
         kind: Function,
-        detail: "fn foo()",
+        detail: "fn foo()"
     },
     CompletionItem {
         label: "std",
         source_range: [18; 18),
         delete: [18; 18),
         insert: "std",
-        kind: Module,
-    },
+        kind: Module
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_use_paths_across_crates.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_use_paths_across_crates.snap
index 113deafb13..2420e77445 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_use_paths_across_crates.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_use_paths_across_crates.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.108690807Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.118807216Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,6 +10,6 @@ expression: kind_completions
         source_range: [9; 9),
         delete: [9; 9),
         insert: "bar",
-        kind: Module,
-    },
+        kind: Module
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__deeply_nested_use_tree.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__deeply_nested_use_tree.snap
index aacdeb7639..c472f79659 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__deeply_nested_use_tree.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__deeply_nested_use_tree.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.085633034Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.044567777Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,6 +10,6 @@ expression: kind_completions
         source_range: [23; 25),
         delete: [23; 25),
         insert: "Spam",
-        kind: Struct,
-    },
+        kind: Struct
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_add_semi_after_return_if_not_a_statement.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_add_semi_after_return_if_not_a_statement.snap
index 9d320c7154..97bd76c494 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_add_semi_after_return_if_not_a_statement.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_add_semi_after_return_if_not_a_statement.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.081993214Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:23.987788705Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,34 +10,34 @@ expression: kind_completions
         source_range: [85; 85),
         delete: [85; 85),
         insert: "if $0 {}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "loop",
         source_range: [85; 85),
         delete: [85; 85),
         insert: "loop {$0}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "match",
         source_range: [85; 85),
         delete: [85; 85),
         insert: "match $0 {}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "return",
         source_range: [85; 85),
         delete: [85; 85),
         insert: "return $0",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "while",
         source_range: [85; 85),
         delete: [85; 85),
         insert: "while $0 {}",
-        kind: Keyword,
-    },
+        kind: Keyword
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_if_already_call.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_if_already_call.snap
index 46bea2ccd4..1de0efb5b3 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_if_already_call.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_if_already_call.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.158296242Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.211680376Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -11,7 +11,7 @@ expression: kind_completions
         delete: [35; 39),
         insert: "frobnicate",
         kind: Function,
-        detail: "fn frobnicate()",
+        detail: "fn frobnicate()"
     },
     CompletionItem {
         label: "main",
@@ -19,6 +19,6 @@ expression: kind_completions
         delete: [35; 39),
         insert: "main",
         kind: Function,
-        detail: "fn main()",
-    },
+        detail: "fn main()"
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_if_already_call_assoc_fn.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_if_already_call_assoc_fn.snap
index b09a6745e6..19375ea958 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_if_already_call_assoc_fn.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_if_already_call_assoc_fn.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:44:10.920136527Z"
-creator: insta@0.8.1
+created: "2019-02-24T16:33:48.008220694Z"
+creator: insta@0.6.3
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -11,6 +11,6 @@ expression: kind_completions
         delete: [67; 69),
         insert: "new",
         kind: Function,
-        detail: "fn new() -> Foo",
-    },
+        detail: "fn new() -> Foo"
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_in_use_item.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_in_use_item.snap
index 84ccc81606..ef77816ec1 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_in_use_item.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_in_use_item.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.154795561Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.213677341Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -11,6 +11,6 @@ expression: kind_completions
         delete: [40; 41),
         insert: "foo",
         kind: Function,
-        detail: "pub fn foo()",
-    },
+        detail: "pub fn foo()"
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_show_both_completions_for_shadowing.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_show_both_completions_for_shadowing.snap
index 57434210d5..34adcda6cb 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_show_both_completions_for_shadowing.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_show_both_completions_for_shadowing.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.142044205Z"
-creator: insta@0.8.1
+created: "2019-04-04T14:52:24.531844100Z"
+creator: insta@0.7.4
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,7 +10,7 @@ expression: kind_completions
         source_range: [126; 126),
         delete: [126; 126),
         insert: "bar",
-        kind: Binding,
+        kind: Binding
     },
     CompletionItem {
         label: "foo",
@@ -18,6 +18,6 @@ expression: kind_completions
         delete: [126; 126),
         insert: "foo()$0",
         kind: Function,
-        detail: "fn foo()",
-    },
+        detail: "fn foo()"
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__enum_variant.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__enum_variant.snap
index e40217ca83..1df121523b 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__enum_variant.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__enum_variant.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.090178265Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.045355450Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -13,8 +13,8 @@ expression: kind_completions
         kind: EnumVariant,
         detail: "(i32)",
         documentation: Documentation(
-            "Bar Variant with i32",
-        ),
+            "Bar Variant with i32"
+        )
     },
     CompletionItem {
         label: "Foo",
@@ -24,7 +24,7 @@ expression: kind_completions
         kind: EnumVariant,
         detail: "()",
         documentation: Documentation(
-            "Foo Variant",
-        ),
-    },
+            "Foo Variant"
+        )
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__enum_variant_with_details.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__enum_variant_with_details.snap
index e09d7988a3..daccd9fba0 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__enum_variant_with_details.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__enum_variant_with_details.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.091325331Z"
-creator: insta@0.8.1
+created: "2019-04-02T07:43:12.954637543Z"
+creator: insta@0.7.4
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -13,8 +13,8 @@ expression: kind_completions
         kind: EnumVariant,
         detail: "(i32, u32)",
         documentation: Documentation(
-            "Bar Variant with i32 and u32",
-        ),
+            "Bar Variant with i32 and u32"
+        )
     },
     CompletionItem {
         label: "Foo",
@@ -24,8 +24,8 @@ expression: kind_completions
         kind: EnumVariant,
         detail: "()",
         documentation: Documentation(
-            "Foo Variant (empty)",
-        ),
+            "Foo Variant (empty)"
+        )
     },
     CompletionItem {
         label: "S",
@@ -35,7 +35,7 @@ expression: kind_completions
         kind: EnumVariant,
         detail: "(S)",
         documentation: Documentation(
-            "",
-        ),
-    },
+            ""
+        )
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__extern_prelude.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__extern_prelude.snap
index b9449a76c1..0d36fd6035 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__extern_prelude.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__extern_prelude.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.123197049Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.137183638Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,6 +10,6 @@ expression: kind_completions
         source_range: [4; 4),
         delete: [4; 4),
         insert: "other_crate",
-        kind: Module,
-    },
+        kind: Module
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params.snap
index eb1a4151af..210e5a02d2 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.123825399Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.143253235Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,7 +10,7 @@ expression: kind_completions
         source_range: [44; 44),
         delete: [44; 44),
         insert: "T",
-        kind: TypeParam,
+        kind: TypeParam
     },
     CompletionItem {
         label: "quux",
@@ -18,6 +18,6 @@ expression: kind_completions
         delete: [44; 44),
         insert: "quux()$0",
         kind: Function,
-        detail: "fn quux<T>()",
-    },
+        detail: "fn quux<T>()"
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params_in_struct.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params_in_struct.snap
index 52f08267f7..ab8c304467 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params_in_struct.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__generic_params_in_struct.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.130778739Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.149424158Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,13 +10,13 @@ expression: kind_completions
         source_range: [46; 46),
         delete: [46; 46),
         insert: "T",
-        kind: TypeParam,
+        kind: TypeParam
     },
     CompletionItem {
         label: "X",
         source_range: [46; 46),
         delete: [46; 46),
         insert: "X",
-        kind: Struct,
-    },
+        kind: Struct
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls1.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls1.snap
index c795b9aaee..a4fc447b27 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls1.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls1.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.156115632Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.224510370Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -11,7 +11,7 @@ expression: kind_completions
         delete: [53; 56),
         insert: "main()$0",
         kind: Function,
-        detail: "fn main()",
+        detail: "fn main()"
     },
     CompletionItem {
         label: "no_args",
@@ -19,6 +19,6 @@ expression: kind_completions
         delete: [53; 56),
         insert: "no_args()$0",
         kind: Function,
-        detail: "fn no_args()",
-    },
+        detail: "fn no_args()"
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls2.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls2.snap
index b49a838e0e..b124355d5e 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls2.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls2.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:44:10.916806744Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.267013140Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -11,7 +11,7 @@ expression: kind_completions
         delete: [72; 77),
         insert: "main()$0",
         kind: Function,
-        detail: "fn main()",
+        detail: "fn main()"
     },
     CompletionItem {
         label: "with_args",
@@ -19,6 +19,6 @@ expression: kind_completions
         delete: [72; 77),
         insert: "with_args($0)",
         kind: Function,
-        detail: "fn with_args(x: i32, y: String)",
-    },
+        detail: "fn with_args(x: i32, y: String)"
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls3.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls3.snap
index b62cb7aa12..fec729d487 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls3.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls3.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:44:40.543731193Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.303360770Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -11,6 +11,6 @@ expression: kind_completions
         delete: [139; 140),
         insert: "foo()$0",
         kind: Method,
-        detail: "fn foo(&self)",
-    },
+        detail: "fn foo(&self)"
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function1.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function1.snap
index 34a44bb703..045e2a4e6f 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function1.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function1.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.075690846Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:23.987788720Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,34 +10,34 @@ expression: kind_completions
         source_range: [41; 41),
         delete: [41; 41),
         insert: "if $0 {}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "loop",
         source_range: [41; 41),
         delete: [41; 41),
         insert: "loop {$0}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "match",
         source_range: [41; 41),
         delete: [41; 41),
         insert: "match $0 {}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "return",
         source_range: [41; 41),
         delete: [41; 41),
         insert: "return;",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "while",
         source_range: [41; 41),
         delete: [41; 41),
         insert: "while $0 {}",
-        kind: Keyword,
-    },
+        kind: Keyword
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function2.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function2.snap
index ac744f3625..b08efa522e 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function2.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function2.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.068799431Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:23.984740354Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,48 +10,48 @@ expression: kind_completions
         source_range: [92; 92),
         delete: [92; 92),
         insert: "else {$0}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "else if",
         source_range: [92; 92),
         delete: [92; 92),
         insert: "else if $0 {}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "if",
         source_range: [92; 92),
         delete: [92; 92),
         insert: "if $0 {}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "loop",
         source_range: [92; 92),
         delete: [92; 92),
         insert: "loop {$0}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "match",
         source_range: [92; 92),
         delete: [92; 92),
         insert: "match $0 {}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "return",
         source_range: [92; 92),
         delete: [92; 92),
         insert: "return;",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "while",
         source_range: [92; 92),
         delete: [92; 92),
         insert: "while $0 {}",
-        kind: Keyword,
-    },
+        kind: Keyword
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function3.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function3.snap
index 1098ecf54c..e2b9214fbc 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function3.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function3.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.085655258Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.049699338Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,34 +10,34 @@ expression: kind_completions
         source_range: [48; 48),
         delete: [48; 48),
         insert: "if $0 {}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "loop",
         source_range: [48; 48),
         delete: [48; 48),
         insert: "loop {$0}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "match",
         source_range: [48; 48),
         delete: [48; 48),
         insert: "match $0 {}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "return",
         source_range: [48; 48),
         delete: [48; 48),
         insert: "return $0;",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "while",
         source_range: [48; 48),
         delete: [48; 48),
         insert: "while $0 {}",
-        kind: Keyword,
-    },
+        kind: Keyword
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function4.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function4.snap
index 3c5eca1baa..1ea7eb5cea 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function4.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function4.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:44:10.869539856Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.090949782Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,34 +10,34 @@ expression: kind_completions
         source_range: [41; 41),
         delete: [41; 41),
         insert: "if $0 {}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "loop",
         source_range: [41; 41),
         delete: [41; 41),
         insert: "loop {$0}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "match",
         source_range: [41; 41),
         delete: [41; 41),
         insert: "match $0 {}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "return",
         source_range: [41; 41),
         delete: [41; 41),
         insert: "return;",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "while",
         source_range: [41; 41),
         delete: [41; 41),
         insert: "while $0 {}",
-        kind: Keyword,
-    },
+        kind: Keyword
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_use_stmt1.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_use_stmt1.snap
index 71d7e9de84..76d5daf556 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_use_stmt1.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_use_stmt1.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.066687241Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:23.988755424Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,20 +10,20 @@ expression: kind_completions
         source_range: [17; 17),
         delete: [17; 17),
         insert: "crate::",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "self",
         source_range: [17; 17),
         delete: [17; 17),
         insert: "self",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "super",
         source_range: [17; 17),
         delete: [17; 17),
         insert: "super::",
-        kind: Keyword,
-    },
+        kind: Keyword
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_use_stmt2.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_use_stmt2.snap
index ad156fb440..ee8bf4ca12 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_use_stmt2.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_use_stmt2.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:44:10.859494330Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.030382527Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,13 +10,13 @@ expression: kind_completions
         source_range: [20; 20),
         delete: [20; 20),
         insert: "self",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "super",
         source_range: [20; 20),
         delete: [20; 20),
         insert: "super::",
-        kind: Keyword,
-    },
+        kind: Keyword
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_use_stmt3.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_use_stmt3.snap
index e7b11d532e..b44db276e1 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_use_stmt3.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_use_stmt3.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:44:40.506690279Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.073607133Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,13 +10,13 @@ expression: kind_completions
         source_range: [24; 24),
         delete: [24; 24),
         insert: "self",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "super",
         source_range: [24; 24),
         delete: [24; 24),
         insert: "super::",
-        kind: Keyword,
-    },
+        kind: Keyword
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__last_return_in_block_has_semi1.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__last_return_in_block_has_semi1.snap
index e7069dc0c0..f220d35c26 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__last_return_in_block_has_semi1.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__last_return_in_block_has_semi1.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.082403612Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:23.989188654Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,34 +10,34 @@ expression: kind_completions
         source_range: [83; 83),
         delete: [83; 83),
         insert: "if $0 {}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "loop",
         source_range: [83; 83),
         delete: [83; 83),
         insert: "loop {$0}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "match",
         source_range: [83; 83),
         delete: [83; 83),
         insert: "match $0 {}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "return",
         source_range: [83; 83),
         delete: [83; 83),
         insert: "return $0;",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "while",
         source_range: [83; 83),
         delete: [83; 83),
         insert: "while $0 {}",
-        kind: Keyword,
-    },
+        kind: Keyword
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__last_return_in_block_has_semi2.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__last_return_in_block_has_semi2.snap
index 47beb904bc..d2093acdfd 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__last_return_in_block_has_semi2.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__last_return_in_block_has_semi2.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:44:10.871868390Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.036383875Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,34 +10,34 @@ expression: kind_completions
         source_range: [83; 83),
         delete: [83; 83),
         insert: "if $0 {}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "loop",
         source_range: [83; 83),
         delete: [83; 83),
         insert: "loop {$0}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "match",
         source_range: [83; 83),
         delete: [83; 83),
         insert: "match $0 {}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "return",
         source_range: [83; 83),
         delete: [83; 83),
         insert: "return $0;",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "while",
         source_range: [83; 83),
         delete: [83; 83),
         insert: "while $0 {}",
-        kind: Keyword,
-    },
+        kind: Keyword
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__mod_with_docs.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__mod_with_docs.snap
index f2b26e3930..1da3c3ba20 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__mod_with_docs.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__mod_with_docs.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.093689514Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.066918191Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -12,7 +12,7 @@ expression: kind_completions
         insert: "my",
         kind: Module,
         documentation: Documentation(
-            "Some simple\ndocs describing `mod my`.",
-        ),
-    },
+            "Some simple\ndocs describing `mod my`."
+        )
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__module_items.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__module_items.snap
index cee4898c3e..86bc8679de 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__module_items.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__module_items.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.133106898Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.161888678Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,14 +10,14 @@ expression: kind_completions
         source_range: [89; 89),
         delete: [89; 89),
         insert: "Baz",
-        kind: Enum,
+        kind: Enum
     },
     CompletionItem {
         label: "Foo",
         source_range: [89; 89),
         delete: [89; 89),
         insert: "Foo",
-        kind: Struct,
+        kind: Struct
     },
     CompletionItem {
         label: "quux",
@@ -25,6 +25,6 @@ expression: kind_completions
         delete: [89; 89),
         insert: "quux()$0",
         kind: Function,
-        detail: "fn quux()",
-    },
+        detail: "fn quux()"
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__module_items_in_nested_modules.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__module_items_in_nested_modules.snap
index ce18e5bb7c..9f796b7cae 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__module_items_in_nested_modules.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__module_items_in_nested_modules.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.134417551Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.180517419Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,7 +10,7 @@ expression: kind_completions
         source_range: [101; 101),
         delete: [101; 101),
         insert: "Bar",
-        kind: Struct,
+        kind: Struct
     },
     CompletionItem {
         label: "quux",
@@ -18,6 +18,6 @@ expression: kind_completions
         delete: [101; 101),
         insert: "quux()$0",
         kind: Function,
-        detail: "fn quux()",
-    },
+        detail: "fn quux()"
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__nested_use_tree.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__nested_use_tree.snap
index 4c143d28e8..4920e500eb 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__nested_use_tree.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__nested_use_tree.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.099358768Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.085605313Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,13 +10,13 @@ expression: kind_completions
         source_range: [12; 14),
         delete: [12; 14),
         insert: "Spam",
-        kind: Struct,
+        kind: Struct
     },
     CompletionItem {
         label: "foo",
         source_range: [12; 14),
         delete: [12; 14),
         insert: "foo",
-        kind: Module,
-    },
+        kind: Module
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__no_semi_after_break_continue_in_expr.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__no_semi_after_break_continue_in_expr.snap
index 22e25fe3dc..038e7f4025 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__no_semi_after_break_continue_in_expr.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__no_semi_after_break_continue_in_expr.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.085365816Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:23.999953358Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,48 +10,48 @@ expression: kind_completions
         source_range: [106; 108),
         delete: [106; 108),
         insert: "break",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "continue",
         source_range: [106; 108),
         delete: [106; 108),
         insert: "continue",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "if",
         source_range: [106; 108),
         delete: [106; 108),
         insert: "if $0 {}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "loop",
         source_range: [106; 108),
         delete: [106; 108),
         insert: "loop {$0}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "match",
         source_range: [106; 108),
         delete: [106; 108),
         insert: "match $0 {}",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "return",
         source_range: [106; 108),
         delete: [106; 108),
         insert: "return",
-        kind: Keyword,
+        kind: Keyword
     },
     CompletionItem {
         label: "while",
         source_range: [106; 108),
         delete: [106; 108),
         insert: "while $0 {}",
-        kind: Keyword,
-    },
+        kind: Keyword
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__postfix_completion_works_for_trivial_path_expression.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__postfix_completion_works_for_trivial_path_expression.snap
index fcb2925963..3bbc9e3c41 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__postfix_completion_works_for_trivial_path_expression.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__postfix_completion_works_for_trivial_path_expression.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.118738523Z"
-creator: insta@0.8.1
+created: "2019-04-22T07:37:13.981826301Z"
+creator: insta@0.7.4
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,48 +10,48 @@ expression: kind_completions
         source_range: [76; 76),
         delete: [72; 76),
         insert: "dbg!(bar)",
-        detail: "dbg!(expr)",
+        detail: "dbg!(expr)"
     },
     CompletionItem {
         label: "if",
         source_range: [76; 76),
         delete: [72; 76),
         insert: "if bar {$0}",
-        detail: "if expr {}",
+        detail: "if expr {}"
     },
     CompletionItem {
         label: "match",
         source_range: [76; 76),
         delete: [72; 76),
         insert: "match bar {\n    ${1:_} => {$0\\},\n}",
-        detail: "match expr {}",
+        detail: "match expr {}"
     },
     CompletionItem {
         label: "not",
         source_range: [76; 76),
         delete: [72; 76),
         insert: "!bar",
-        detail: "!expr",
+        detail: "!expr"
     },
     CompletionItem {
         label: "ref",
         source_range: [76; 76),
         delete: [72; 76),
         insert: "&bar",
-        detail: "&expr",
+        detail: "&expr"
     },
     CompletionItem {
         label: "refm",
         source_range: [76; 76),
         delete: [72; 76),
         insert: "&mut bar",
-        detail: "&mut expr",
+        detail: "&mut expr"
     },
     CompletionItem {
         label: "while",
         source_range: [76; 76),
         delete: [72; 76),
         insert: "while bar {\n$0\n}",
-        detail: "while expr {}",
-    },
+        detail: "while expr {}"
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__return_type.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__return_type.snap
index 16dd18431b..ff36df707b 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__return_type.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__return_type.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.140648630Z"
-creator: insta@0.8.1
+created: "2019-04-04T14:52:24.525395600Z"
+creator: insta@0.7.4
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,7 +10,7 @@ expression: kind_completions
         source_range: [47; 47),
         delete: [47; 47),
         insert: "Foo",
-        kind: Struct,
+        kind: Struct
     },
     CompletionItem {
         label: "x",
@@ -18,6 +18,6 @@ expression: kind_completions
         delete: [47; 47),
         insert: "x()$0",
         kind: Function,
-        detail: "fn x()",
-    },
+        detail: "fn x()"
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__self_in_methods.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__self_in_methods.snap
index e1af94870d..baf12cae13 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__self_in_methods.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__self_in_methods.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.141900902Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.174038680Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,13 +10,13 @@ expression: kind_completions
         source_range: [25; 25),
         delete: [25; 25),
         insert: "Self",
-        kind: TypeParam,
+        kind: TypeParam
     },
     CompletionItem {
         label: "self",
         source_range: [25; 25),
         delete: [25; 25),
         insert: "self",
-        kind: Binding,
-    },
+        kind: Binding
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__snippets_in_expressions.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__snippets_in_expressions.snap
index 6f41bf76f9..fce2d64799 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__snippets_in_expressions.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__snippets_in_expressions.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.141901047Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.191576723Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,13 +10,13 @@ expression: kind_completions
         source_range: [17; 17),
         delete: [17; 17),
         insert: "eprintln!(\"$0 = {:?}\", $0);",
-        kind: Snippet,
+        kind: Snippet
     },
     CompletionItem {
         label: "ppd",
         source_range: [17; 17),
         delete: [17; 17),
         insert: "eprintln!(\"$0 = {:#?}\", $0);",
-        kind: Snippet,
-    },
+        kind: Snippet
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__snippets_in_items.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__snippets_in_items.snap
index 1eb0adebea..d2b1a5f0ef 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__snippets_in_items.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__snippets_in_items.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.149234118Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.187670733Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -11,13 +11,13 @@ expression: kind_completions
         delete: [66; 66),
         insert: "#[test]\nfn ${1:feature}() {\n    $0\n}",
         kind: Snippet,
-        lookup: "tfn",
+        lookup: "tfn"
     },
     CompletionItem {
         label: "pub(crate)",
         source_range: [66; 66),
         delete: [66; 66),
         insert: "pub(crate) $0",
-        kind: Snippet,
-    },
+        kind: Snippet
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__struct_associated_const.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__struct_associated_const.snap
index f7bc6177cb..6ad4c5acc5 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__struct_associated_const.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__struct_associated_const.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.101474826Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.093406123Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -13,7 +13,7 @@ expression: kind_completions
         kind: Const,
         detail: "const C: i32 = 42;",
         documentation: Documentation(
-            "An associated const",
-        ),
-    },
+            "An associated const"
+        )
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__struct_associated_method.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__struct_associated_method.snap
index 45080a802c..7c69eebeb3 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__struct_associated_method.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__struct_associated_method.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.102351365Z"
-creator: insta@0.8.1
+created: "2019-02-24T16:33:47.990111169Z"
+creator: insta@0.6.3
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -13,7 +13,7 @@ expression: kind_completions
         kind: Function,
         detail: "fn m()",
         documentation: Documentation(
-            "An associated method",
-        ),
-    },
+            "An associated method"
+        )
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__struct_associated_type.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__struct_associated_type.snap
index f40065286c..583bda2257 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__struct_associated_type.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__struct_associated_type.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.105188762Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.090876030Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -13,7 +13,7 @@ expression: kind_completions
         kind: TypeAlias,
         detail: "type T = i32;",
         documentation: Documentation(
-            "An associated type",
-        ),
-    },
+            "An associated type"
+        )
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__use_item_starting_with_crate.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__use_item_starting_with_crate.snap
index 17e831c840..34e70c35dd 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__use_item_starting_with_crate.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__use_item_starting_with_crate.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.105336210Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.098574884Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,13 +10,13 @@ expression: kind_completions
         source_range: [11; 13),
         delete: [11; 13),
         insert: "Spam",
-        kind: Struct,
+        kind: Struct
     },
     CompletionItem {
         label: "foo",
         source_range: [11; 13),
         delete: [11; 13),
         insert: "foo",
-        kind: Module,
-    },
+        kind: Module
+    }
 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__use_item_starting_with_self.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__use_item_starting_with_self.snap
index d1abc6b5bb..d15f1905ba 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__use_item_starting_with_self.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__use_item_starting_with_self.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.106923266Z"
-creator: insta@0.8.1
+created: "2019-02-18T09:22:24.102063333Z"
+creator: insta@0.6.2
 source: crates/ra_ide_api/src/completion/completion_item.rs
 expression: kind_completions
 ---
@@ -10,6 +10,6 @@ expression: kind_completions
         source_range: [26; 26),
         delete: [26; 26),
         insert: "Bar",
-        kind: Struct,
-    },
+        kind: Struct
+    }
 ]
diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs
index 923008708f..9a0eb2c141 100644
--- a/crates/ra_ide_api/src/diagnostics.rs
+++ b/crates/ra_ide_api/src/diagnostics.rs
@@ -310,30 +310,28 @@ mod tests {
     fn test_unresolved_module_diagnostic() {
         let (analysis, file_id) = single_file("mod foo;");
         let diagnostics = analysis.diagnostics(file_id).unwrap();
-        assert_debug_snapshot_matches!(diagnostics, @r###"
-       ⋮[
-       ⋮    Diagnostic {
-       ⋮        message: "unresolved module",
-       ⋮        range: [0; 8),
-       ⋮        fix: Some(
-       ⋮            SourceChange {
-       ⋮                label: "create module",
-       ⋮                source_file_edits: [],
-       ⋮                file_system_edits: [
-       ⋮                    CreateFile {
-       ⋮                        source_root: SourceRootId(
-       ⋮                            0,
-       ⋮                        ),
-       ⋮                        path: "foo.rs",
-       ⋮                    },
-       ⋮                ],
-       ⋮                cursor_position: None,
-       ⋮            },
-       ⋮        ),
-       ⋮        severity: Error,
-       ⋮    },
-       ⋮]
-        "###);
+        assert_debug_snapshot_matches!(diagnostics, @r####"[
+    Diagnostic {
+        message: "unresolved module",
+        range: [0; 8),
+        fix: Some(
+            SourceChange {
+                label: "create module",
+                source_file_edits: [],
+                file_system_edits: [
+                    CreateFile {
+                        source_root: SourceRootId(
+                            0
+                        ),
+                        path: "foo.rs"
+                    }
+                ],
+                cursor_position: None
+            }
+        ),
+        severity: Error
+    }
+]"####);
     }
 
     #[test]
diff --git a/crates/ra_ide_api/src/display/navigation_target.rs b/crates/ra_ide_api/src/display/navigation_target.rs
index 7f81483f78..1c694cbc9b 100644
--- a/crates/ra_ide_api/src/display/navigation_target.rs
+++ b/crates/ra_ide_api/src/display/navigation_target.rs
@@ -154,10 +154,6 @@ impl NavigationTarget {
                 let (file_id, node) = s.source(db);
                 NavigationTarget::from_named(file_id.original_file(db), &*node)
             }
-            hir::AdtDef::Union(s) => {
-                let (file_id, node) = s.source(db);
-                NavigationTarget::from_named(file_id.original_file(db), &*node)
-            }
             hir::AdtDef::Enum(s) => {
                 let (file_id, node) = s.source(db);
                 NavigationTarget::from_named(file_id.original_file(db), &*node)
@@ -173,10 +169,6 @@ impl NavigationTarget {
                 let (file_id, node) = s.source(db);
                 NavigationTarget::from_named(file_id.original_file(db), &*node)
             }
-            hir::ModuleDef::Union(s) => {
-                let (file_id, node) = s.source(db);
-                NavigationTarget::from_named(file_id.original_file(db), &*node)
-            }
             hir::ModuleDef::Const(s) => {
                 let (file_id, node) = s.source(db);
                 NavigationTarget::from_named(file_id.original_file(db), &*node)
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs
index d3456d5b25..f78348f745 100644
--- a/crates/ra_ide_api/src/lib.rs
+++ b/crates/ra_ide_api/src/lib.rs
@@ -462,11 +462,6 @@ impl Analysis {
         self.with_db(|db| syntax_highlighting::highlight(db, file_id))
     }
 
-    /// Computes syntax highlighting for the given file.
-    pub fn highlight_as_html(&self, file_id: FileId) -> Cancelable<String> {
-        self.with_db(|db| syntax_highlighting::highlight_as_html(db, file_id))
-    }
-
     /// Computes completions at the given position.
     pub fn completions(&self, position: FilePosition) -> Cancelable<Option<Vec<CompletionItem>>> {
         self.with_db(|db| completion::completions(db, position).map(Into::into))
diff --git a/crates/ra_ide_api/src/snapshots/highlighting.html b/crates/ra_ide_api/src/snapshots/highlighting.html
deleted file mode 100644
index bfc0a67b11..0000000000
--- a/crates/ra_ide_api/src/snapshots/highlighting.html
+++ /dev/null
@@ -1,45 +0,0 @@
-
-<style>
-pre {
-    color: #DCDCCC;
-    background-color: #3F3F3F;
-    font-size: 22px;
-}
-
-.comment   { color: #7F9F7F; }
-.string    { color: #CC9393; }
-.function  { color: #93E0E3; }
-.parameter { color: #94BFF3; }
-.builtin   { color: #DD6718; }
-.text      { color: #DCDCCC; }
-.attribute { color: #BFEBBF; }
-.literal   { color: #DFAF8F; }
-.macro     { color: #DFAF8F; }
-
-.keyword           { color: #F0DFAF; }
-.keyword\.unsafe  { color: #F0DFAF; font-weight: bold; }
-.keyword\.control { color: #DC8CC3; }
-
-</style>
-<pre><code>
-<span class="attribute">#</span><span class="attribute">[</span><span class="attribute">derive</span><span class="attribute">(</span><span class="attribute">Clone</span><span class="attribute">,</span><span class="attribute"> </span><span class="attribute">Debug</span><span class="attribute">)</span><span class="attribute">]</span>
-<span class="keyword">struct</span> <span class="function">Foo</span> {
-    <span class="keyword">pub</span> <span class="function">x</span>: <span class="text">i32</span>,
-    <span class="keyword">pub</span> <span class="function">y</span>: <span class="text">i32</span>,
-}
-
-<span class="keyword">fn</span> <span class="function">foo</span>&lt;<span class="type function">T</span>&gt;() -&gt; <span class="type">T</span> {
-    <span class="macro">unimplemented</span><span class="macro">!</span>();
-}
-
-<span class="comment">// comment</span>
-<span class="keyword">fn</span> <span class="function">main</span>() {
-    <span class="macro">println</span><span class="macro">!</span>(<span class="string">"Hello, {}!"</span>, <span class="literal">92</span>);
-
-    <span class="keyword">let</span> <span class="keyword">mut</span> <span class="function">vec</span> = <span class="text">Vec</span>::<span class="text">new</span>();
-    <span class="keyword.control">if</span> <span class="keyword">true</span> {
-        <span class="text">vec</span>.<span class="text">push</span>(<span class="type">Foo</span> { <span class="field">x</span>: <span class="literal">0</span>, <span class="field">y</span>: <span class="literal">1</span> });
-    }
-    <span class="keyword.unsafe">unsafe</span> { <span class="text">vec</span>.<span class="text">set_len</span>(<span class="literal">0</span>); }
-}
-</code></pre>
\ No newline at end of file
diff --git a/crates/ra_ide_api/src/syntax_highlighting.rs b/crates/ra_ide_api/src/syntax_highlighting.rs
index 87e053364c..89f20260f5 100644
--- a/crates/ra_ide_api/src/syntax_highlighting.rs
+++ b/crates/ra_ide_api/src/syntax_highlighting.rs
@@ -2,7 +2,6 @@ use rustc_hash::FxHashSet;
 
 use ra_syntax::{ast, AstNode, TextRange, Direction, SyntaxKind, SyntaxKind::*, SyntaxElement, T};
 use ra_db::SourceDatabase;
-use ra_prof::profile;
 
 use crate::{FileId, db::RootDatabase};
 
@@ -28,8 +27,6 @@ fn is_control_keyword(kind: SyntaxKind) -> bool {
 }
 
 pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> {
-    let _p = profile("highlight");
-
     let source_file = db.parse(file_id);
 
     // Visited nodes to handle highlighting priorities
@@ -60,7 +57,6 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
                         Some(Def(ModuleDef::Module(_))) => "module",
                         Some(Def(ModuleDef::Function(_))) => "function",
                         Some(Def(ModuleDef::Struct(_))) => "type",
-                        Some(Def(ModuleDef::Union(_))) => "type",
                         Some(Def(ModuleDef::Enum(_))) => "type",
                         Some(Def(ModuleDef::EnumVariant(_))) => "constant",
                         Some(Def(ModuleDef::Const(_))) => "constant",
@@ -114,79 +110,10 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
     res
 }
 
-pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId) -> String {
-    let source_file = db.parse(file_id);
-
-    let mut ranges = highlight(db, file_id);
-    ranges.sort_by_key(|it| it.range.start());
-    // quick non-optimal heuristic to intersect token ranges and highlighted ranges
-    let mut frontier = 0;
-    let mut could_intersect: Vec<&HighlightedRange> = Vec::new();
-
-    let mut buf = String::new();
-    buf.push_str(&STYLE);
-    buf.push_str("<pre><code>");
-    let tokens = source_file.syntax().descendants_with_tokens().filter_map(|it| it.as_token());
-    for token in tokens {
-        could_intersect.retain(|it| token.range().start() <= it.range.end());
-        while let Some(r) = ranges.get(frontier) {
-            if r.range.start() <= token.range().end() {
-                could_intersect.push(r);
-                frontier += 1;
-            } else {
-                break;
-            }
-        }
-        let text = html_escape(&token.text());
-        let classes = could_intersect
-            .iter()
-            .filter(|it| token.range().is_subrange(&it.range))
-            .map(|it| it.tag)
-            .collect::<Vec<_>>();
-        if classes.is_empty() {
-            buf.push_str(&text);
-        } else {
-            let classes = classes.join(" ");
-            buf.push_str(&format!("<span class=\"{}\">{}</span>", classes, text));
-        }
-    }
-    buf.push_str("</code></pre>");
-    buf
-}
-
-//FIXME: like, real html escaping
-fn html_escape(text: &str) -> String {
-    text.replace("<", "&lt;").replace(">", "&gt;")
-}
-
-const STYLE: &str = "
-<style>
-pre {
-    color: #DCDCCC;
-    background-color: #3F3F3F;
-    font-size: 22px;
-}
-
-.comment   { color: #7F9F7F; }
-.string    { color: #CC9393; }
-.function  { color: #93E0E3; }
-.parameter { color: #94BFF3; }
-.builtin   { color: #DD6718; }
-.text      { color: #DCDCCC; }
-.attribute { color: #BFEBBF; }
-.literal   { color: #DFAF8F; }
-.macro     { color: #DFAF8F; }
-
-.keyword           { color: #F0DFAF; }
-.keyword\\.unsafe  { color: #F0DFAF; font-weight: bold; }
-.keyword\\.control { color: #DC8CC3; }
-
-</style>
-";
-
 #[cfg(test)]
 mod tests {
-    use test_utils::{project_dir, read_text, assert_eq_text};
+    use insta::assert_debug_snapshot_matches;
+
     use crate::mock_analysis::single_file;
 
     #[test]
@@ -204,21 +131,15 @@ fn foo<T>() -> T {
 }
 
 // comment
-fn main() {
+fn main() {}
     println!("Hello, {}!", 92);
 
     let mut vec = Vec::new();
-    if true {
-        vec.push(Foo { x: 0, y: 1 });
-    }
+    vec.push(Foo { x: 0, y: 1 });
     unsafe { vec.set_len(0); }
-}
 "#,
         );
-        let dst_file = project_dir().join("crates/ra_ide_api/src/snapshots/highlighting.html");
-        let actual_html = &analysis.highlight_as_html(file_id).unwrap();
-        let expected_html = &read_text(&dst_file);
-        // std::fs::write(dst_file, &actual_html).unwrap();
-        assert_eq_text!(expected_html, actual_html);
+        let result = analysis.highlight(file_id);
+        assert_debug_snapshot_matches!("highlighting", result);
     }
 }
diff --git a/crates/ra_mbe/src/subtree_parser.rs b/crates/ra_mbe/src/subtree_parser.rs
index 709b87a384..9cc989b23a 100644
--- a/crates/ra_mbe/src/subtree_parser.rs
+++ b/crates/ra_mbe/src/subtree_parser.rs
@@ -68,13 +68,13 @@ impl<'a> Parser<'a> {
 
     fn parse<F>(self, f: F) -> Option<tt::TokenTree>
     where
-        F: FnOnce(&dyn TokenSource, &mut dyn TreeSink),
+        F: FnOnce(&mut dyn TokenSource, &mut dyn TreeSink),
     {
         let buffer = TokenBuffer::new(&self.subtree.token_trees[*self.cur_pos..]);
         let mut src = SubtreeTokenSource::new(&buffer);
         let mut sink = OffsetTokenSink { token_pos: 0, error: false };
 
-        f(&src, &mut sink);
+        f(&mut src, &mut sink);
 
         let r = self.finish(sink.token_pos, &mut src);
         if sink.error {
diff --git a/crates/ra_mbe/src/subtree_source.rs b/crates/ra_mbe/src/subtree_source.rs
index 972af4a7c5..c4f79f38a3 100644
--- a/crates/ra_mbe/src/subtree_source.rs
+++ b/crates/ra_mbe/src/subtree_source.rs
@@ -1,6 +1,7 @@
-use ra_parser::{TokenSource};
+use ra_parser::{TokenSource, Token};
 use ra_syntax::{classify_literal, SmolStr, SyntaxKind, SyntaxKind::*, T};
 use std::cell::{RefCell, Cell};
+use std::sync::Arc;
 use tt::buffer::{TokenBuffer, Cursor};
 
 pub(crate) trait Querier {
@@ -65,7 +66,7 @@ impl<'a> SubtreeWalk<'a> {
         return cached[pos].clone();
     }
 
-    fn collect_token_trees(&mut self, n: usize) -> Vec<tt::TokenTree> {
+    fn collect_token_trees(&self, n: usize) -> Vec<tt::TokenTree> {
         let mut res = vec![];
 
         let mut pos = 0;
@@ -117,43 +118,59 @@ impl<'a> Querier for SubtreeWalk<'a> {
 }
 
 pub(crate) struct SubtreeTokenSource<'a> {
-    walker: SubtreeWalk<'a>,
+    walker: Arc<SubtreeWalk<'a>>,
+    curr: (Token, usize),
 }
 
 impl<'a> SubtreeTokenSource<'a> {
     pub fn new(buffer: &'a TokenBuffer) -> SubtreeTokenSource<'a> {
-        SubtreeTokenSource { walker: SubtreeWalk::new(buffer.begin()) }
+        let mut res = SubtreeTokenSource {
+            walker: Arc::new(SubtreeWalk::new(buffer.begin())),
+            curr: (Token { kind: EOF, is_jointed_to_next: false }, 0),
+        };
+        res.curr = (res.mk_token(0), 0);
+        res
     }
 
-    pub fn querier<'b>(&'a self) -> &'b SubtreeWalk<'a>
-    where
-        'a: 'b,
-    {
-        &self.walker
+    pub fn querier(&self) -> Arc<SubtreeWalk<'a>> {
+        self.walker.clone()
     }
 
     pub(crate) fn bump_n(&mut self, parsed_tokens: usize) -> Vec<tt::TokenTree> {
         let res = self.walker.collect_token_trees(parsed_tokens);
         res
     }
+
+    fn mk_token(&self, pos: usize) -> Token {
+        match self.walker.get(pos) {
+            Some(tt) => Token { kind: tt.kind, is_jointed_to_next: tt.is_joint_to_next },
+            None => Token { kind: EOF, is_jointed_to_next: false },
+        }
+    }
 }
 
 impl<'a> TokenSource for SubtreeTokenSource<'a> {
-    fn token_kind(&self, pos: usize) -> SyntaxKind {
-        if let Some(tok) = self.walker.get(pos) {
-            tok.kind
-        } else {
-            SyntaxKind::EOF
-        }
+    fn current(&self) -> Token {
+        self.curr.0
     }
-    fn is_token_joint_to_next(&self, pos: usize) -> bool {
-        match self.walker.get(pos) {
-            Some(t) => t.is_joint_to_next,
-            _ => false,
+
+    /// Lookahead n token
+    fn lookahead_nth(&self, n: usize) -> Token {
+        self.mk_token(self.curr.1 + n)
+    }
+
+    /// bump cursor to next token
+    fn bump(&mut self) {
+        if self.current().kind == EOF {
+            return;
         }
+
+        self.curr = (self.mk_token(self.curr.1 + 1), self.curr.1 + 1)
     }
-    fn is_keyword(&self, pos: usize, kw: &str) -> bool {
-        match self.walker.get(pos) {
+
+    /// Is the current token a specified keyword?
+    fn is_keyword(&self, kw: &str) -> bool {
+        match self.walker.get(self.curr.1) {
             Some(t) => t.text == *kw,
             _ => false,
         }
diff --git a/crates/ra_mbe/src/syntax_bridge.rs b/crates/ra_mbe/src/syntax_bridge.rs
index 0a75305b47..0a7e50c4e2 100644
--- a/crates/ra_mbe/src/syntax_bridge.rs
+++ b/crates/ra_mbe/src/syntax_bridge.rs
@@ -45,17 +45,25 @@ pub fn syntax_node_to_token_tree(node: &SyntaxNode) -> Option<(tt::Subtree, Toke
 //
 //
 
-/// Parses the token tree (result of macro expansion) to an expression
-pub fn token_tree_to_expr(tt: &tt::Subtree) -> Result<TreeArc<ast::Expr>, ExpandError> {
+fn token_tree_to_syntax_node<F>(tt: &tt::Subtree, f: F) -> Result<TreeArc<SyntaxNode>, ExpandError>
+where
+    F: Fn(&mut ra_parser::TokenSource, &mut ra_parser::TreeSink),
+{
     let buffer = tt::buffer::TokenBuffer::new(&[tt.clone().into()]);
-    let token_source = SubtreeTokenSource::new(&buffer);
-    let mut tree_sink = TtTreeSink::new(token_source.querier());
-    ra_parser::parse_expr(&token_source, &mut tree_sink);
+    let mut token_source = SubtreeTokenSource::new(&buffer);
+    let querier = token_source.querier();
+    let mut tree_sink = TtTreeSink::new(querier.as_ref());
+    f(&mut token_source, &mut tree_sink);
     if tree_sink.roots.len() != 1 {
         return Err(ExpandError::ConversionError);
     }
 
-    let syntax = tree_sink.inner.finish();
+    Ok(tree_sink.inner.finish())
+}
+
+/// Parses the token tree (result of macro expansion) to an expression
+pub fn token_tree_to_expr(tt: &tt::Subtree) -> Result<TreeArc<ast::Expr>, ExpandError> {
+    let syntax = token_tree_to_syntax_node(tt, ra_parser::parse_expr)?;
     ast::Expr::cast(&syntax)
         .map(|m| m.to_owned())
         .ok_or_else(|| crate::ExpandError::ConversionError)
@@ -63,28 +71,13 @@ pub fn token_tree_to_expr(tt: &tt::Subtree) -> Result<TreeArc<ast::Expr>, Expand
 
 /// Parses the token tree (result of macro expansion) to a Pattern
 pub fn token_tree_to_pat(tt: &tt::Subtree) -> Result<TreeArc<ast::Pat>, ExpandError> {
-    let buffer = tt::buffer::TokenBuffer::new(&[tt.clone().into()]);
-    let token_source = SubtreeTokenSource::new(&buffer);
-    let mut tree_sink = TtTreeSink::new(token_source.querier());
-    ra_parser::parse_pat(&token_source, &mut tree_sink);
-    if tree_sink.roots.len() != 1 {
-        return Err(ExpandError::ConversionError);
-    }
-
-    let syntax = tree_sink.inner.finish();
+    let syntax = token_tree_to_syntax_node(tt, ra_parser::parse_pat)?;
     ast::Pat::cast(&syntax).map(|m| m.to_owned()).ok_or_else(|| ExpandError::ConversionError)
 }
 
 /// Parses the token tree (result of macro expansion) to a Type
 pub fn token_tree_to_ty(tt: &tt::Subtree) -> Result<TreeArc<ast::TypeRef>, ExpandError> {
-    let buffer = tt::buffer::TokenBuffer::new(&[tt.clone().into()]);
-    let token_source = SubtreeTokenSource::new(&buffer);
-    let mut tree_sink = TtTreeSink::new(token_source.querier());
-    ra_parser::parse_ty(&token_source, &mut tree_sink);
-    if tree_sink.roots.len() != 1 {
-        return Err(ExpandError::ConversionError);
-    }
-    let syntax = tree_sink.inner.finish();
+    let syntax = token_tree_to_syntax_node(tt, ra_parser::parse_ty)?;
     ast::TypeRef::cast(&syntax).map(|m| m.to_owned()).ok_or_else(|| ExpandError::ConversionError)
 }
 
@@ -92,14 +85,7 @@ pub fn token_tree_to_ty(tt: &tt::Subtree) -> Result<TreeArc<ast::TypeRef>, Expan
 pub fn token_tree_to_macro_stmts(
     tt: &tt::Subtree,
 ) -> Result<TreeArc<ast::MacroStmts>, ExpandError> {
-    let buffer = tt::buffer::TokenBuffer::new(&[tt.clone().into()]);
-    let token_source = SubtreeTokenSource::new(&buffer);
-    let mut tree_sink = TtTreeSink::new(token_source.querier());
-    ra_parser::parse_macro_stmts(&token_source, &mut tree_sink);
-    if tree_sink.roots.len() != 1 {
-        return Err(ExpandError::ConversionError);
-    }
-    let syntax = tree_sink.inner.finish();
+    let syntax = token_tree_to_syntax_node(tt, ra_parser::parse_macro_stmts)?;
     ast::MacroStmts::cast(&syntax).map(|m| m.to_owned()).ok_or_else(|| ExpandError::ConversionError)
 }
 
@@ -107,24 +93,13 @@ pub fn token_tree_to_macro_stmts(
 pub fn token_tree_to_macro_items(
     tt: &tt::Subtree,
 ) -> Result<TreeArc<ast::MacroItems>, ExpandError> {
-    let buffer = tt::buffer::TokenBuffer::new(&[tt.clone().into()]);
-    let token_source = SubtreeTokenSource::new(&buffer);
-    let mut tree_sink = TtTreeSink::new(token_source.querier());
-    ra_parser::parse_macro_items(&token_source, &mut tree_sink);
-    if tree_sink.roots.len() != 1 {
-        return Err(ExpandError::ConversionError);
-    }
-    let syntax = tree_sink.inner.finish();
+    let syntax = token_tree_to_syntax_node(tt, ra_parser::parse_macro_items)?;
     ast::MacroItems::cast(&syntax).map(|m| m.to_owned()).ok_or_else(|| ExpandError::ConversionError)
 }
 
 /// Parses the token tree (result of macro expansion) as a sequence of items
 pub fn token_tree_to_ast_item_list(tt: &tt::Subtree) -> TreeArc<ast::SourceFile> {
-    let buffer = tt::buffer::TokenBuffer::new(&[tt.clone().into()]);
-    let token_source = SubtreeTokenSource::new(&buffer);
-    let mut tree_sink = TtTreeSink::new(token_source.querier());
-    ra_parser::parse(&token_source, &mut tree_sink);
-    let syntax = tree_sink.inner.finish();
+    let syntax = token_tree_to_syntax_node(tt, ra_parser::parse).unwrap();
     ast::SourceFile::cast(&syntax).unwrap().to_owned()
 }
 
diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs
index 7718fbe6a1..6728e395fa 100644
--- a/crates/ra_parser/src/grammar/items.rs
+++ b/crates/ra_parser/src/grammar/items.rs
@@ -103,7 +103,7 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker, flavor: ItemFlavor) -> Resul
         p.bump_remap(T![auto]);
         has_mods = true;
     }
-    if p.at(IDENT) && p.at_contextual_kw("default") && p.nth(1) == T![impl] {
+    if p.at(IDENT) && p.at_contextual_kw("default") && p.nth(1) == T![impl ] {
         p.bump_remap(T![default]);
         has_mods = true;
     }
@@ -161,7 +161,7 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker, flavor: ItemFlavor) -> Resul
 
         // test unsafe_default_impl
         // unsafe default impl Foo {}
-        T![impl] => {
+        T![impl ] => {
             traits::impl_block(p);
             m.complete(p, IMPL_BLOCK);
         }
diff --git a/crates/ra_parser/src/grammar/items/traits.rs b/crates/ra_parser/src/grammar/items/traits.rs
index 5fcacfbffc..09ab3bfd4e 100644
--- a/crates/ra_parser/src/grammar/items/traits.rs
+++ b/crates/ra_parser/src/grammar/items/traits.rs
@@ -44,7 +44,7 @@ pub(crate) fn trait_item_list(p: &mut Parser) {
 // test impl_block
 // impl Foo {}
 pub(super) fn impl_block(p: &mut Parser) {
-    assert!(p.at(T![impl]));
+    assert!(p.at(T![impl ]));
     p.bump();
     if choose_type_params_over_qpath(p) {
         type_params::opt_type_param_list(p);
@@ -130,7 +130,7 @@ fn choose_type_params_over_qpath(p: &Parser) -> bool {
 // impl impl NotType {}
 // impl Trait2 for impl NotType {}
 pub(crate) fn impl_type(p: &mut Parser) {
-    if p.at(T![impl]) {
+    if p.at(T![impl ]) {
         p.error("expected trait or type");
         return;
     }
diff --git a/crates/ra_parser/src/grammar/type_params.rs b/crates/ra_parser/src/grammar/type_params.rs
index ef59b59d3e..4bbfed7803 100644
--- a/crates/ra_parser/src/grammar/type_params.rs
+++ b/crates/ra_parser/src/grammar/type_params.rs
@@ -150,7 +150,7 @@ pub(super) fn opt_where_clause(p: &mut Parser) {
 fn is_where_predicate(p: &mut Parser) -> bool {
     match p.current() {
         LIFETIME => true,
-        T![impl] => false,
+        T![impl ] => false,
         token => types::TYPE_FIRST.contains(token),
     }
 }
@@ -170,7 +170,7 @@ fn where_predicate(p: &mut Parser) {
                 p.error("expected colon");
             }
         }
-        T![impl] => {
+        T![impl ] => {
             p.error("expected lifetime or type");
         }
         _ => {
diff --git a/crates/ra_parser/src/grammar/types.rs b/crates/ra_parser/src/grammar/types.rs
index c0b7225696..438e3ab0e4 100644
--- a/crates/ra_parser/src/grammar/types.rs
+++ b/crates/ra_parser/src/grammar/types.rs
@@ -25,7 +25,7 @@ fn type_with_bounds_cond(p: &mut Parser, allow_bounds: bool) {
         T![_] => placeholder_type(p),
         T![fn] | T![unsafe] | T![extern] => fn_pointer_type(p),
         T![for] => for_type(p),
-        T![impl] => impl_trait_type(p),
+        T![impl ] => impl_trait_type(p),
         T![dyn ] => dyn_trait_type(p),
         // Some path types are not allowed to have bounds (no plus)
         T![<] => path_type_(p, allow_bounds),
@@ -221,7 +221,7 @@ pub(super) fn for_type(p: &mut Parser) {
 // test impl_trait_type
 // type A = impl Iterator<Item=Foo<'a>> + 'a;
 fn impl_trait_type(p: &mut Parser) {
-    assert!(p.at(T![impl]));
+    assert!(p.at(T![impl ]));
     let m = p.start();
     p.bump();
     type_params::bounds_without_colon(p);
diff --git a/crates/ra_parser/src/lib.rs b/crates/ra_parser/src/lib.rs
index 697d1b7949..3d88be6425 100644
--- a/crates/ra_parser/src/lib.rs
+++ b/crates/ra_parser/src/lib.rs
@@ -31,12 +31,26 @@ pub struct ParseError(pub String);
 ///
 /// Hopefully this will allow us to treat text and token trees in the same way!
 pub trait TokenSource {
+    fn current(&self) -> Token;
+
+    /// Lookahead n token
+    fn lookahead_nth(&self, n: usize) -> Token;
+
+    /// bump cursor to next token
+    fn bump(&mut self);
+
+    /// Is the current token a specified keyword?
+    fn is_keyword(&self, kw: &str) -> bool;
+}
+
+/// `TokenCursor` abstracts the cursor of `TokenSource` operates one.
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub struct Token {
     /// What is the current token?
-    fn token_kind(&self, pos: usize) -> SyntaxKind;
+    pub kind: SyntaxKind,
+
     /// Is the current token joined to the next one (`> >` vs `>>`).
-    fn is_token_joint_to_next(&self, pos: usize) -> bool;
-    /// Is the current token a specified keyword?
-    fn is_keyword(&self, pos: usize, kw: &str) -> bool;
+    pub is_jointed_to_next: bool,
 }
 
 /// `TreeSink` abstracts details of a particular syntax tree implementation.
@@ -54,7 +68,7 @@ pub trait TreeSink {
     fn error(&mut self, error: ParseError);
 }
 
-fn parse_from_tokens<F>(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink, f: F)
+fn parse_from_tokens<F>(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink, f: F)
 where
     F: FnOnce(&mut parser::Parser),
 {
@@ -65,61 +79,65 @@ where
 }
 
 /// Parse given tokens into the given sink as a rust file.
-pub fn parse(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
+pub fn parse(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) {
     parse_from_tokens(token_source, tree_sink, grammar::root);
 }
 
 /// Parse given tokens into the given sink as a path
-pub fn parse_path(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
+pub fn parse_path(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) {
     parse_from_tokens(token_source, tree_sink, grammar::path);
 }
 
 /// Parse given tokens into the given sink as a expression
-pub fn parse_expr(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
+pub fn parse_expr(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) {
     parse_from_tokens(token_source, tree_sink, grammar::expr);
 }
 
 /// Parse given tokens into the given sink as a ty
-pub fn parse_ty(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
+pub fn parse_ty(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) {
     parse_from_tokens(token_source, tree_sink, grammar::type_);
 }
 
 /// Parse given tokens into the given sink as a pattern
-pub fn parse_pat(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
+pub fn parse_pat(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) {
     parse_from_tokens(token_source, tree_sink, grammar::pattern);
 }
 
 /// Parse given tokens into the given sink as a statement
-pub fn parse_stmt(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink, with_semi: bool) {
+pub fn parse_stmt(
+    token_source: &mut dyn TokenSource,
+    tree_sink: &mut dyn TreeSink,
+    with_semi: bool,
+) {
     parse_from_tokens(token_source, tree_sink, |p| grammar::stmt(p, with_semi));
 }
 
 /// Parse given tokens into the given sink as a block
-pub fn parse_block(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
+pub fn parse_block(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) {
     parse_from_tokens(token_source, tree_sink, grammar::block);
 }
 
-pub fn parse_meta(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
+pub fn parse_meta(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) {
     parse_from_tokens(token_source, tree_sink, grammar::meta_item);
 }
 
 /// Parse given tokens into the given sink as an item
-pub fn parse_item(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
+pub fn parse_item(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) {
     parse_from_tokens(token_source, tree_sink, grammar::item);
 }
 
 /// Parse given tokens into the given sink as an visibility qualifier
-pub fn parse_vis(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
+pub fn parse_vis(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) {
     parse_from_tokens(token_source, tree_sink, |p| {
         grammar::opt_visibility(p);
     });
 }
 
-pub fn parse_macro_items(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
+pub fn parse_macro_items(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) {
     parse_from_tokens(token_source, tree_sink, grammar::macro_items);
 }
 
-pub fn parse_macro_stmts(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
+pub fn parse_macro_stmts(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) {
     parse_from_tokens(token_source, tree_sink, grammar::macro_stmts);
 }
 
@@ -140,7 +158,7 @@ impl Reparser {
     ///
     /// Tokens must start with `{`, end with `}` and form a valid brace
     /// sequence.
-    pub fn parse(self, token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
+    pub fn parse(self, token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) {
         let Reparser(r) = self;
         let mut p = parser::Parser::new(token_source);
         r(&mut p);
diff --git a/crates/ra_parser/src/parser.rs b/crates/ra_parser/src/parser.rs
index 4434dfb096..8f654f04c0 100644
--- a/crates/ra_parser/src/parser.rs
+++ b/crates/ra_parser/src/parser.rs
@@ -19,15 +19,14 @@ use crate::{
 /// "start expression, consume number literal,
 /// finish expression". See `Event` docs for more.
 pub(crate) struct Parser<'t> {
-    token_source: &'t dyn TokenSource,
-    token_pos: usize,
+    token_source: &'t mut dyn TokenSource,
     events: Vec<Event>,
     steps: Cell<u32>,
 }
 
 impl<'t> Parser<'t> {
-    pub(super) fn new(token_source: &'t dyn TokenSource) -> Parser<'t> {
-        Parser { token_source, token_pos: 0, events: Vec::new(), steps: Cell::new(0) }
+    pub(super) fn new(token_source: &'t mut dyn TokenSource) -> Parser<'t> {
+        Parser { token_source, events: Vec::new(), steps: Cell::new(0) }
     }
 
     pub(crate) fn finish(self) -> Vec<Event> {
@@ -49,7 +48,7 @@ impl<'t> Parser<'t> {
         let c1 = self.nth(0);
         let c2 = self.nth(1);
 
-        if self.token_source.is_token_joint_to_next(self.token_pos) {
+        if self.token_source.current().is_jointed_to_next {
             Some((c1, c2))
         } else {
             None
@@ -64,8 +63,8 @@ impl<'t> Parser<'t> {
         let c1 = self.nth(0);
         let c2 = self.nth(1);
         let c3 = self.nth(2);
-        if self.token_source.is_token_joint_to_next(self.token_pos)
-            && self.token_source.is_token_joint_to_next(self.token_pos + 1)
+        if self.token_source.current().is_jointed_to_next
+            && self.token_source.lookahead_nth(1).is_jointed_to_next
         {
             Some((c1, c2, c3))
         } else {
@@ -76,6 +75,8 @@ impl<'t> Parser<'t> {
     /// Lookahead operation: returns the kind of the next nth
     /// token.
     pub(crate) fn nth(&self, n: usize) -> SyntaxKind {
+        assert!(n <= 3);
+
         let steps = self.steps.get();
         assert!(steps <= 10_000_000, "the parser seems stuck");
         self.steps.set(steps + 1);
@@ -86,7 +87,7 @@ impl<'t> Parser<'t> {
         let mut i = 0;
 
         loop {
-            let mut kind = self.token_source.token_kind(self.token_pos + i);
+            let mut kind = self.token_source.lookahead_nth(i).kind;
             if let Some((composited, step)) = self.is_composite(kind, i) {
                 kind = composited;
                 i += step;
@@ -115,7 +116,7 @@ impl<'t> Parser<'t> {
 
     /// Checks if the current token is contextual keyword with text `t`.
     pub(crate) fn at_contextual_kw(&self, kw: &str) -> bool {
-        self.token_source.is_keyword(self.token_pos, kw)
+        self.token_source.is_keyword(kw)
     }
 
     /// Starts a new node in the syntax tree. All nodes and tokens
@@ -130,12 +131,12 @@ impl<'t> Parser<'t> {
     /// Advances the parser by one token unconditionally
     /// Mainly use in `token_tree` parsing
     pub(crate) fn bump_raw(&mut self) {
-        let mut kind = self.token_source.token_kind(self.token_pos);
+        let mut kind = self.token_source.current().kind;
 
         // Skip dollars, do_bump will eat these later
         let mut i = 0;
         while kind == SyntaxKind::L_DOLLAR || kind == SyntaxKind::R_DOLLAR {
-            kind = self.token_source.token_kind(self.token_pos + i);
+            kind = self.token_source.lookahead_nth(i).kind;
             i += 1;
         }
 
@@ -236,7 +237,11 @@ impl<'t> Parser<'t> {
 
     fn do_bump(&mut self, kind: SyntaxKind, n_raw_tokens: u8) {
         self.eat_dollars();
-        self.token_pos += usize::from(n_raw_tokens);
+
+        for _ in 0..n_raw_tokens {
+            self.token_source.bump();
+        }
+
         self.push_event(Event::Token { kind, n_raw_tokens });
     }
 
@@ -249,10 +254,14 @@ impl<'t> Parser<'t> {
         // We assume the dollars will not occuried between
         // mult-byte tokens
 
-        let jn1 = self.token_source.is_token_joint_to_next(self.token_pos + n);
-        let la2 = self.token_source.token_kind(self.token_pos + n + 1);
-        let jn2 = self.token_source.is_token_joint_to_next(self.token_pos + n + 1);
-        let la3 = self.token_source.token_kind(self.token_pos + n + 2);
+        let first = self.token_source.lookahead_nth(n);
+        let second = self.token_source.lookahead_nth(n + 1);
+        let third = self.token_source.lookahead_nth(n + 2);
+
+        let jn1 = first.is_jointed_to_next;
+        let la2 = second.kind;
+        let jn2 = second.is_jointed_to_next;
+        let la3 = third.kind;
 
         match kind {
             T![.] if jn1 && la2 == T![.] && jn2 && la3 == T![.] => Some((T![...], 3)),
@@ -271,9 +280,9 @@ impl<'t> Parser<'t> {
 
     fn eat_dollars(&mut self) {
         loop {
-            match self.token_source.token_kind(self.token_pos) {
+            match self.token_source.current().kind {
                 k @ SyntaxKind::L_DOLLAR | k @ SyntaxKind::R_DOLLAR => {
-                    self.token_pos += 1;
+                    self.token_source.bump();
                     self.push_event(Event::Token { kind: k, n_raw_tokens: 1 });
                 }
                 _ => {
@@ -286,9 +295,9 @@ impl<'t> Parser<'t> {
     pub(crate) fn eat_l_dollars(&mut self) -> usize {
         let mut ate_count = 0;
         loop {
-            match self.token_source.token_kind(self.token_pos) {
+            match self.token_source.current().kind {
                 k @ SyntaxKind::L_DOLLAR => {
-                    self.token_pos += 1;
+                    self.token_source.bump();
                     self.push_event(Event::Token { kind: k, n_raw_tokens: 1 });
                     ate_count += 1;
                 }
@@ -302,9 +311,9 @@ impl<'t> Parser<'t> {
     pub(crate) fn eat_r_dollars(&mut self, max_count: usize) -> usize {
         let mut ate_count = 0;
         loop {
-            match self.token_source.token_kind(self.token_pos) {
+            match self.token_source.current().kind {
                 k @ SyntaxKind::R_DOLLAR => {
-                    self.token_pos += 1;
+                    self.token_source.bump();
                     self.push_event(Event::Token { kind: k, n_raw_tokens: 1 });
                     ate_count += 1;
 
@@ -320,12 +329,12 @@ impl<'t> Parser<'t> {
     }
 
     pub(crate) fn at_l_dollar(&self) -> bool {
-        let kind = self.token_source.token_kind(self.token_pos);
+        let kind = self.token_source.current().kind;
         (kind == SyntaxKind::L_DOLLAR)
     }
 
     pub(crate) fn at_r_dollar(&self) -> bool {
-        let kind = self.token_source.token_kind(self.token_pos);
+        let kind = self.token_source.current().kind;
         (kind == SyntaxKind::R_DOLLAR)
     }
 }
diff --git a/crates/ra_syntax/src/parsing.rs b/crates/ra_syntax/src/parsing.rs
index 15d69c5ab0..4c1fa6c4f3 100644
--- a/crates/ra_syntax/src/parsing.rs
+++ b/crates/ra_syntax/src/parsing.rs
@@ -17,8 +17,8 @@ pub(crate) use self::reparsing::incremental_reparse;
 
 pub(crate) fn parse_text(text: &str) -> (GreenNode, Vec<SyntaxError>) {
     let tokens = tokenize(&text);
-    let token_source = text_token_source::TextTokenSource::new(text, &tokens);
+    let mut token_source = text_token_source::TextTokenSource::new(text, &tokens);
     let mut tree_sink = text_tree_sink::TextTreeSink::new(text, &tokens);
-    ra_parser::parse(&token_source, &mut tree_sink);
+    ra_parser::parse(&mut token_source, &mut tree_sink);
     tree_sink.finish()
 }
diff --git a/crates/ra_syntax/src/parsing/reparsing.rs b/crates/ra_syntax/src/parsing/reparsing.rs
index 6de02a15a7..3b6687f61b 100644
--- a/crates/ra_syntax/src/parsing/reparsing.rs
+++ b/crates/ra_syntax/src/parsing/reparsing.rs
@@ -85,9 +85,9 @@ fn reparse_block<'node>(
     if !is_balanced(&tokens) {
         return None;
     }
-    let token_source = TextTokenSource::new(&text, &tokens);
+    let mut token_source = TextTokenSource::new(&text, &tokens);
     let mut tree_sink = TextTreeSink::new(&text, &tokens);
-    reparser.parse(&token_source, &mut tree_sink);
+    reparser.parse(&mut token_source, &mut tree_sink);
     let (green, new_errors) = tree_sink.finish();
     Some((node.replace_with(green), new_errors, node.range()))
 }
diff --git a/crates/ra_syntax/src/parsing/text_token_source.rs b/crates/ra_syntax/src/parsing/text_token_source.rs
index a6277f66fc..71d2947f77 100644
--- a/crates/ra_syntax/src/parsing/text_token_source.rs
+++ b/crates/ra_syntax/src/parsing/text_token_source.rs
@@ -1,7 +1,8 @@
 use ra_parser::TokenSource;
+use ra_parser::Token as PToken;
 
 use crate::{
-    SyntaxKind, SyntaxKind::EOF, TextRange, TextUnit,
+    SyntaxKind::EOF, TextRange, TextUnit,
     parsing::lexer::Token,
 };
 
@@ -23,31 +24,50 @@ pub(crate) struct TextTokenSource<'t> {
     /// ```
     /// tokens: `[struct, Foo, {, }]`
     tokens: Vec<Token>,
+
+    /// Current token and position
+    curr: (PToken, usize),
 }
 
 impl<'t> TokenSource for TextTokenSource<'t> {
-    fn token_kind(&self, pos: usize) -> SyntaxKind {
-        if !(pos < self.tokens.len()) {
-            return EOF;
-        }
-        self.tokens[pos].kind
+    fn current(&self) -> PToken {
+        return self.curr.0;
     }
-    fn is_token_joint_to_next(&self, pos: usize) -> bool {
-        if !(pos + 1 < self.tokens.len()) {
-            return true;
+
+    fn lookahead_nth(&self, n: usize) -> PToken {
+        mk_token(self.curr.1 + n, &self.start_offsets, &self.tokens)
+    }
+
+    fn bump(&mut self) {
+        if self.curr.0.kind == EOF {
+            return;
         }
-        self.start_offsets[pos] + self.tokens[pos].len == self.start_offsets[pos + 1]
+
+        let pos = self.curr.1 + 1;
+        self.curr = (mk_token(pos, &self.start_offsets, &self.tokens), pos);
     }
-    fn is_keyword(&self, pos: usize, kw: &str) -> bool {
+
+    fn is_keyword(&self, kw: &str) -> bool {
+        let pos = self.curr.1;
         if !(pos < self.tokens.len()) {
             return false;
         }
         let range = TextRange::offset_len(self.start_offsets[pos], self.tokens[pos].len);
-
         self.text[range] == *kw
     }
 }
 
+fn mk_token(pos: usize, start_offsets: &[TextUnit], tokens: &[Token]) -> PToken {
+    let kind = tokens.get(pos).map(|t| t.kind).unwrap_or(EOF);
+    let is_jointed_to_next = if pos + 1 < start_offsets.len() {
+        start_offsets[pos] + tokens[pos].len == start_offsets[pos + 1]
+    } else {
+        false
+    };
+
+    PToken { kind, is_jointed_to_next }
+}
+
 impl<'t> TextTokenSource<'t> {
     /// Generate input from tokens(expect comment and whitespace).
     pub fn new(text: &'t str, raw_tokens: &'t [Token]) -> TextTokenSource<'t> {
@@ -62,6 +82,7 @@ impl<'t> TextTokenSource<'t> {
             len += token.len;
         }
 
-        TextTokenSource { text, start_offsets, tokens }
+        let first = mk_token(0, &start_offsets, &tokens);
+        TextTokenSource { text, start_offsets, tokens, curr: (first, 0) }
     }
 }


Test patch:
diff --git a/crates/ra_ide_api/src/display/snapshots/tests__file_structure.snap b/crates/ra_ide_api/src/display/snapshots/tests__file_structure.snap
index 3097977de6..32dd994849 100644
--- a/crates/ra_ide_api/src/display/snapshots/tests__file_structure.snap
+++ b/crates/ra_ide_api/src/display/snapshots/tests__file_structure.snap
@@ -1,6 +1,6 @@
 ---
-created: "2019-05-23T22:23:35.168422050Z"
-creator: insta@0.8.1
+created: "2019-04-08T09:44:50.196004400Z"
+creator: insta@0.7.4
 source: crates/ra_ide_api/src/display/structure.rs
 expression: structure
 ---
@@ -12,20 +12,20 @@ expression: structure
         node_range: [1; 26),
         kind: STRUCT_DEF,
         detail: None,
-        deprecated: false,
+        deprecated: false
     },
     StructureNode {
         parent: Some(
-            0,
+            0
         ),
         label: "x",
         navigation_range: [18; 19),
         node_range: [18; 24),
         kind: NAMED_FIELD_DEF,
         detail: Some(
-            "i32",
+            "i32"
         ),
-        deprecated: false,
+        deprecated: false
     },
     StructureNode {
         parent: None,
@@ -34,46 +34,46 @@ expression: structure
         node_range: [28; 158),
         kind: MODULE,
         detail: None,
-        deprecated: false,
+        deprecated: false
     },
     StructureNode {
         parent: Some(
-            2,
+            2
         ),
         label: "bar1",
         navigation_range: [43; 47),
         node_range: [40; 52),
         kind: FN_DEF,
         detail: Some(
-            "fn()",
+            "fn()"
         ),
-        deprecated: false,
+        deprecated: false
     },
     StructureNode {
         parent: Some(
-            2,
+            2
         ),
         label: "bar2",
         navigation_range: [60; 64),
         node_range: [57; 81),
         kind: FN_DEF,
         detail: Some(
-            "fn<T>(t: T) -> T",
+            "fn<T>(t: T) -> T"
         ),
-        deprecated: false,
+        deprecated: false
     },
     StructureNode {
         parent: Some(
-            2,
+            2
         ),
         label: "bar3",
         navigation_range: [89; 93),
         node_range: [86; 156),
         kind: FN_DEF,
         detail: Some(
-            "fn<A, B>(a: A, b: B) -> Vec< u32 >",
+            "fn<A, B>(a: A, b: B) -> Vec< u32 >"
         ),
-        deprecated: false,
+        deprecated: false
     },
     StructureNode {
         parent: None,
@@ -82,29 +82,29 @@ expression: structure
         node_range: [160; 180),
         kind: ENUM_DEF,
         detail: None,
-        deprecated: false,
+        deprecated: false
     },
     StructureNode {
         parent: Some(
-            6,
+            6
         ),
         label: "X",
         navigation_range: [169; 170),
         node_range: [169; 170),
         kind: ENUM_VARIANT,
         detail: None,
-        deprecated: false,
+        deprecated: false
     },
     StructureNode {
         parent: Some(
-            6,
+            6
         ),
         label: "Y",
         navigation_range: [172; 173),
         node_range: [172; 178),
         kind: ENUM_VARIANT,
         detail: None,
-        deprecated: false,
+        deprecated: false
     },
     StructureNode {
         parent: None,
@@ -113,9 +113,9 @@ expression: structure
         node_range: [181; 193),
         kind: TYPE_ALIAS_DEF,
         detail: Some(
-            "()",
+            "()"
         ),
-        deprecated: false,
+        deprecated: false
     },
     StructureNode {
         parent: None,
@@ -124,9 +124,9 @@ expression: structure
         node_range: [194; 213),
         kind: STATIC_DEF,
         detail: Some(
-            "i32",
+            "i32"
         ),
-        deprecated: false,
+        deprecated: false
     },
     StructureNode {
         parent: None,
@@ -135,9 +135,9 @@ expression: structure
         node_range: [214; 232),
         kind: CONST_DEF,
         detail: Some(
-            "i32",
+            "i32"
         ),
-        deprecated: false,
+        deprecated: false
     },
     StructureNode {
         parent: None,
@@ -146,7 +146,7 @@ expression: structure
         node_range: [234; 243),
         kind: IMPL_BLOCK,
         detail: None,
-        deprecated: false,
+        deprecated: false
     },
     StructureNode {
         parent: None,
@@ -155,7 +155,7 @@ expression: structure
         node_range: [245; 269),
         kind: IMPL_BLOCK,
         detail: None,
-        deprecated: false,
+        deprecated: false
     },
     StructureNode {
         parent: None,
@@ -164,9 +164,9 @@ expression: structure
         node_range: [271; 301),
         kind: FN_DEF,
         detail: Some(
-            "fn()",
+            "fn()"
         ),
-        deprecated: true,
+        deprecated: true
     },
     StructureNode {
         parent: None,
@@ -175,8 +175,8 @@ expression: structure
         node_range: [303; 359),
         kind: FN_DEF,
         detail: Some(
-            "fn()",
+            "fn()"
         ),
-        deprecated: true,
-    },
+        deprecated: true
+    }
 ]
diff --git a/crates/ra_ide_api/src/snapshots/tests__highlighting.snap b/crates/ra_ide_api/src/snapshots/tests__highlighting.snap
new file mode 100644
index 0000000000..9d4c04db31
--- /dev/null
+++ b/crates/ra_ide_api/src/snapshots/tests__highlighting.snap
@@ -0,0 +1,146 @@
+---
+created: "2019-05-23T12:10:32.628883358Z"
+creator: insta@0.8.1
+source: crates/ra_ide_api/src/syntax_highlighting.rs
+expression: result
+---
+Ok(
+    [
+        HighlightedRange {
+            range: [1; 24),
+            tag: "attribute"
+        },
+        HighlightedRange {
+            range: [25; 31),
+            tag: "keyword"
+        },
+        HighlightedRange {
+            range: [32; 35),
+            tag: "function"
+        },
+        HighlightedRange {
+            range: [42; 45),
+            tag: "keyword"
+        },
+        HighlightedRange {
+            range: [46; 47),
+            tag: "function"
+        },
+        HighlightedRange {
+            range: [49; 52),
+            tag: "text"
+        },
+        HighlightedRange {
+            range: [58; 61),
+            tag: "keyword"
+        },
+        HighlightedRange {
+            range: [62; 63),
+            tag: "function"
+        },
+        HighlightedRange {
+            range: [65; 68),
+            tag: "text"
+        },
+        HighlightedRange {
+            range: [73; 75),
+            tag: "keyword"
+        },
+        HighlightedRange {
+            range: [76; 79),
+            tag: "function"
+        },
+        HighlightedRange {
+            range: [80; 81),
+            tag: "type"
+        },
+        HighlightedRange {
+            range: [80; 81),
+            tag: "function"
+        },
+        HighlightedRange {
+            range: [88; 89),
+            tag: "type"
+        },
+        HighlightedRange {
+            range: [96; 110),
+            tag: "macro"
+        },
+        HighlightedRange {
+            range: [117; 127),
+            tag: "comment"
+        },
+        HighlightedRange {
+            range: [128; 130),
+            tag: "keyword"
+        },
+        HighlightedRange {
+            range: [131; 135),
+            tag: "function"
+        },
+        HighlightedRange {
+            range: [145; 153),
+            tag: "macro"
+        },
+        HighlightedRange {
+            range: [154; 166),
+            tag: "string"
+        },
+        HighlightedRange {
+            range: [168; 170),
+            tag: "literal"
+        },
+        HighlightedRange {
+            range: [178; 181),
+            tag: "keyword"
+        },
+        HighlightedRange {
+            range: [182; 185),
+            tag: "keyword"
+        },
+        HighlightedRange {
+            range: [186; 189),
+            tag: "macro"
+        },
+        HighlightedRange {
+            range: [197; 200),
+            tag: "macro"
+        },
+        HighlightedRange {
+            range: [192; 195),
+            tag: "text"
+        },
+        HighlightedRange {
+            range: [208; 211),
+            tag: "macro"
+        },
+        HighlightedRange {
+            range: [212; 216),
+            tag: "macro"
+        },
+        HighlightedRange {
+            range: [226; 227),
+            tag: "literal"
+        },
+        HighlightedRange {
+            range: [232; 233),
+            tag: "literal"
+        },
+        HighlightedRange {
+            range: [242; 248),
+            tag: "keyword.unsafe"
+        },
+        HighlightedRange {
+            range: [251; 254),
+            tag: "text"
+        },
+        HighlightedRange {
+            range: [255; 262),
+            tag: "text"
+        },
+        HighlightedRange {
+            range: [263; 264),
+            tag: "literal"
+        }
+    ]
+)
diff --git a/crates/ra_ide_api/src/snapshots/tests__rename_mod.snap b/crates/ra_ide_api/src/snapshots/tests__rename_mod.snap
index 431de5c559..890426db77 100644
--- a/crates/ra_ide_api/src/snapshots/tests__rename_mod.snap
+++ b/crates/ra_ide_api/src/snapshots/tests__rename_mod.snap
@@ -1,8 +1,8 @@
 ---
-created: "2019-05-23T22:23:35.215905447Z"
-creator: insta@0.8.1
-source: crates/ra_ide_api/src/references.rs
+created: "2019-01-24T08:39:53.759318522+00:00"
+creator: insta@0.5.2
 expression: "&source_change"
+source: crates/ra_ide_api/src/rename.rs
 ---
 Some(
     SourceChange {
@@ -10,29 +10,29 @@ Some(
         source_file_edits: [
             SourceFileEdit {
                 file_id: FileId(
-                    2,
+                    2
                 ),
                 edit: TextEdit {
                     atoms: [
                         AtomTextEdit {
                             delete: [4; 7),
-                            insert: "foo2",
-                        },
-                    ],
-                },
-            },
+                            insert: "foo2"
+                        }
+                    ]
+                }
+            }
         ],
         file_system_edits: [
             MoveFile {
                 src: FileId(
-                    3,
+                    3
                 ),
                 dst_source_root: SourceRootId(
-                    0,
+                    0
                 ),
-                dst_path: "bar/foo2.rs",
-            },
+                dst_path: "bar/foo2.rs"
+            }
         ],
-        cursor_position: None,
-    },
+        cursor_position: None
+    }
 )
diff --git a/crates/ra_ide_api/src/snapshots/tests__rename_mod_in_dir.snap b/crates/ra_ide_api/src/snapshots/tests__rename_mod_in_dir.snap
index aaff9b4b50..e96bf5c02f 100644
--- a/crates/ra_ide_api/src/snapshots/tests__rename_mod_in_dir.snap
+++ b/crates/ra_ide_api/src/snapshots/tests__rename_mod_in_dir.snap
@@ -1,8 +1,8 @@
 ---
-created: "2019-05-23T22:23:35.213830371Z"
-creator: insta@0.8.1
-source: crates/ra_ide_api/src/references.rs
+created: "2019-01-22T14:45:00.975229300+00:00"
+creator: insta@0.4.0
 expression: "&source_change"
+source: "crates\\ra_ide_api\\src\\rename.rs"
 ---
 Some(
     SourceChange {
@@ -10,29 +10,29 @@ Some(
         source_file_edits: [
             SourceFileEdit {
                 file_id: FileId(
-                    1,
+                    1
                 ),
                 edit: TextEdit {
                     atoms: [
                         AtomTextEdit {
                             delete: [4; 7),
-                            insert: "foo2",
-                        },
-                    ],
-                },
-            },
+                            insert: "foo2"
+                        }
+                    ]
+                }
+            }
         ],
         file_system_edits: [
             MoveFile {
                 src: FileId(
-                    2,
+                    2
                 ),
                 dst_source_root: SourceRootId(
-                    0,
+                    0
                 ),
-                dst_path: "foo2/mod.rs",
-            },
+                dst_path: "foo2/mod.rs"
+            }
         ],
-        cursor_position: None,
-    },
+        cursor_position: None
+    }
 )
diff --git a/crates/ra_ide_api/src/snapshots/tests__runnables.snap b/crates/ra_ide_api/src/snapshots/tests__runnables.snap
index de2fadd7f5..71bd7a4bd1 100644
--- a/crates/ra_ide_api/src/snapshots/tests__runnables.snap
+++ b/crates/ra_ide_api/src/snapshots/tests__runnables.snap
@@ -1,24 +1,24 @@
 ---
-created: "2019-05-23T22:23:35.217100106Z"
-creator: insta@0.8.1
-source: crates/ra_ide_api/src/runnables.rs
+created: "2019-01-22T14:45:00.975229300+00:00"
+creator: insta@0.4.0
 expression: "&runnables"
+source: "crates\\ra_ide_api\\src\\runnables.rs"
 ---
 [
     Runnable {
         range: [1; 21),
-        kind: Bin,
+        kind: Bin
     },
     Runnable {
         range: [22; 46),
         kind: Test {
-            name: "test_foo",
-        },
+            name: "test_foo"
+        }
     },
     Runnable {
         range: [47; 81),
         kind: Test {
-            name: "test_foo",
-        },
-    },
+            name: "test_foo"
+        }
+    }
 ]
diff --git a/crates/ra_ide_api/src/snapshots/tests__runnables_module.snap b/crates/ra_ide_api/src/snapshots/tests__runnables_module.snap
index 23993a97f0..a28dd89521 100644
--- a/crates/ra_ide_api/src/snapshots/tests__runnables_module.snap
+++ b/crates/ra_ide_api/src/snapshots/tests__runnables_module.snap
@@ -1,20 +1,20 @@
 ---
-created: "2019-05-23T22:23:35.219258850Z"
-creator: insta@0.8.1
-source: crates/ra_ide_api/src/runnables.rs
+created: "2019-01-22T14:45:00.976230700+00:00"
+creator: insta@0.4.0
 expression: "&runnables"
+source: "crates\\ra_ide_api\\src\\runnables.rs"
 ---
 [
     Runnable {
         range: [1; 59),
         kind: TestMod {
-            path: "test_mod",
-        },
+            path: "test_mod"
+        }
     },
     Runnable {
         range: [28; 57),
         kind: Test {
-            name: "test_foo1",
-        },
-    },
+            name: "test_foo1"
+        }
+    }
 ]
diff --git a/crates/ra_ide_api/src/snapshots/tests__runnables_multiple_depth_module.snap b/crates/ra_ide_api/src/snapshots/tests__runnables_multiple_depth_module.snap
index c516a61dfc..79f07bef94 100644
--- a/crates/ra_ide_api/src/snapshots/tests__runnables_multiple_depth_module.snap
+++ b/crates/ra_ide_api/src/snapshots/tests__runnables_multiple_depth_module.snap
@@ -1,20 +1,20 @@
 ---
-created: "2019-05-23T22:23:35.219671663Z"
-creator: insta@0.8.1
-source: crates/ra_ide_api/src/runnables.rs
+created: "2019-01-22T14:45:00.979218100+00:00"
+creator: insta@0.4.0
 expression: "&runnables"
+source: "crates\\ra_ide_api\\src\\runnables.rs"
 ---
 [
     Runnable {
         range: [41; 115),
         kind: TestMod {
-            path: "foo::bar::test_mod",
-        },
+            path: "foo::bar::test_mod"
+        }
     },
     Runnable {
         range: [68; 105),
         kind: Test {
-            name: "test_foo1",
-        },
-    },
+            name: "test_foo1"
+        }
+    }
 ]
diff --git a/crates/ra_ide_api/src/snapshots/tests__runnables_one_depth_layer_module.snap b/crates/ra_ide_api/src/snapshots/tests__runnables_one_depth_layer_module.snap
index b02e6707ef..d199e90739 100644
--- a/crates/ra_ide_api/src/snapshots/tests__runnables_one_depth_layer_module.snap
+++ b/crates/ra_ide_api/src/snapshots/tests__runnables_one_depth_layer_module.snap
@@ -1,20 +1,20 @@
 ---
-created: "2019-05-23T22:23:35.224315047Z"
-creator: insta@0.8.1
-source: crates/ra_ide_api/src/runnables.rs
+created: "2019-01-22T14:45:01.016119500+00:00"
+creator: insta@0.4.0
 expression: "&runnables"
+source: "crates\\ra_ide_api\\src\\runnables.rs"
 ---
 [
     Runnable {
         range: [23; 85),
         kind: TestMod {
-            path: "foo::test_mod",
-        },
+            path: "foo::test_mod"
+        }
     },
     Runnable {
         range: [46; 79),
         kind: Test {
-            name: "test_foo1",
-        },
-    },
+            name: "test_foo1"
+        }
+    }
 ]