Repository: rust-analyzer/rust-analyzer
Pull request #1771 (2019-09-05 19:44:07)

Further tweak for macro_use on extern crate
Some more tweaks to #1743 to behave more like `rustc`
1. Hoist macros from `#[macro_use] extern crate`, so that they can be used before `extern crate`.
2. Implicit `#[macro_use]` for `prelude` if exists



Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 904d46b94c..27e0a82af0 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -32,7 +32,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "backtrace"
-version = "0.3.37"
+version = "0.3.35"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -78,7 +78,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "bstr"
-version = "0.2.8"
+version = "0.2.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -176,7 +176,7 @@ dependencies = [
 
 [[package]]
 name = "chrono"
-version = "0.4.9"
+version = "0.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -223,7 +223,7 @@ dependencies = [
  "encode_unicode 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.2.1 (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.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -250,6 +250,15 @@ dependencies = [
  "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "crossbeam-deque"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "crossbeam-deque"
 version = "0.7.1"
@@ -294,7 +303,7 @@ name = "derive-new"
 version = "0.5.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -337,7 +346,7 @@ name = "failure"
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "backtrace 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -354,13 +363,12 @@ dependencies = [
 
 [[package]]
 name = "filetime"
-version = "0.2.7"
+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.62 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -373,10 +381,10 @@ name = "flexi_logger"
 version = "0.14.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "yansi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -460,10 +468,10 @@ version = "0.4.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bstr 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -498,7 +506,7 @@ dependencies = [
  "lazy_static 1.4.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.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -741,11 +749,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "notify"
-version = "4.0.13"
+version = "4.0.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "filetime 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "filetime 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "fsevent 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "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)",
@@ -792,7 +800,7 @@ dependencies = [
 
 [[package]]
 name = "once_cell"
-version = "1.0.2"
+version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -839,7 +847,7 @@ version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -868,7 +876,7 @@ name = "proc-macro-hack"
 version = "0.5.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -883,7 +891,7 @@ dependencies = [
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.2"
+version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -903,7 +911,7 @@ dependencies = [
  "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)",
  "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -924,7 +932,7 @@ name = "quote"
 version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -939,7 +947,7 @@ dependencies = [
  "format-buf 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.8.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)",
- "once_cell 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "once_cell 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "ra_db 0.1.0",
  "ra_fmt 0.1.0",
  "ra_hir 0.1.0",
@@ -1009,7 +1017,7 @@ dependencies = [
  "insta 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lalrpop-intern 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "once_cell 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "once_cell 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "ra_arena 0.1.0",
  "ra_db 0.1.0",
@@ -1041,12 +1049,12 @@ dependencies = [
  "ra_syntax 0.1.0",
  "ra_text_edit 0.1.0",
  "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rayon 1.1.0 (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)",
  "superslice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "test_utils 0.1.0",
- "unicase 2.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1100,11 +1108,11 @@ dependencies = [
 name = "ra_prof"
 version = "0.1.0"
 dependencies = [
- "backtrace 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "jemalloc-ctl 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "jemallocator 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "once_cell 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "once_cell 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1157,7 +1165,7 @@ version = "0.1.0"
 dependencies = [
  "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1179,7 +1187,7 @@ dependencies = [
  "crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "jod-thread 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "notify 4.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "notify 4.0.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.9.0 (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)",
@@ -1339,20 +1347,20 @@ dependencies = [
 
 [[package]]
 name = "rayon"
-version = "1.2.0"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rayon-core"
-version = "1.6.0"
+version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1374,18 +1382,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "regex"
-version = "1.3.1"
+version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "regex-syntax"
-version = "0.6.12"
+version = "0.6.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1469,7 +1477,7 @@ version = "0.13.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1514,7 +1522,7 @@ name = "serde_derive"
 version = "1.0.99"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1534,7 +1542,7 @@ name = "serde_repr"
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1599,7 +1607,7 @@ name = "syn"
 version = "1.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1686,7 +1694,7 @@ dependencies = [
 
 [[package]]
 name = "unicase"
-version = "2.5.1"
+version = "2.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1839,13 +1847,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d73f9beda665eaa98ab9e4f7442bd4e7de6652587de55b2525e52e29c1b0ba"
 "checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90"
 "checksum autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875"
-"checksum backtrace 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)" = "5180c5a20655b14a819b652fd2378fa5f1697b6c9ddad3e695c2f9cedf6df4e2"
+"checksum backtrace 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "1371048253fa3bac6704bfd6bbfc922ee9bdcee8881330d40f308b81cc5adc55"
 "checksum backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "82a830b4ef2d1124a711c71d263c5abdc710ef8e907bd508c88be475cebc422b"
 "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"
 "checksum bit-vec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb"
 "checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd"
-"checksum bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8d6c2c5b58ab920a4f5aeaaca34b4488074e8cc7596af94e6f8c6ff247c60245"
+"checksum bstr 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94cdf78eb7e94c566c1f5dbe2abf8fc70a548fc902942a48c4b3a98b48ca9ade"
 "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
 "checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101"
 "checksum cargo_metadata 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "700b3731fd7d357223d0000f4dbf1808401b694609035c3c411fbc0cd375c426"
@@ -1856,13 +1864,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum chalk-macros 0.1.1 (git+https://github.com/rust-lang/chalk.git)" = "<none>"
 "checksum chalk-rust-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git)" = "<none>"
 "checksum chalk-solve 0.1.0 (git+https://github.com/rust-lang/chalk.git)" = "<none>"
-"checksum chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e8493056968583b0193c1bb04d6f7684586f3726992d6c573261941a895dbd68"
+"checksum chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "77d81f58b7301084de3b958691458a53c3f7e0b1d702f77e550b6a88e3a88abe"
 "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
 "checksum clicolors-control 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90082ee5dcdd64dc4e9e0d37fbf3ee325419e39c0092191e0393df65518f741e"
 "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
 "checksum console 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b147390a412132d75d10dd3b7b175a69cf5fd95032f7503c7091b8831ba10242"
 "checksum crossbeam 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2d818a4990769aac0c7ff1360e233ef3a41adcb009ebb2036bf6915eb0f6b23c"
 "checksum crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c8ec7fcd21571dc78f96cc96243cab8d8f035247c3efd16c687be154c3fa9efa"
+"checksum crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "05e44b8cf3e1a625844d1750e1f7820da46044ff6d28f4d43e455ba3e5bb2c13"
 "checksum crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71"
 "checksum crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fedcd6772e37f3da2a9af9bf12ebe046c0dfe657992377b4df982a2b54cd37a9"
 "checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b"
@@ -1876,7 +1885,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum encode_unicode 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
 "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 filetime 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6bd7380b54ced79dda72ecc35cc4fbbd1da6bba54afaa37e96fd1c2a308cd469"
+"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.14.3 (registry+https://github.com/rust-lang/crates.io-index)" = "66473c1b6a0d2a72f6ed983d33021a4c744a1d179e6f4265867b7d0a9dd679c5"
 "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
@@ -1924,12 +1933,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "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.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1191efa2b8fe041decb55c238a125b7a1aeb6fad7a525133a02be5ec949ff3cb"
+"checksum notify 4.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "3572d71f13ea8ed41867accd971fd564aa75934cf7a1fae03ddb8c74a8a49943"
 "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_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273"
 "checksum number_prefix 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dbf9993e59c894e3c08aa1c2712914e9e6bf1fcbfc6bef283e2183df345a4fee"
-"checksum once_cell 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd38c1bb51148ca239ec38ef1bb4f7570d432861f03e91774d53b01c2ba2132f"
+"checksum once_cell 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c9192c5a4c3b5488dae8d3886ef9df6b5eb246d36323dc7a5078595a154e7771"
 "checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
 "checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252"
 "checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b"
@@ -1940,7 +1949,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b"
 "checksum proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e688f31d92ffd7c1ddc57a1b4e6d773c0f2a14ee437a4b0a4f5a69c80eb221c8"
 "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
-"checksum proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "175a40b9cf564ce9bf050654633dbf339978706b8ead1a907bb970b63185dd95"
+"checksum proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c5c2380ae88876faae57698be9e9775e3544decad214599c3a6266cca6ac802"
 "checksum proptest 0.9.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cf147e022eacf0c8a054ab864914a7602618adba841d800a9a9868a5237a529f"
 "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
 "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
@@ -1962,12 +1971,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
 "checksum rand_pcg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e196346cbbc5c70c77e7b4926147ee8e383a38ee4d15d58a08098b169e492b6"
 "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
-"checksum rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83a27732a533a1be0a0035a111fe76db89ad312f6f0347004c220c57f209a123"
-"checksum rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98dcf634205083b17d0861252431eb2acbfb698ab7478a2d20de07954f47ec7b"
+"checksum rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4b0186e22767d5b9738a05eab7c6ac90b15db17e5b5f9bd87976dd7d89a10a4"
+"checksum rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbe0df8435ac0c397d467b6cad6d25543d06e8a019ef3f6af3c384597515bd2"
 "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
 "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
-"checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd"
-"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716"
+"checksum regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88c3d9193984285d544df4a30c23a4e62ead42edf70a4452ceb76dac1ce05c26"
+"checksum regex-syntax 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b143cceb2ca5e56d5671988ef8b15615733e7ee16cd348e064333b251b89343f"
 "checksum relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0e7790c7f1cc73d831d28dc5a7deb316a006e7848e6a7f467cdb10a0a9e0fb1c"
 "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
 "checksum ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ece421e0c4129b90e4a35b6f625e472e96c552136f5093a2f4fa2bbb75a62d5"
@@ -2002,7 +2011,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
 "checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865"
 "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
-"checksum unicase 2.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2e2e6bd1e59e56598518beb94fd6db628ded570326f0a98c679a304bd9f00150"
+"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"
diff --git a/crates/ra_assists/src/ast_editor.rs b/crates/ra_assists/src/ast_editor.rs
index a710edce8e..0484786625 100644
--- a/crates/ra_assists/src/ast_editor.rs
+++ b/crates/ra_assists/src/ast_editor.rs
@@ -297,11 +297,6 @@ impl AstBuilder<ast::Path> {
         ast_node_from_file_text(text)
     }
 
-    pub fn from_name(name: ast::Name) -> ast::Path {
-        let name = name.syntax().to_string();
-        Self::from_text(name.as_str())
-    }
-
     pub fn from_pieces(enum_name: ast::Name, var_name: ast::Name) -> ast::Path {
         Self::from_text(&format!("{}::{}", enum_name.syntax(), var_name.syntax()))
     }
@@ -385,31 +380,6 @@ impl AstBuilder<ast::MatchArmList> {
     }
 }
 
-impl AstBuilder<ast::WherePred> {
-    fn from_text(text: &str) -> ast::WherePred {
-        ast_node_from_file_text(&format!("fn f() where {} {{ }}", text))
-    }
-
-    pub fn from_pieces(
-        path: ast::Path,
-        bounds: impl Iterator<Item = ast::TypeBound>,
-    ) -> ast::WherePred {
-        let bounds = bounds.map(|b| b.syntax().to_string()).collect::<Vec<_>>().join(" + ");
-        Self::from_text(&format!("{}: {}", path.syntax(), bounds))
-    }
-}
-
-impl AstBuilder<ast::WhereClause> {
-    fn from_text(text: &str) -> ast::WhereClause {
-        ast_node_from_file_text(&format!("fn f() where {} {{ }}", text))
-    }
-
-    pub fn from_predicates(preds: impl Iterator<Item = ast::WherePred>) -> ast::WhereClause {
-        let preds = preds.map(|p| p.syntax().to_string()).collect::<Vec<_>>().join(", ");
-        Self::from_text(preds.as_str())
-    }
-}
-
 fn ast_node_from_file_text<N: AstNode>(text: &str) -> N {
     let parse = SourceFile::parse(text);
     let res = parse.tree().syntax().descendants().find_map(N::cast).unwrap();
diff --git a/crates/ra_assists/src/lib.rs b/crates/ra_assists/src/lib.rs
index 10ccc345c9..03eec73ad8 100644
--- a/crates/ra_assists/src/lib.rs
+++ b/crates/ra_assists/src/lib.rs
@@ -102,7 +102,6 @@ mod remove_dbg;
 pub mod auto_import;
 mod add_missing_impl_members;
 mod move_guard;
-mod move_bounds;
 
 fn all_assists<DB: HirDatabase>() -> &'static [fn(AssistCtx<DB>) -> Option<Assist>] {
     &[
@@ -124,7 +123,6 @@ fn all_assists<DB: HirDatabase>() -> &'static [fn(AssistCtx<DB>) -> Option<Assis
         inline_local_variable::inline_local_varialbe,
         move_guard::move_guard_to_arm_body,
         move_guard::move_arm_cond_to_match_guard,
-        move_bounds::move_bounds_to_where_clause,
     ]
 }
 
diff --git a/crates/ra_assists/src/move_bounds.rs b/crates/ra_assists/src/move_bounds.rs
deleted file mode 100644
index 526de1d983..0000000000
--- a/crates/ra_assists/src/move_bounds.rs
+++ /dev/null
@@ -1,135 +0,0 @@
-use hir::db::HirDatabase;
-use ra_syntax::{
-    ast::{self, AstNode, NameOwner, TypeBoundsOwner},
-    SyntaxElement,
-    SyntaxKind::*,
-    TextRange,
-};
-
-use crate::{ast_editor::AstBuilder, Assist, AssistCtx, AssistId};
-
-pub(crate) fn move_bounds_to_where_clause(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
-    let type_param_list = ctx.node_at_offset::<ast::TypeParamList>()?;
-
-    let mut type_params = type_param_list.type_params();
-    if type_params.all(|p| p.type_bound_list().is_none()) {
-        return None;
-    }
-
-    let parent = type_param_list.syntax().parent()?;
-    if parent.children_with_tokens().find(|it| it.kind() == WHERE_CLAUSE).is_some() {
-        return None;
-    }
-
-    let anchor: SyntaxElement = match parent.kind() {
-        FN_DEF => ast::FnDef::cast(parent)?.body()?.syntax().clone().into(),
-        TRAIT_DEF => ast::TraitDef::cast(parent)?.item_list()?.syntax().clone().into(),
-        IMPL_BLOCK => ast::ImplBlock::cast(parent)?.item_list()?.syntax().clone().into(),
-        ENUM_DEF => ast::EnumDef::cast(parent)?.variant_list()?.syntax().clone().into(),
-        STRUCT_DEF => parent
-            .children_with_tokens()
-            .find(|it| it.kind() == RECORD_FIELD_DEF_LIST || it.kind() == SEMI)?,
-        _ => return None,
-    };
-
-    ctx.add_action(
-        AssistId("move_bounds_to_where_clause"),
-        "move_bounds_to_where_clause",
-        |edit| {
-            let type_params = type_param_list.type_params().collect::<Vec<_>>();
-
-            for param in &type_params {
-                if let Some(bounds) = param.type_bound_list() {
-                    let colon = param
-                        .syntax()
-                        .children_with_tokens()
-                        .find(|it| it.kind() == COLON)
-                        .unwrap();
-                    let start = colon.text_range().start();
-                    let end = bounds.syntax().text_range().end();
-                    edit.delete(TextRange::from_to(start, end));
-                }
-            }
-
-            let predicates = type_params.iter().filter_map(build_predicate);
-            let where_clause = AstBuilder::<ast::WhereClause>::from_predicates(predicates);
-
-            let to_insert = match anchor.prev_sibling_or_token() {
-                Some(ref elem) if elem.kind() == WHITESPACE => {
-                    format!("{} ", where_clause.syntax())
-                }
-                _ => format!(" {}", where_clause.syntax()),
-            };
-            edit.insert(anchor.text_range().start(), to_insert);
-            edit.target(type_param_list.syntax().text_range());
-        },
-    );
-
-    ctx.build()
-}
-
-fn build_predicate(param: &ast::TypeParam) -> Option<ast::WherePred> {
-    let path = AstBuilder::<ast::Path>::from_name(param.name()?);
-    let predicate =
-        AstBuilder::<ast::WherePred>::from_pieces(path, param.type_bound_list()?.bounds());
-    Some(predicate)
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    use crate::helpers::check_assist;
-
-    #[test]
-    fn move_bounds_to_where_clause_fn() {
-        check_assist(
-            move_bounds_to_where_clause,
-            r#"
-            fn foo<T: u32, <|>F: FnOnce(T) -> T>() {}
-            "#,
-            r#"
-            fn foo<T, <|>F>() where T: u32, F: FnOnce(T) -> T {}
-            "#,
-        );
-    }
-
-    #[test]
-    fn move_bounds_to_where_clause_impl() {
-        check_assist(
-            move_bounds_to_where_clause,
-            r#"
-            impl<U: u32, <|>T> A<U, T> {}
-            "#,
-            r#"
-            impl<U, <|>T> A<U, T> where U: u32 {}
-            "#,
-        );
-    }
-
-    #[test]
-    fn move_bounds_to_where_clause_struct() {
-        check_assist(
-            move_bounds_to_where_clause,
-            r#"
-            struct A<<|>T: Iterator<Item = u32>> {}
-            "#,
-            r#"
-            struct A<<|>T> where T: Iterator<Item = u32> {}
-            "#,
-        );
-    }
-
-    #[test]
-    fn move_bounds_to_where_clause_tuple_struct() {
-        check_assist(
-            move_bounds_to_where_clause,
-            r#"
-            struct Pair<<|>T: u32>(T, T);
-            "#,
-            r#"
-            struct Pair<<|>T>(T, T) where T: u32;
-            "#,
-        );
-    }
-}
diff --git a/crates/ra_hir/src/marks.rs b/crates/ra_hir/src/marks.rs
index 2e1d35c8cb..fe119b97c5 100644
--- a/crates/ra_hir/src/marks.rs
+++ b/crates/ra_hir/src/marks.rs
@@ -12,4 +12,5 @@ test_utils::marks!(
     trait_resolution_on_fn_type
     infer_while_let
     macro_rules_from_other_crates_are_visible_with_macro_use
+    prelude_is_macro_use
 );
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs
index dc2e2172b5..f69179bf68 100644
--- a/crates/ra_hir/src/nameres.rs
+++ b/crates/ra_hir/src/nameres.rs
@@ -50,7 +50,6 @@
 mod per_ns;
 mod raw;
 mod collector;
-mod mod_resolution;
 #[cfg(test)]
 mod tests;
 
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs
index d6c7c083dc..698e40247f 100644
--- a/crates/ra_hir/src/nameres/collector.rs
+++ b/crates/ra_hir/src/nameres/collector.rs
@@ -1,5 +1,9 @@
-use ra_db::FileId;
-use ra_syntax::ast;
+use std::borrow::Cow;
+use std::sync::Arc;
+
+use ra_db::{FileId, SourceRoot};
+use ra_syntax::{ast, SmolStr};
+use relative_path::RelativePathBuf;
 use rustc_hash::FxHashMap;
 use test_utils::tested_by;
 
@@ -8,10 +12,8 @@ use crate::{
     ids::{AstItemDef, LocationCtx, MacroCallId, MacroCallLoc, MacroDefId, MacroFileKind},
     name::MACRO_RULES,
     nameres::{
-        diagnostics::DefDiagnostic,
-        mod_resolution::{resolve_submodule, ParentModule},
-        raw, CrateDefMap, CrateModuleId, ItemOrMacro, ModuleData, ModuleDef, PerNs,
-        ReachedFixedPoint, Resolution, ResolveMode,
+        diagnostics::DefDiagnostic, raw, CrateDefMap, CrateModuleId, ItemOrMacro, ModuleData,
+        ModuleDef, PerNs, ReachedFixedPoint, Resolution, ResolveMode,
     },
     AstId, Const, DefDatabase, Enum, Function, HirFileId, MacroDef, Module, Name, Path, Static,
     Struct, Trait, TypeAlias, Union,
@@ -183,11 +185,14 @@ where
 
         if let Some(ModuleDef::Module(m)) = res.take_types() {
             tested_by!(macro_rules_from_other_crates_are_visible_with_macro_use);
+            self.import_all_macros_exported(m);
+        }
+    }
 
-            let item_map = self.db.crate_def_map(m.krate);
-            for (name, &macro_id) in &item_map.exported_macros {
-                self.global_macro_scope.insert(name.clone(), macro_id);
-            }
+    fn import_all_macros_exported(&mut self, module: Module) {
+        let item_map = self.db.crate_def_map(module.krate);
+        for (name, &macro_id) in &item_map.exported_macros {
+            self.global_macro_scope.insert(name.clone(), macro_id);
         }
     }
 
@@ -520,20 +525,32 @@ where
     DB: DefDatabase,
 {
     fn collect(&mut self, items: &[raw::RawItem]) {
+        // Prelude module is always considered to be `#[macro_use]`.
+        if let Some(prelude_module) = self.def_collector.def_map.prelude {
+            tested_by!(prelude_is_macro_use);
+            self.def_collector.import_all_macros_exported(prelude_module);
+        }
+
+        // This should be processed eagerly instead of deferred to resolving.
+        // `#[macro_use] extern crate` is hoisted to imports macros before collecting
+        // any other items.
+        for item in items {
+            if let raw::RawItem::Import(import_id) = *item {
+                let import = self.raw_items[import_id].clone();
+                if import.is_extern_crate && import.is_macro_use {
+                    self.def_collector.import_macros_from_extern_crate(&import);
+                }
+            }
+        }
+
         for item in items {
             match *item {
                 raw::RawItem::Module(m) => self.collect_module(&self.raw_items[m]),
-                raw::RawItem::Import(import_id) => {
-                    let import = self.raw_items[import_id].clone();
-                    // This should be processed eagerly instead of deferred to resolving.
-                    // Otherwise, since it will only mutate `global_macro_scope`
-                    // without `update` names in `mod`s, unresolved macros cannot be expanded.
-                    if import.is_extern_crate && import.is_macro_use {
-                        self.def_collector.import_macros_from_extern_crate(&import);
-                    }
-
-                    self.def_collector.unresolved_imports.push((self.module_id, import_id, import));
-                }
+                raw::RawItem::Import(import_id) => self.def_collector.unresolved_imports.push((
+                    self.module_id,
+                    import_id,
+                    self.raw_items[import_id].clone(),
+                )),
                 raw::RawItem::Def(def) => self.define_def(&self.raw_items[def]),
                 raw::RawItem::Macro(mac) => self.collect_macro(&self.raw_items[mac]),
             }
@@ -566,7 +583,7 @@ where
                     name,
                     is_root,
                     attr_path.as_ref(),
-                    self.parent_module,
+                    self.parent_module.as_ref(),
                 ) {
                     Ok(file_id) => {
                         let module_id = self.push_child_module(name.clone(), ast_id, Some(file_id));
@@ -677,6 +694,180 @@ fn is_macro_rules(path: &Path) -> bool {
     path.as_ident() == Some(&MACRO_RULES)
 }
 
+fn resolve_submodule(
+    db: &impl DefDatabase,
+    file_id: HirFileId,
+    name: &Name,
+    is_root: bool,
+    attr_path: Option<&SmolStr>,
+    parent_module: Option<&ParentModule>,
+) -> Result<FileId, RelativePathBuf> {
+    let file_id = file_id.original_file(db);
+    let source_root_id = db.file_source_root(file_id);
+    let path = db.file_relative_path(file_id);
+    let root = RelativePathBuf::default();
+    let dir_path = path.parent().unwrap_or(&root);
+    let mod_name = path.file_stem().unwrap_or("unknown");
+
+    let resolve_mode = match (attr_path.filter(|p| !p.is_empty()), parent_module) {
+        (Some(file_path), Some(parent_module)) => {
+            let file_path = normalize_attribute_path(file_path);
+            match parent_module.attribute_path() {
+                Some(parent_module_attr_path) => {
+                    let path = dir_path
+                        .join(format!(
+                            "{}/{}",
+                            normalize_attribute_path(parent_module_attr_path),
+                            file_path
+                        ))
+                        .normalize();
+                    ResolutionMode::InlineModuleWithAttributePath(
+                        InsideInlineModuleMode::WithAttributePath(path),
+                    )
+                }
+                None => {
+                    let path =
+                        dir_path.join(format!("{}/{}", parent_module.name, file_path)).normalize();
+                    ResolutionMode::InsideInlineModule(InsideInlineModuleMode::WithAttributePath(
+                        path,
+                    ))
+                }
+            }
+        }
+        (None, Some(parent_module)) => match parent_module.attribute_path() {
+            Some(parent_module_attr_path) => {
+                let path = dir_path.join(format!(
+                    "{}/{}.rs",
+                    normalize_attribute_path(parent_module_attr_path),
+                    name
+                ));
+                ResolutionMode::InlineModuleWithAttributePath(InsideInlineModuleMode::File(path))
+            }
+            None => {
+                let path = dir_path.join(format!("{}/{}.rs", parent_module.name, name));
+                ResolutionMode::InsideInlineModule(InsideInlineModuleMode::File(path))
+            }
+        },
+        (Some(file_path), None) => {
+            let file_path = normalize_attribute_path(file_path);
+            let path = dir_path.join(file_path.as_ref()).normalize();
+            ResolutionMode::OutOfLine(OutOfLineMode::WithAttributePath(path))
+        }
+        _ => {
+            let is_dir_owner = is_root || mod_name == "mod";
+            if is_dir_owner {
+                let file_mod = dir_path.join(format!("{}.rs", name));
+                let dir_mod = dir_path.join(format!("{}/mod.rs", name));
+                ResolutionMode::OutOfLine(OutOfLineMode::RootOrModRs {
+                    file: file_mod,
+                    directory: dir_mod,
+                })
+            } else {
+                let path = dir_path.join(format!("{}/{}.rs", mod_name, name));
+                ResolutionMode::OutOfLine(OutOfLineMode::FileInDirectory(path))
+            }
+        }
+    };
+
+    resolve_mode.resolve(db.source_root(source_root_id))
+}
+
+fn normalize_attribute_path(file_path: &SmolStr) -> Cow<str> {
+    let current_dir = "./";
+    let windows_path_separator = r#"\"#;
+    let current_dir_normalize = if file_path.starts_with(current_dir) {
+        &file_path[current_dir.len()..]
+    } else {
+        file_path.as_str()
+    };
+    if current_dir_normalize.contains(windows_path_separator) {
+        Cow::Owned(current_dir_normalize.replace(windows_path_separator, "/"))
+    } else {
+        Cow::Borrowed(current_dir_normalize)
+    }
+}
+
+enum OutOfLineMode {
+    RootOrModRs { file: RelativePathBuf, directory: RelativePathBuf },
+    FileInDirectory(RelativePathBuf),
+    WithAttributePath(RelativePathBuf),
+}
+
+impl OutOfLineMode {
+    pub fn resolve(&self, source_root: Arc<SourceRoot>) -> Result<FileId, RelativePathBuf> {
+        match self {
+            OutOfLineMode::RootOrModRs { file, directory } => match source_root.files.get(file) {
+                None => resolve_simple_path(source_root, directory).map_err(|_| file.clone()),
+                file_id => resolve_find_result(file_id, file),
+            },
+            OutOfLineMode::FileInDirectory(path) => resolve_simple_path(source_root, path),
+            OutOfLineMode::WithAttributePath(path) => resolve_simple_path(source_root, path),
+        }
+    }
+}
+
+enum InsideInlineModuleMode {
+    File(RelativePathBuf),
+    WithAttributePath(RelativePathBuf),
+}
+
+impl InsideInlineModuleMode {
+    pub fn resolve(&self, source_root: Arc<SourceRoot>) -> Result<FileId, RelativePathBuf> {
+        match self {
+            InsideInlineModuleMode::File(path) => resolve_simple_path(source_root, path),
+            InsideInlineModuleMode::WithAttributePath(path) => {
+                resolve_simple_path(source_root, path)
+            }
+        }
+    }
+}
+
+enum ResolutionMode {
+    OutOfLine(OutOfLineMode),
+    InsideInlineModule(InsideInlineModuleMode),
+    InlineModuleWithAttributePath(InsideInlineModuleMode),
+}
+
+impl ResolutionMode {
+    pub fn resolve(&self, source_root: Arc<SourceRoot>) -> Result<FileId, RelativePathBuf> {
+        use self::ResolutionMode::*;
+
+        match self {
+            OutOfLine(mode) => mode.resolve(source_root),
+            InsideInlineModule(mode) => mode.resolve(source_root),
+            InlineModuleWithAttributePath(mode) => mode.resolve(source_root),
+        }
+    }
+}
+
+fn resolve_simple_path(
+    source_root: Arc<SourceRoot>,
+    path: &RelativePathBuf,
+) -> Result<FileId, RelativePathBuf> {
+    resolve_find_result(source_root.files.get(path), path)
+}
+
+fn resolve_find_result(
+    file_id: Option<&FileId>,
+    path: &RelativePathBuf,
+) -> Result<FileId, RelativePathBuf> {
+    match file_id {
+        Some(file_id) => Ok(file_id.clone()),
+        None => Err(path.clone()),
+    }
+}
+
+struct ParentModule<'a> {
+    name: &'a Name,
+    attr_path: Option<&'a SmolStr>,
+}
+
+impl<'a> ParentModule<'a> {
+    pub fn attribute_path(&self) -> Option<&SmolStr> {
+        self.attr_path.filter(|p| !p.is_empty())
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use ra_db::SourceDatabase;
diff --git a/crates/ra_hir/src/nameres/mod_resolution.rs b/crates/ra_hir/src/nameres/mod_resolution.rs
deleted file mode 100644
index 94c9946ffd..0000000000
--- a/crates/ra_hir/src/nameres/mod_resolution.rs
+++ /dev/null
@@ -1,182 +0,0 @@
-use std::{borrow::Cow, sync::Arc};
-
-use ra_db::{FileId, SourceRoot};
-use ra_syntax::SmolStr;
-use relative_path::RelativePathBuf;
-
-use crate::{DefDatabase, HirFileId, Name};
-
-#[derive(Clone, Copy)]
-pub(super) struct ParentModule<'a> {
-    pub(super) name: &'a Name,
-    pub(super) attr_path: Option<&'a SmolStr>,
-}
-
-impl<'a> ParentModule<'a> {
-    fn attribute_path(&self) -> Option<&SmolStr> {
-        self.attr_path.filter(|p| !p.is_empty())
-    }
-}
-
-pub(super) fn resolve_submodule(
-    db: &impl DefDatabase,
-    file_id: HirFileId,
-    name: &Name,
-    is_root: bool,
-    attr_path: Option<&SmolStr>,
-    parent_module: Option<ParentModule<'_>>,
-) -> Result<FileId, RelativePathBuf> {
-    let file_id = file_id.original_file(db);
-    let source_root_id = db.file_source_root(file_id);
-    let path = db.file_relative_path(file_id);
-    let root = RelativePathBuf::default();
-    let dir_path = path.parent().unwrap_or(&root);
-    let mod_name = path.file_stem().unwrap_or("unknown");
-
-    let resolve_mode = match (attr_path.filter(|p| !p.is_empty()), parent_module) {
-        (Some(file_path), Some(parent_module)) => {
-            let file_path = normalize_attribute_path(file_path);
-            match parent_module.attribute_path() {
-                Some(parent_module_attr_path) => {
-                    let path = dir_path
-                        .join(format!(
-                            "{}/{}",
-                            normalize_attribute_path(parent_module_attr_path),
-                            file_path
-                        ))
-                        .normalize();
-                    ResolutionMode::InlineModuleWithAttributePath(
-                        InsideInlineModuleMode::WithAttributePath(path),
-                    )
-                }
-                None => {
-                    let path =
-                        dir_path.join(format!("{}/{}", parent_module.name, file_path)).normalize();
-                    ResolutionMode::InsideInlineModule(InsideInlineModuleMode::WithAttributePath(
-                        path,
-                    ))
-                }
-            }
-        }
-        (None, Some(parent_module)) => match parent_module.attribute_path() {
-            Some(parent_module_attr_path) => {
-                let path = dir_path.join(format!(
-                    "{}/{}.rs",
-                    normalize_attribute_path(parent_module_attr_path),
-                    name
-                ));
-                ResolutionMode::InlineModuleWithAttributePath(InsideInlineModuleMode::File(path))
-            }
-            None => {
-                let path = dir_path.join(format!("{}/{}.rs", parent_module.name, name));
-                ResolutionMode::InsideInlineModule(InsideInlineModuleMode::File(path))
-            }
-        },
-        (Some(file_path), None) => {
-            let file_path = normalize_attribute_path(file_path);
-            let path = dir_path.join(file_path.as_ref()).normalize();
-            ResolutionMode::OutOfLine(OutOfLineMode::WithAttributePath(path))
-        }
-        _ => {
-            let is_dir_owner = is_root || mod_name == "mod";
-            if is_dir_owner {
-                let file_mod = dir_path.join(format!("{}.rs", name));
-                let dir_mod = dir_path.join(format!("{}/mod.rs", name));
-                ResolutionMode::OutOfLine(OutOfLineMode::RootOrModRs {
-                    file: file_mod,
-                    directory: dir_mod,
-                })
-            } else {
-                let path = dir_path.join(format!("{}/{}.rs", mod_name, name));
-                ResolutionMode::OutOfLine(OutOfLineMode::FileInDirectory(path))
-            }
-        }
-    };
-
-    resolve_mode.resolve(db.source_root(source_root_id))
-}
-
-fn normalize_attribute_path(file_path: &SmolStr) -> Cow<str> {
-    let current_dir = "./";
-    let windows_path_separator = r#"\"#;
-    let current_dir_normalize = if file_path.starts_with(current_dir) {
-        &file_path[current_dir.len()..]
-    } else {
-        file_path.as_str()
-    };
-    if current_dir_normalize.contains(windows_path_separator) {
-        Cow::Owned(current_dir_normalize.replace(windows_path_separator, "/"))
-    } else {
-        Cow::Borrowed(current_dir_normalize)
-    }
-}
-
-enum OutOfLineMode {
-    RootOrModRs { file: RelativePathBuf, directory: RelativePathBuf },
-    FileInDirectory(RelativePathBuf),
-    WithAttributePath(RelativePathBuf),
-}
-
-impl OutOfLineMode {
-    pub fn resolve(&self, source_root: Arc<SourceRoot>) -> Result<FileId, RelativePathBuf> {
-        match self {
-            OutOfLineMode::RootOrModRs { file, directory } => match source_root.files.get(file) {
-                None => resolve_simple_path(source_root, directory).map_err(|_| file.clone()),
-                file_id => resolve_find_result(file_id, file),
-            },
-            OutOfLineMode::FileInDirectory(path) => resolve_simple_path(source_root, path),
-            OutOfLineMode::WithAttributePath(path) => resolve_simple_path(source_root, path),
-        }
-    }
-}
-
-enum InsideInlineModuleMode {
-    File(RelativePathBuf),
-    WithAttributePath(RelativePathBuf),
-}
-
-impl InsideInlineModuleMode {
-    pub fn resolve(&self, source_root: Arc<SourceRoot>) -> Result<FileId, RelativePathBuf> {
-        match self {
-            InsideInlineModuleMode::File(path) => resolve_simple_path(source_root, path),
-            InsideInlineModuleMode::WithAttributePath(path) => {
-                resolve_simple_path(source_root, path)
-            }
-        }
-    }
-}
-
-enum ResolutionMode {
-    OutOfLine(OutOfLineMode),
-    InsideInlineModule(InsideInlineModuleMode),
-    InlineModuleWithAttributePath(InsideInlineModuleMode),
-}
-
-impl ResolutionMode {
-    pub fn resolve(&self, source_root: Arc<SourceRoot>) -> Result<FileId, RelativePathBuf> {
-        use self::ResolutionMode::*;
-
-        match self {
-            OutOfLine(mode) => mode.resolve(source_root),
-            InsideInlineModule(mode) => mode.resolve(source_root),
-            InlineModuleWithAttributePath(mode) => mode.resolve(source_root),
-        }
-    }
-}
-
-fn resolve_simple_path(
-    source_root: Arc<SourceRoot>,
-    path: &RelativePathBuf,
-) -> Result<FileId, RelativePathBuf> {
-    resolve_find_result(source_root.files.get(path), path)
-}
-
-fn resolve_find_result(
-    file_id: Option<&FileId>,
-    path: &RelativePathBuf,
-) -> Result<FileId, RelativePathBuf> {
-    match file_id {
-        Some(file_id) => Ok(file_id.clone()),
-        None => Err(path.clone()),
-    }
-}
diff --git a/crates/ra_hir/src/nameres/tests/mod_resolution.rs b/crates/ra_hir/src/nameres/tests/mods.rs
similarity index 100%
rename from crates/ra_hir/src/nameres/tests/mod_resolution.rs
rename to crates/ra_hir/src/nameres/tests/mods.rs
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs
index e90fbd4285..514dcaf962 100644
--- a/crates/ra_ide_api/src/lib.rs
+++ b/crates/ra_ide_api/src/lib.rs
@@ -466,7 +466,7 @@ impl Analysis {
         &self,
         position: FilePosition,
     ) -> Cancelable<Option<ReferenceSearchResult>> {
-        self.with_db(|db| references::find_all_refs(db, position).map(|it| it.info))
+        self.with_db(|db| references::find_all_refs(db, position))
     }
 
     /// Returns a short text describing element at position.
@@ -536,7 +536,7 @@ impl Analysis {
         &self,
         position: FilePosition,
         new_name: &str,
-    ) -> Cancelable<Option<RangeInfo<SourceChange>>> {
+    ) -> Cancelable<Option<SourceChange>> {
         self.with_db(|db| references::rename(db, position, new_name))
     }
 
diff --git a/crates/ra_ide_api/src/references.rs b/crates/ra_ide_api/src/references.rs
index 5f1f0efc30..d8a00067fe 100644
--- a/crates/ra_ide_api/src/references.rs
+++ b/crates/ra_ide_api/src/references.rs
@@ -4,7 +4,7 @@ use ra_syntax::{algo::find_node_at_offset, ast, AstNode, SourceFile, SyntaxNode}
 use relative_path::{RelativePath, RelativePathBuf};
 
 use crate::{
-    db::RootDatabase, FileId, FilePosition, FileRange, FileSystemEdit, NavigationTarget, RangeInfo,
+    db::RootDatabase, FileId, FilePosition, FileRange, FileSystemEdit, NavigationTarget,
     SourceChange, SourceFileEdit, TextRange,
 };
 
@@ -48,9 +48,9 @@ impl IntoIterator for ReferenceSearchResult {
 pub(crate) fn find_all_refs(
     db: &RootDatabase,
     position: FilePosition,
-) -> Option<RangeInfo<ReferenceSearchResult>> {
+) -> Option<ReferenceSearchResult> {
     let parse = db.parse(position.file_id);
-    let RangeInfo { range, info: (binding, analyzer) } = find_binding(db, &parse.tree(), position)?;
+    let (binding, analyzer) = find_binding(db, &parse.tree(), position)?;
     let declaration = NavigationTarget::from_bind_pat(position.file_id, &binding);
 
     let references = analyzer
@@ -59,26 +59,24 @@ pub(crate) fn find_all_refs(
         .map(move |ref_desc| FileRange { file_id: position.file_id, range: ref_desc.range })
         .collect::<Vec<_>>();
 
-    return Some(RangeInfo::new(range, ReferenceSearchResult { declaration, references }));
+    return Some(ReferenceSearchResult { declaration, references });
 
     fn find_binding<'a>(
         db: &RootDatabase,
         source_file: &SourceFile,
         position: FilePosition,
-    ) -> Option<RangeInfo<(ast::BindPat, hir::SourceAnalyzer)>> {
+    ) -> Option<(ast::BindPat, hir::SourceAnalyzer)> {
         let syntax = source_file.syntax();
         if let Some(binding) = find_node_at_offset::<ast::BindPat>(syntax, position.offset) {
-            let range = binding.syntax().text_range();
             let analyzer = hir::SourceAnalyzer::new(db, position.file_id, binding.syntax(), None);
-            return Some(RangeInfo::new(range, (binding, analyzer)));
+            return Some((binding, analyzer));
         };
         let name_ref = find_node_at_offset::<ast::NameRef>(syntax, position.offset)?;
-        let range = name_ref.syntax().text_range();
         let analyzer = hir::SourceAnalyzer::new(db, position.file_id, name_ref.syntax(), None);
         let resolved = analyzer.resolve_local_name(&name_ref)?;
         if let Either::A(ptr) = resolved.ptr() {
             if let ast::Pat::BindPat(binding) = ptr.to_node(source_file.syntax()) {
-                return Some(RangeInfo::new(range, (binding, analyzer)));
+                return Some((binding, analyzer));
             }
         }
         None
@@ -89,14 +87,12 @@ pub(crate) fn rename(
     db: &RootDatabase,
     position: FilePosition,
     new_name: &str,
-) -> Option<RangeInfo<SourceChange>> {
+) -> Option<SourceChange> {
     let parse = db.parse(position.file_id);
     if let Some((ast_name, ast_module)) =
         find_name_and_module_at_offset(parse.tree().syntax(), position)
     {
-        let range = ast_name.syntax().text_range();
         rename_mod(db, &ast_name, &ast_module, position, new_name)
-            .map(|info| RangeInfo::new(range, info))
     } else {
         rename_reference(db, position, new_name)
     }
@@ -111,7 +107,7 @@ fn find_name_and_module_at_offset(
     Some((ast_name, ast_module))
 }
 
-fn source_edit_from_file_id_range(
+fn source_edit_from_fileid_range(
     file_id: FileId,
     range: TextRange,
     new_name: &str,
@@ -183,19 +179,19 @@ fn rename_reference(
     db: &RootDatabase,
     position: FilePosition,
     new_name: &str,
-) -> Option<RangeInfo<SourceChange>> {
-    let RangeInfo { range, info: refs } = find_all_refs(db, position)?;
+) -> Option<SourceChange> {
+    let refs = find_all_refs(db, position)?;
 
     let edit = refs
         .into_iter()
-        .map(|range| source_edit_from_file_id_range(range.file_id, range.range, new_name))
+        .map(|range| source_edit_from_fileid_range(range.file_id, range.range, new_name))
         .collect::<Vec<_>>();
 
     if edit.is_empty() {
         return None;
     }
 
-    Some(RangeInfo::new(range, SourceChange::source_file_edits("rename", edit)))
+    Some(SourceChange::source_file_edits("rename", edit))
 }
 
 #[cfg(test)]
@@ -346,43 +342,38 @@ mod tests {
         let new_name = "foo2";
         let source_change = analysis.rename(position, new_name).unwrap();
         assert_debug_snapshot!(&source_change,
-@r###"
-        Some(
-            RangeInfo {
-                range: [4; 7),
-                info: SourceChange {
-                    label: "rename",
-                    source_file_edits: [
-                        SourceFileEdit {
-                            file_id: FileId(
-                                2,
-                            ),
-                            edit: TextEdit {
-                                atoms: [
-                                    AtomTextEdit {
-                                        delete: [4; 7),
-                                        insert: "foo2",
-                                    },
-                                ],
-                            },
-                        },
-                    ],
-                    file_system_edits: [
-                        MoveFile {
-                            src: FileId(
-                                3,
-                            ),
-                            dst_source_root: SourceRootId(
-                                0,
-                            ),
-                            dst_path: "bar/foo2.rs",
+@r#"Some(
+    SourceChange {
+        label: "rename",
+        source_file_edits: [
+            SourceFileEdit {
+                file_id: FileId(
+                    2,
+                ),
+                edit: TextEdit {
+                    atoms: [
+                        AtomTextEdit {
+                            delete: [4; 7),
+                            insert: "foo2",
                         },
                     ],
-                    cursor_position: None,
                 },
             },
-        )
-        "###);
+        ],
+        file_system_edits: [
+            MoveFile {
+                src: FileId(
+                    3,
+                ),
+                dst_source_root: SourceRootId(
+                    0,
+                ),
+                dst_path: "bar/foo2.rs",
+            },
+        ],
+        cursor_position: None,
+    },
+)"#);
     }
 
     #[test]
@@ -398,43 +389,38 @@ mod tests {
         let new_name = "foo2";
         let source_change = analysis.rename(position, new_name).unwrap();
         assert_debug_snapshot!(&source_change,
-        @r###"
-        Some(
-            RangeInfo {
-                range: [4; 7),
-                info: SourceChange {
-                    label: "rename",
-                    source_file_edits: [
-                        SourceFileEdit {
-                            file_id: FileId(
-                                1,
-                            ),
-                            edit: TextEdit {
-                                atoms: [
-                                    AtomTextEdit {
-                                        delete: [4; 7),
-                                        insert: "foo2",
-                                    },
-                                ],
-                            },
-                        },
-                    ],
-                    file_system_edits: [
-                        MoveFile {
-                            src: FileId(
-                                2,
-                            ),
-                            dst_source_root: SourceRootId(
-                                0,
-                            ),
-                            dst_path: "foo2/mod.rs",
+        @r###"Some(
+    SourceChange {
+        label: "rename",
+        source_file_edits: [
+            SourceFileEdit {
+                file_id: FileId(
+                    1,
+                ),
+                edit: TextEdit {
+                    atoms: [
+                        AtomTextEdit {
+                            delete: [4; 7),
+                            insert: "foo2",
                         },
                     ],
-                    cursor_position: None,
                 },
             },
-        )
-        "###
+        ],
+        file_system_edits: [
+            MoveFile {
+                src: FileId(
+                    2,
+                ),
+                dst_source_root: SourceRootId(
+                    0,
+                ),
+                dst_path: "foo2/mod.rs",
+            },
+        ],
+        cursor_position: None,
+    },
+)"###
                );
     }
 
@@ -444,7 +430,7 @@ mod tests {
         let mut text_edit_builder = ra_text_edit::TextEditBuilder::default();
         let mut file_id: Option<FileId> = None;
         if let Some(change) = source_change {
-            for edit in change.info.source_file_edits {
+            for edit in change.source_file_edits {
                 file_id = Some(edit.file_id);
                 for atom in edit.edit.as_atoms() {
                     text_edit_builder.replace(atom.delete, atom.insert.clone());
diff --git a/crates/ra_ide_api/src/syntax_tree.rs b/crates/ra_ide_api/src/syntax_tree.rs
index e2bb120b4b..9147597091 100644
--- a/crates/ra_ide_api/src/syntax_tree.rs
+++ b/crates/ra_ide_api/src/syntax_tree.rs
@@ -1,357 +1,357 @@
-use crate::db::RootDatabase;
-use ra_db::SourceDatabase;
-use ra_syntax::{
-    algo, AstNode, NodeOrToken, SourceFile,
-    SyntaxKind::{RAW_STRING, STRING},
-    SyntaxToken, TextRange,
-};
-
-pub use ra_db::FileId;
-
-pub(crate) fn syntax_tree(
-    db: &RootDatabase,
-    file_id: FileId,
-    text_range: Option<TextRange>,
-) -> String {
-    let parse = db.parse(file_id);
-    if let Some(text_range) = text_range {
-        let node = match algo::find_covering_element(parse.tree().syntax(), text_range) {
-            NodeOrToken::Node(node) => node,
-            NodeOrToken::Token(token) => {
-                if let Some(tree) = syntax_tree_for_string(&token, text_range) {
-                    return tree;
-                }
-                token.parent()
-            }
-        };
-
-        format!("{:#?}", node)
-    } else {
-        format!("{:#?}", parse.tree().syntax())
-    }
-}
-
-/// Attempts parsing the selected contents of a string literal
-/// as rust syntax and returns its syntax tree
-fn syntax_tree_for_string(token: &SyntaxToken, text_range: TextRange) -> Option<String> {
-    // When the range is inside a string
-    // we'll attempt parsing it as rust syntax
-    // to provide the syntax tree of the contents of the string
-    match token.kind() {
-        STRING | RAW_STRING => syntax_tree_for_token(token, text_range),
-        _ => None,
-    }
-}
-
-fn syntax_tree_for_token(node: &SyntaxToken, text_range: TextRange) -> Option<String> {
-    // Range of the full node
-    let node_range = node.text_range();
-    let text = node.text().to_string();
-
-    // We start at some point inside the node
-    // Either we have selected the whole string
-    // or our selection is inside it
-    let start = text_range.start() - node_range.start();
-
-    // how many characters we have selected
-    let len = text_range.len().to_usize();
-
-    let node_len = node_range.len().to_usize();
-
-    let start = start.to_usize();
-
-    // We want to cap our length
-    let len = len.min(node_len);
-
-    // Ensure our slice is inside the actual string
-    let end = if start + len < text.len() { start + len } else { text.len() - start };
-
-    let text = &text[start..end];
-
-    // Remove possible extra string quotes from the start
-    // and the end of the string
-    let text = text
-        .trim_start_matches('r')
-        .trim_start_matches('#')
-        .trim_start_matches('"')
-        .trim_end_matches('#')
-        .trim_end_matches('"')
-        .trim()
-        // Remove custom markers
-        .replace("<|>", "");
-
-    let parsed = SourceFile::parse(&text);
-
-    // If the "file" parsed without errors,
-    // return its syntax
-    if parsed.errors().is_empty() {
-        return Some(format!("{:#?}", parsed.tree().syntax()));
-    }
-
-    None
-}
-
-#[cfg(test)]
-mod tests {
-    use test_utils::assert_eq_text;
-
-    use crate::mock_analysis::{single_file, single_file_with_range};
-
-    #[test]
-    fn test_syntax_tree_without_range() {
-        // Basic syntax
-        let (analysis, file_id) = single_file(r#"fn foo() {}"#);
-        let syn = analysis.syntax_tree(file_id, None).unwrap();
-
-        assert_eq_text!(
-            syn.trim(),
-            r#"
-SOURCE_FILE@[0; 11)
-  FN_DEF@[0; 11)
-    FN_KW@[0; 2) "fn"
-    WHITESPACE@[2; 3) " "
-    NAME@[3; 6)
-      IDENT@[3; 6) "foo"
-    PARAM_LIST@[6; 8)
-      L_PAREN@[6; 7) "("
-      R_PAREN@[7; 8) ")"
-    WHITESPACE@[8; 9) " "
-    BLOCK_EXPR@[9; 11)
-      BLOCK@[9; 11)
-        L_CURLY@[9; 10) "{"
-        R_CURLY@[10; 11) "}"
-"#
-            .trim()
-        );
-
-        let (analysis, file_id) = single_file(
-            r#"
-fn test() {
-    assert!("
-    fn foo() {
-    }
-    ", "");
-}"#
-            .trim(),
-        );
-        let syn = analysis.syntax_tree(file_id, None).unwrap();
-
-        assert_eq_text!(
-            syn.trim(),
-            r#"
-SOURCE_FILE@[0; 60)
-  FN_DEF@[0; 60)
-    FN_KW@[0; 2) "fn"
-    WHITESPACE@[2; 3) " "
-    NAME@[3; 7)
-      IDENT@[3; 7) "test"
-    PARAM_LIST@[7; 9)
-      L_PAREN@[7; 8) "("
-      R_PAREN@[8; 9) ")"
-    WHITESPACE@[9; 10) " "
-    BLOCK_EXPR@[10; 60)
-      BLOCK@[10; 60)
-        L_CURLY@[10; 11) "{"
-        WHITESPACE@[11; 16) "\n    "
-        EXPR_STMT@[16; 58)
-          MACRO_CALL@[16; 57)
-            PATH@[16; 22)
-              PATH_SEGMENT@[16; 22)
-                NAME_REF@[16; 22)
-                  IDENT@[16; 22) "assert"
-            EXCL@[22; 23) "!"
-            TOKEN_TREE@[23; 57)
-              L_PAREN@[23; 24) "("
-              STRING@[24; 52) "\"\n    fn foo() {\n     ..."
-              COMMA@[52; 53) ","
-              WHITESPACE@[53; 54) " "
-              STRING@[54; 56) "\"\""
-              R_PAREN@[56; 57) ")"
-          SEMI@[57; 58) ";"
-        WHITESPACE@[58; 59) "\n"
-        R_CURLY@[59; 60) "}"
-"#
-            .trim()
-        );
-    }
-
-    #[test]
-    fn test_syntax_tree_with_range() {
-        let (analysis, range) = single_file_with_range(r#"<|>fn foo() {}<|>"#.trim());
-        let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap();
-
-        assert_eq_text!(
-            syn.trim(),
-            r#"
-FN_DEF@[0; 11)
-  FN_KW@[0; 2) "fn"
-  WHITESPACE@[2; 3) " "
-  NAME@[3; 6)
-    IDENT@[3; 6) "foo"
-  PARAM_LIST@[6; 8)
-    L_PAREN@[6; 7) "("
-    R_PAREN@[7; 8) ")"
-  WHITESPACE@[8; 9) " "
-  BLOCK_EXPR@[9; 11)
-    BLOCK@[9; 11)
-      L_CURLY@[9; 10) "{"
-      R_CURLY@[10; 11) "}"
-"#
-            .trim()
-        );
-
-        let (analysis, range) = single_file_with_range(
-            r#"fn test() {
-    <|>assert!("
-    fn foo() {
-    }
-    ", "");<|>
-}"#
-            .trim(),
-        );
-        let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap();
-
-        assert_eq_text!(
-            syn.trim(),
-            r#"
-EXPR_STMT@[16; 58)
-  MACRO_CALL@[16; 57)
-    PATH@[16; 22)
-      PATH_SEGMENT@[16; 22)
-        NAME_REF@[16; 22)
-          IDENT@[16; 22) "assert"
-    EXCL@[22; 23) "!"
-    TOKEN_TREE@[23; 57)
-      L_PAREN@[23; 24) "("
-      STRING@[24; 52) "\"\n    fn foo() {\n     ..."
-      COMMA@[52; 53) ","
-      WHITESPACE@[53; 54) " "
-      STRING@[54; 56) "\"\""
-      R_PAREN@[56; 57) ")"
-  SEMI@[57; 58) ";"
-"#
-            .trim()
-        );
-    }
-
-    #[test]
-    fn test_syntax_tree_inside_string() {
-        let (analysis, range) = single_file_with_range(
-            r#"fn test() {
-    assert!("
-<|>fn foo() {
-}<|>
-fn bar() {
-}
-    ", "");
-}"#
-            .trim(),
-        );
-        let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap();
-        assert_eq_text!(
-            syn.trim(),
-            r#"
-SOURCE_FILE@[0; 12)
-  FN_DEF@[0; 12)
-    FN_KW@[0; 2) "fn"
-    WHITESPACE@[2; 3) " "
-    NAME@[3; 6)
-      IDENT@[3; 6) "foo"
-    PARAM_LIST@[6; 8)
-      L_PAREN@[6; 7) "("
-      R_PAREN@[7; 8) ")"
-    WHITESPACE@[8; 9) " "
-    BLOCK_EXPR@[9; 12)
-      BLOCK@[9; 12)
-        L_CURLY@[9; 10) "{"
-        WHITESPACE@[10; 11) "\n"
-        R_CURLY@[11; 12) "}"
-"#
-            .trim()
-        );
-
-        // With a raw string
-        let (analysis, range) = single_file_with_range(
-            r###"fn test() {
-    assert!(r#"
-<|>fn foo() {
-}<|>
-fn bar() {
-}
-    "#, "");
-}"###
-                .trim(),
-        );
-        let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap();
-        assert_eq_text!(
-            syn.trim(),
-            r#"
-SOURCE_FILE@[0; 12)
-  FN_DEF@[0; 12)
-    FN_KW@[0; 2) "fn"
-    WHITESPACE@[2; 3) " "
-    NAME@[3; 6)
-      IDENT@[3; 6) "foo"
-    PARAM_LIST@[6; 8)
-      L_PAREN@[6; 7) "("
-      R_PAREN@[7; 8) ")"
-    WHITESPACE@[8; 9) " "
-    BLOCK_EXPR@[9; 12)
-      BLOCK@[9; 12)
-        L_CURLY@[9; 10) "{"
-        WHITESPACE@[10; 11) "\n"
-        R_CURLY@[11; 12) "}"
-"#
-            .trim()
-        );
-
-        // With a raw string
-        let (analysis, range) = single_file_with_range(
-            r###"fn test() {
-    assert!(r<|>#"
-fn foo() {
-}
-fn bar() {
-}"<|>#, "");
-}"###
-                .trim(),
-        );
-        let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap();
-        assert_eq_text!(
-            syn.trim(),
-            r#"
-SOURCE_FILE@[0; 25)
-  FN_DEF@[0; 12)
-    FN_KW@[0; 2) "fn"
-    WHITESPACE@[2; 3) " "
-    NAME@[3; 6)
-      IDENT@[3; 6) "foo"
-    PARAM_LIST@[6; 8)
-      L_PAREN@[6; 7) "("
-      R_PAREN@[7; 8) ")"
-    WHITESPACE@[8; 9) " "
-    BLOCK_EXPR@[9; 12)
-      BLOCK@[9; 12)
-        L_CURLY@[9; 10) "{"
-        WHITESPACE@[10; 11) "\n"
-        R_CURLY@[11; 12) "}"
-  WHITESPACE@[12; 13) "\n"
-  FN_DEF@[13; 25)
-    FN_KW@[13; 15) "fn"
-    WHITESPACE@[15; 16) " "
-    NAME@[16; 19)
-      IDENT@[16; 19) "bar"
-    PARAM_LIST@[19; 21)
-      L_PAREN@[19; 20) "("
-      R_PAREN@[20; 21) ")"
-    WHITESPACE@[21; 22) " "
-    BLOCK_EXPR@[22; 25)
-      BLOCK@[22; 25)
-        L_CURLY@[22; 23) "{"
-        WHITESPACE@[23; 24) "\n"
-        R_CURLY@[24; 25) "}"
-"#
-            .trim()
-        );
-    }
-}
+use crate::db::RootDatabase;
+use ra_db::SourceDatabase;
+use ra_syntax::{
+    algo, AstNode, NodeOrToken, SourceFile,
+    SyntaxKind::{RAW_STRING, STRING},
+    SyntaxToken, TextRange,
+};
+
+pub use ra_db::FileId;
+
+pub(crate) fn syntax_tree(
+    db: &RootDatabase,
+    file_id: FileId,
+    text_range: Option<TextRange>,
+) -> String {
+    let parse = db.parse(file_id);
+    if let Some(text_range) = text_range {
+        let node = match algo::find_covering_element(parse.tree().syntax(), text_range) {
+            NodeOrToken::Node(node) => node,
+            NodeOrToken::Token(token) => {
+                if let Some(tree) = syntax_tree_for_string(&token, text_range) {
+                    return tree;
+                }
+                token.parent()
+            }
+        };
+
+        format!("{:#?}", node)
+    } else {
+        format!("{:#?}", parse.tree().syntax())
+    }
+}
+
+/// Attempts parsing the selected contents of a string literal
+/// as rust syntax and returns its syntax tree
+fn syntax_tree_for_string(token: &SyntaxToken, text_range: TextRange) -> Option<String> {
+    // When the range is inside a string
+    // we'll attempt parsing it as rust syntax
+    // to provide the syntax tree of the contents of the string
+    match token.kind() {
+        STRING | RAW_STRING => syntax_tree_for_token(token, text_range),
+        _ => None,
+    }
+}
+
+fn syntax_tree_for_token(node: &SyntaxToken, text_range: TextRange) -> Option<String> {
+    // Range of the full node
+    let node_range = node.text_range();
+    let text = node.text().to_string();
+
+    // We start at some point inside the node
+    // Either we have selected the whole string
+    // or our selection is inside it
+    let start = text_range.start() - node_range.start();
+
+    // how many characters we have selected
+    let len = text_range.len().to_usize();
+
+    let node_len = node_range.len().to_usize();
+
+    let start = start.to_usize();
+
+    // We want to cap our length
+    let len = len.min(node_len);
+
+    // Ensure our slice is inside the actual string
+    let end = if start + len < text.len() { start + len } else { text.len() - start };
+
+    let text = &text[start..end];
+
+    // Remove possible extra string quotes from the start
+    // and the end of the string
+    let text = text
+        .trim_start_matches('r')
+        .trim_start_matches('#')
+        .trim_start_matches('"')
+        .trim_end_matches('#')
+        .trim_end_matches('"')
+        .trim()
+        // Remove custom markers
+        .replace("<|>", "");
+
+    let parsed = SourceFile::parse(&text);
+
+    // If the "file" parsed without errors,
+    // return its syntax
+    if parsed.errors().is_empty() {
+        return Some(format!("{:#?}", parsed.tree().syntax()));
+    }
+
+    None
+}
+
+#[cfg(test)]
+mod tests {
+    use test_utils::assert_eq_text;
+
+    use crate::mock_analysis::{single_file, single_file_with_range};
+
+    #[test]
+    fn test_syntax_tree_without_range() {
+        // Basic syntax
+        let (analysis, file_id) = single_file(r#"fn foo() {}"#);
+        let syn = analysis.syntax_tree(file_id, None).unwrap();
+
+        assert_eq_text!(
+            syn.trim(),
+            r#"
+SOURCE_FILE@[0; 11)
+  FN_DEF@[0; 11)
+    FN_KW@[0; 2) "fn"
+    WHITESPACE@[2; 3) " "
+    NAME@[3; 6)
+      IDENT@[3; 6) "foo"
+    PARAM_LIST@[6; 8)
+      L_PAREN@[6; 7) "("
+      R_PAREN@[7; 8) ")"
+    WHITESPACE@[8; 9) " "
+    BLOCK_EXPR@[9; 11)
+      BLOCK@[9; 11)
+        L_CURLY@[9; 10) "{"
+        R_CURLY@[10; 11) "}"
+"#
+            .trim()
+        );
+
+        let (analysis, file_id) = single_file(
+            r#"
+fn test() {
+    assert!("
+    fn foo() {
+    }
+    ", "");
+}"#
+            .trim(),
+        );
+        let syn = analysis.syntax_tree(file_id, None).unwrap();
+
+        assert_eq_text!(
+            syn.trim(),
+            r#"
+SOURCE_FILE@[0; 60)
+  FN_DEF@[0; 60)
+    FN_KW@[0; 2) "fn"
+    WHITESPACE@[2; 3) " "
+    NAME@[3; 7)
+      IDENT@[3; 7) "test"
+    PARAM_LIST@[7; 9)
+      L_PAREN@[7; 8) "("
+      R_PAREN@[8; 9) ")"
+    WHITESPACE@[9; 10) " "
+    BLOCK_EXPR@[10; 60)
+      BLOCK@[10; 60)
+        L_CURLY@[10; 11) "{"
+        WHITESPACE@[11; 16) "\n    "
+        EXPR_STMT@[16; 58)
+          MACRO_CALL@[16; 57)
+            PATH@[16; 22)
+              PATH_SEGMENT@[16; 22)
+                NAME_REF@[16; 22)
+                  IDENT@[16; 22) "assert"
+            EXCL@[22; 23) "!"
+            TOKEN_TREE@[23; 57)
+              L_PAREN@[23; 24) "("
+              STRING@[24; 52) "\"\n    fn foo() {\n     ..."
+              COMMA@[52; 53) ","
+              WHITESPACE@[53; 54) " "
+              STRING@[54; 56) "\"\""
+              R_PAREN@[56; 57) ")"
+          SEMI@[57; 58) ";"
+        WHITESPACE@[58; 59) "\n"
+        R_CURLY@[59; 60) "}"
+"#
+            .trim()
+        );
+    }
+
+    #[test]
+    fn test_syntax_tree_with_range() {
+        let (analysis, range) = single_file_with_range(r#"<|>fn foo() {}<|>"#.trim());
+        let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap();
+
+        assert_eq_text!(
+            syn.trim(),
+            r#"
+FN_DEF@[0; 11)
+  FN_KW@[0; 2) "fn"
+  WHITESPACE@[2; 3) " "
+  NAME@[3; 6)
+    IDENT@[3; 6) "foo"
+  PARAM_LIST@[6; 8)
+    L_PAREN@[6; 7) "("
+    R_PAREN@[7; 8) ")"
+  WHITESPACE@[8; 9) " "
+  BLOCK_EXPR@[9; 11)
+    BLOCK@[9; 11)
+      L_CURLY@[9; 10) "{"
+      R_CURLY@[10; 11) "}"
+"#
+            .trim()
+        );
+
+        let (analysis, range) = single_file_with_range(
+            r#"fn test() {
+    <|>assert!("
+    fn foo() {
+    }
+    ", "");<|>
+}"#
+            .trim(),
+        );
+        let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap();
+
+        assert_eq_text!(
+            syn.trim(),
+            r#"
+EXPR_STMT@[16; 58)
+  MACRO_CALL@[16; 57)
+    PATH@[16; 22)
+      PATH_SEGMENT@[16; 22)
+        NAME_REF@[16; 22)
+          IDENT@[16; 22) "assert"
+    EXCL@[22; 23) "!"
+    TOKEN_TREE@[23; 57)
+      L_PAREN@[23; 24) "("
+      STRING@[24; 52) "\"\n    fn foo() {\n     ..."
+      COMMA@[52; 53) ","
+      WHITESPACE@[53; 54) " "
+      STRING@[54; 56) "\"\""
+      R_PAREN@[56; 57) ")"
+  SEMI@[57; 58) ";"
+"#
+            .trim()
+        );
+    }
+
+    #[test]
+    fn test_syntax_tree_inside_string() {
+        let (analysis, range) = single_file_with_range(
+            r#"fn test() {
+    assert!("
+<|>fn foo() {
+}<|>
+fn bar() {
+}
+    ", "");
+}"#
+            .trim(),
+        );
+        let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap();
+        assert_eq_text!(
+            syn.trim(),
+            r#"
+SOURCE_FILE@[0; 12)
+  FN_DEF@[0; 12)
+    FN_KW@[0; 2) "fn"
+    WHITESPACE@[2; 3) " "
+    NAME@[3; 6)
+      IDENT@[3; 6) "foo"
+    PARAM_LIST@[6; 8)
+      L_PAREN@[6; 7) "("
+      R_PAREN@[7; 8) ")"
+    WHITESPACE@[8; 9) " "
+    BLOCK_EXPR@[9; 12)
+      BLOCK@[9; 12)
+        L_CURLY@[9; 10) "{"
+        WHITESPACE@[10; 11) "\n"
+        R_CURLY@[11; 12) "}"
+"#
+            .trim()
+        );
+
+        // With a raw string
+        let (analysis, range) = single_file_with_range(
+            r###"fn test() {
+    assert!(r#"
+<|>fn foo() {
+}<|>
+fn bar() {
+}
+    "#, "");
+}"###
+                .trim(),
+        );
+        let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap();
+        assert_eq_text!(
+            syn.trim(),
+            r#"
+SOURCE_FILE@[0; 12)
+  FN_DEF@[0; 12)
+    FN_KW@[0; 2) "fn"
+    WHITESPACE@[2; 3) " "
+    NAME@[3; 6)
+      IDENT@[3; 6) "foo"
+    PARAM_LIST@[6; 8)
+      L_PAREN@[6; 7) "("
+      R_PAREN@[7; 8) ")"
+    WHITESPACE@[8; 9) " "
+    BLOCK_EXPR@[9; 12)
+      BLOCK@[9; 12)
+        L_CURLY@[9; 10) "{"
+        WHITESPACE@[10; 11) "\n"
+        R_CURLY@[11; 12) "}"
+"#
+            .trim()
+        );
+
+        // With a raw string
+        let (analysis, range) = single_file_with_range(
+            r###"fn test() {
+    assert!(r<|>#"
+fn foo() {
+}
+fn bar() {
+}"<|>#, "");
+}"###
+                .trim(),
+        );
+        let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap();
+        assert_eq_text!(
+            syn.trim(),
+            r#"
+SOURCE_FILE@[0; 25)
+  FN_DEF@[0; 12)
+    FN_KW@[0; 2) "fn"
+    WHITESPACE@[2; 3) " "
+    NAME@[3; 6)
+      IDENT@[3; 6) "foo"
+    PARAM_LIST@[6; 8)
+      L_PAREN@[6; 7) "("
+      R_PAREN@[7; 8) ")"
+    WHITESPACE@[8; 9) " "
+    BLOCK_EXPR@[9; 12)
+      BLOCK@[9; 12)
+        L_CURLY@[9; 10) "{"
+        WHITESPACE@[10; 11) "\n"
+        R_CURLY@[11; 12) "}"
+  WHITESPACE@[12; 13) "\n"
+  FN_DEF@[13; 25)
+    FN_KW@[13; 15) "fn"
+    WHITESPACE@[15; 16) " "
+    NAME@[16; 19)
+      IDENT@[16; 19) "bar"
+    PARAM_LIST@[19; 21)
+      L_PAREN@[19; 20) "("
+      R_PAREN@[20; 21) ")"
+    WHITESPACE@[21; 22) " "
+    BLOCK_EXPR@[22; 25)
+      BLOCK@[22; 25)
+        L_CURLY@[22; 23) "{"
+        WHITESPACE@[23; 24) "\n"
+        R_CURLY@[24; 25) "}"
+"#
+            .trim()
+        );
+    }
+}
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs
index 948d543ea2..eb805a6d39 100644
--- a/crates/ra_lsp_server/src/main_loop/handlers.rs
+++ b/crates/ra_lsp_server/src/main_loop/handlers.rs
@@ -460,16 +460,18 @@ pub fn handle_prepare_rename(
 
     // We support renaming references like handle_rename does.
     // In the future we may want to reject the renaming of things like keywords here too.
-    let optional_change = world.analysis().rename(position, "dummy")?;
-    let range = match optional_change {
+    let refs = match world.analysis().find_all_refs(position)? {
         None => return Ok(None),
-        Some(it) => it.range,
+        Some(refs) => refs,
     };
 
+    // Refs should always have a declaration
+    let r = refs.declaration();
     let file_id = params.text_document.try_conv_with(&world)?;
     let line_index = world.analysis().file_line_index(file_id)?;
-    let range = range.conv_with(&line_index);
-    Ok(Some(PrepareRenameResponse::Range(range)))
+    let loc = to_location(r.file_id(), r.range(), &world, &line_index)?;
+
+    Ok(Some(PrepareRenameResponse::Range(loc.range)))
 }
 
 pub fn handle_rename(world: WorldSnapshot, params: RenameParams) -> Result<Option<WorkspaceEdit>> {
@@ -486,7 +488,7 @@ pub fn handle_rename(world: WorldSnapshot, params: RenameParams) -> Result<Optio
     let optional_change = world.analysis().rename(position, &*params.new_name)?;
     let change = match optional_change {
         None => return Ok(None),
-        Some(it) => it.info,
+        Some(it) => it,
     };
 
     let source_change_req = change.try_conv_with(&world)?;
diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs
index b4327b78f4..6d426206e9 100644
--- a/crates/ra_parser/src/grammar/items.rs
+++ b/crates/ra_parser/src/grammar/items.rs
@@ -31,7 +31,7 @@ pub(super) enum ItemFlavor {
 
 pub(super) const ITEM_RECOVERY_SET: TokenSet = token_set![
     FN_KW, STRUCT_KW, ENUM_KW, IMPL_KW, TRAIT_KW, CONST_KW, STATIC_KW, LET_KW, MOD_KW, PUB_KW,
-    CRATE_KW, USE_KW
+    CRATE_KW
 ];
 
 pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool, flavor: ItemFlavor) {
diff --git a/crates/ra_parser/src/grammar/items/use_item.rs b/crates/ra_parser/src/grammar/items/use_item.rs
index 83a65e2265..c0c7d0ec6f 100644
--- a/crates/ra_parser/src/grammar/items/use_item.rs
+++ b/crates/ra_parser/src/grammar/items/use_item.rs
@@ -101,10 +101,7 @@ fn use_tree(p: &mut Parser) {
         }
         _ => {
             m.abandon(p);
-            p.err_recover(
-                "expected one of `*`, `::`, `{`, `self`, `super` or an identifier",
-                ITEM_RECOVERY_SET,
-            );
+            p.err_and_bump("expected one of `*`, `::`, `{`, `self`, `super` or an indentifier");
             return;
         }
     }
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs
index 9b2f534e71..676dc49418 100644
--- a/crates/ra_project_model/src/lib.rs
+++ b/crates/ra_project_model/src/lib.rs
@@ -153,7 +153,7 @@ impl ProjectWorkspace {
                     if let Some(file_id) = load(krate.root(&sysroot)) {
                         sysroot_crates.insert(
                             krate,
-                            crate_graph.add_crate_root(file_id, Edition::Edition2018),
+                            crate_graph.add_crate_root(file_id, Edition::Edition2015),
                         );
                     }
                 }
diff --git a/docs/user/features.md b/docs/user/features.md
index 1034a51172..b6e6008c42 100644
--- a/docs/user/features.md
+++ b/docs/user/features.md
@@ -435,16 +435,6 @@ fn f() {
 }
 ```
 
-- Move type bounds to where clause
-
-```rust
-// before:
-fn foo<T: u32, F: FnOnce(T) -> T>() {}
-
-// after:
-fn foo<T, F>() where T: u32, F: FnOnce(T) -> T {}
-```
-
 ### Magic Completions
 
 In addition to usual reference completion, rust-analyzer provides some ✨magic✨
diff --git a/rustfmt.toml b/rustfmt.toml
index f2e1646181..71007de81b 100644
--- a/rustfmt.toml
+++ b/rustfmt.toml
@@ -1,3 +1,2 @@
 reorder_modules = false
 use_small_heuristics = "Max"
-newline_style = "Unix"


Test patch:
diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs
index 4ff897ca5e..c1dbad283a 100644
--- a/crates/ra_hir/src/nameres/tests.rs
+++ b/crates/ra_hir/src/nameres/tests.rs
@@ -2,7 +2,7 @@ mod macros;
 mod globs;
 mod incremental;
 mod primitives;
-mod mod_resolution;
+mod mods;
 
 use std::sync::Arc;
 
diff --git a/crates/ra_hir/src/nameres/tests/macros.rs b/crates/ra_hir/src/nameres/tests/macros.rs
index ebfefe273f..aece1515b5 100644
--- a/crates/ra_hir/src/nameres/tests/macros.rs
+++ b/crates/ra_hir/src/nameres/tests/macros.rs
@@ -144,9 +144,6 @@ fn macro_rules_from_other_crates_are_visible_with_macro_use() {
     let map = def_map_with_crate_graph(
         "
         //- /main.rs
-        #[macro_use]
-        extern crate foo;
-
         structs!(Foo);
         structs_priv!(Bar);
         structs_not_exported!(MacroNotResolved1);
@@ -154,6 +151,9 @@ fn macro_rules_from_other_crates_are_visible_with_macro_use() {
 
         mod bar;
 
+        #[macro_use]
+        extern crate foo;
+
         //- /bar.rs
         structs!(Baz);
         crate::structs!(MacroNotResolved3);
@@ -191,3 +191,60 @@ fn macro_rules_from_other_crates_are_visible_with_macro_use() {
    ⋮Baz: t v
     "###);
 }
+
+#[test]
+fn prelude_is_macro_use() {
+    covers!(prelude_is_macro_use);
+    let map = def_map_with_crate_graph(
+        "
+        //- /main.rs
+        structs!(Foo);
+        structs_priv!(Bar);
+        structs_outside!(Out);
+        crate::structs!(MacroNotResolved2);
+
+        mod bar;
+
+        //- /bar.rs
+        structs!(Baz);
+        crate::structs!(MacroNotResolved3);
+
+        //- /lib.rs
+        #[prelude_import]
+        use self::prelude::*;
+
+        mod prelude {
+            #[macro_export]
+            macro_rules! structs {
+                ($i:ident) => { struct $i; }
+            }
+
+            mod priv_mod {
+                #[macro_export]
+                macro_rules! structs_priv {
+                    ($i:ident) => { struct $i; }
+                }
+            }
+        }
+
+        #[macro_export]
+        macro_rules! structs_outside {
+            ($i:ident) => { struct $i; }
+        }
+        ",
+        crate_graph! {
+            "main": ("/main.rs", ["foo"]),
+            "foo": ("/lib.rs", []),
+        },
+    );
+    assert_snapshot!(map, @r###"
+   ⋮crate
+   ⋮Bar: t v
+   ⋮Foo: t v
+   ⋮Out: t v
+   ⋮bar: t
+   ⋮
+   ⋮crate::bar
+   ⋮Baz: t v
+    "###);
+}
diff --git a/crates/ra_syntax/test_data/parser/err/0002_duplicate_shebang.txt b/crates/ra_syntax/test_data/parser/err/0002_duplicate_shebang.txt
index bdb5fa6c5a..84867026f4 100644
--- a/crates/ra_syntax/test_data/parser/err/0002_duplicate_shebang.txt
+++ b/crates/ra_syntax/test_data/parser/err/0002_duplicate_shebang.txt
@@ -28,7 +28,7 @@ SOURCE_FILE@[0; 42)
   WHITESPACE@[41; 42) "\n"
 error 23: expected `[`
 error 23: expected an item
-error 27: expected one of `*`, `::`, `{`, `self`, `super` or an identifier
+error 27: expected one of `*`, `::`, `{`, `self`, `super` or an indentifier
 error 28: expected SEMI
 error 31: expected EXCL
 error 31: expected `{`, `[`, `(`
diff --git a/crates/ra_syntax/test_data/parser/err/0035_use_recover.rs b/crates/ra_syntax/test_data/parser/err/0035_use_recover.rs
deleted file mode 100644
index 4a26681262..0000000000
--- a/crates/ra_syntax/test_data/parser/err/0035_use_recover.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-use foo::bar;
-use
-use crate::baz;
-use
-fn f() {}
diff --git a/crates/ra_syntax/test_data/parser/err/0035_use_recover.txt b/crates/ra_syntax/test_data/parser/err/0035_use_recover.txt
deleted file mode 100644
index 6368408288..0000000000
--- a/crates/ra_syntax/test_data/parser/err/0035_use_recover.txt
+++ /dev/null
@@ -1,54 +0,0 @@
-SOURCE_FILE@[0; 48)
-  USE_ITEM@[0; 13)
-    USE_KW@[0; 3) "use"
-    WHITESPACE@[3; 4) " "
-    USE_TREE@[4; 12)
-      PATH@[4; 12)
-        PATH@[4; 7)
-          PATH_SEGMENT@[4; 7)
-            NAME_REF@[4; 7)
-              IDENT@[4; 7) "foo"
-        COLONCOLON@[7; 9) "::"
-        PATH_SEGMENT@[9; 12)
-          NAME_REF@[9; 12)
-            IDENT@[9; 12) "bar"
-    SEMI@[12; 13) ";"
-  WHITESPACE@[13; 14) "\n"
-  USE_ITEM@[14; 17)
-    USE_KW@[14; 17) "use"
-  WHITESPACE@[17; 18) "\n"
-  USE_ITEM@[18; 33)
-    USE_KW@[18; 21) "use"
-    WHITESPACE@[21; 22) " "
-    USE_TREE@[22; 32)
-      PATH@[22; 32)
-        PATH@[22; 27)
-          PATH_SEGMENT@[22; 27)
-            CRATE_KW@[22; 27) "crate"
-        COLONCOLON@[27; 29) "::"
-        PATH_SEGMENT@[29; 32)
-          NAME_REF@[29; 32)
-            IDENT@[29; 32) "baz"
-    SEMI@[32; 33) ";"
-  WHITESPACE@[33; 34) "\n"
-  USE_ITEM@[34; 37)
-    USE_KW@[34; 37) "use"
-  WHITESPACE@[37; 38) "\n"
-  FN_DEF@[38; 47)
-    FN_KW@[38; 40) "fn"
-    WHITESPACE@[40; 41) " "
-    NAME@[41; 42)
-      IDENT@[41; 42) "f"
-    PARAM_LIST@[42; 44)
-      L_PAREN@[42; 43) "("
-      R_PAREN@[43; 44) ")"
-    WHITESPACE@[44; 45) " "
-    BLOCK_EXPR@[45; 47)
-      BLOCK@[45; 47)
-        L_CURLY@[45; 46) "{"
-        R_CURLY@[46; 47) "}"
-  WHITESPACE@[47; 48) "\n"
-error 17: expected one of `*`, `::`, `{`, `self`, `super` or an identifier
-error 17: expected SEMI
-error 37: expected one of `*`, `::`, `{`, `self`, `super` or an identifier
-error 37: expected SEMI