Repository: rust-analyzer/rust-analyzer
Pull request #260 (2018-12-06 18:16:48)

Modernize


Patch:
diff --git a/.travis.yml b/.travis.yml
index ece7425fe3..1af8bc1b72 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,7 +9,7 @@ env:
 
 build: &rust_build
   language: rust
-  rust: 1.31.0
+  rust: stable
   script:
     - cargo gen-tests --verify
     - cargo gen-syntax --verify
diff --git a/crates/gen_lsp_server/Cargo.toml b/crates/gen_lsp_server/Cargo.toml
index cf5c34a887..08b357b1eb 100644
--- a/crates/gen_lsp_server/Cargo.toml
+++ b/crates/gen_lsp_server/Cargo.toml
@@ -1,4 +1,5 @@
 [package]
+edition = "2018"
 name = "gen_lsp_server"
 version = "0.1.0"
 authors = ["Aleksey Kladov <aleksey.kladov@gmail.com>"]
diff --git a/crates/gen_lsp_server/src/lib.rs b/crates/gen_lsp_server/src/lib.rs
index 5dab8f4086..8779fbf0fd 100644
--- a/crates/gen_lsp_server/src/lib.rs
+++ b/crates/gen_lsp_server/src/lib.rs
@@ -59,16 +59,7 @@
 //! }
 //! ```
 
-#[macro_use]
-extern crate failure;
-#[macro_use]
-extern crate log;
-extern crate serde;
-extern crate serde_json;
-#[macro_use]
-extern crate serde_derive;
-extern crate crossbeam_channel;
-extern crate languageserver_types;
+use failure::{bail, format_err};
 
 mod msg;
 mod stdio;
@@ -81,7 +72,7 @@ use languageserver_types::{
 };
 
 pub type Result<T> = ::std::result::Result<T, failure::Error>;
-pub use {
+pub use crate::{
     msg::{ErrorCode, RawMessage, RawNotification, RawRequest, RawResponse, RawResponseError},
     stdio::{stdio_transport, Threads},
 };
@@ -98,18 +89,18 @@ pub fn run_server(
     sender: Sender<RawMessage>,
     server: impl FnOnce(InitializeParams, &Receiver<RawMessage>, &Sender<RawMessage>) -> Result<()>,
 ) -> Result<()> {
-    info!("lsp server initializes");
+    log::info!("lsp server initializes");
     let params = initialize(&receiver, &sender, caps)?;
-    info!("lsp server initialized, serving requests");
+    log::info!("lsp server initialized, serving requests");
     server(params, &receiver, &sender)?;
-    info!("lsp server waiting for exit notification");
+    log::info!("lsp server waiting for exit notification");
     match receiver.recv() {
         Some(RawMessage::Notification(n)) => n
             .cast::<Exit>()
             .map_err(|n| format_err!("unexpected notification during shutdown: {:?}", n))?,
         m => bail!("unexpected message during shutdown: {:?}", m),
     }
-    info!("lsp server shutdown complete");
+    log::info!("lsp server shutdown complete");
     Ok(())
 }
 
diff --git a/crates/gen_lsp_server/src/msg.rs b/crates/gen_lsp_server/src/msg.rs
index e1b27c808e..1e5384380f 100644
--- a/crates/gen_lsp_server/src/msg.rs
+++ b/crates/gen_lsp_server/src/msg.rs
@@ -1,10 +1,11 @@
 use std::io::{BufRead, Write};
 
 use languageserver_types::{notification::Notification, request::Request};
-use serde::{de::DeserializeOwned, Serialize};
+use serde_derive::{Deserialize, Serialize};
 use serde_json::{from_str, from_value, to_string, to_value, Value};
+use failure::{bail, format_err};
 
-use Result;
+use crate::Result;
 
 #[derive(Debug, Serialize, Deserialize, Clone)]
 #[serde(untagged)]
@@ -91,7 +92,7 @@ impl RawRequest {
     pub fn new<R>(id: u64, params: &R::Params) -> RawRequest
     where
         R: Request,
-        R::Params: Serialize,
+        R::Params: serde::Serialize,
     {
         RawRequest {
             id,
@@ -102,7 +103,7 @@ impl RawRequest {
     pub fn cast<R>(self) -> ::std::result::Result<(u64, R::Params), RawRequest>
     where
         R: Request,
-        R::Params: DeserializeOwned,
+        R::Params: serde::de::DeserializeOwned,
     {
         if self.method != R::METHOD {
             return Err(self);
@@ -117,7 +118,7 @@ impl RawResponse {
     pub fn ok<R>(id: u64, result: &R::Result) -> RawResponse
     where
         R: Request,
-        R::Result: Serialize,
+        R::Result: serde::Serialize,
     {
         RawResponse {
             id,
@@ -143,7 +144,7 @@ impl RawNotification {
     pub fn new<N>(params: &N::Params) -> RawNotification
     where
         N: Notification,
-        N::Params: Serialize,
+        N::Params: serde::Serialize,
     {
         RawNotification {
             method: N::METHOD.to_string(),
@@ -153,7 +154,7 @@ impl RawNotification {
     pub fn cast<N>(self) -> ::std::result::Result<N::Params, RawNotification>
     where
         N: Notification,
-        N::Params: DeserializeOwned,
+        N::Params: serde::de::DeserializeOwned,
     {
         if self.method != N::METHOD {
             return Err(self);
@@ -191,12 +192,12 @@ fn read_msg_text(inp: &mut impl BufRead) -> Result<Option<String>> {
     buf.resize(size, 0);
     inp.read_exact(&mut buf)?;
     let buf = String::from_utf8(buf)?;
-    debug!("< {}", buf);
+    log::debug!("< {}", buf);
     Ok(Some(buf))
 }
 
 fn write_msg_text(out: &mut impl Write, msg: &str) -> Result<()> {
-    debug!("> {}", msg);
+    log::debug!("> {}", msg);
     write!(out, "Content-Length: {}\r\n\r\n", msg.len())?;
     out.write_all(msg.as_bytes())?;
     out.flush()?;
diff --git a/crates/gen_lsp_server/src/stdio.rs b/crates/gen_lsp_server/src/stdio.rs
index 3d8a1712ab..35d8e46d00 100644
--- a/crates/gen_lsp_server/src/stdio.rs
+++ b/crates/gen_lsp_server/src/stdio.rs
@@ -4,8 +4,9 @@ use std::{
 };
 
 use crossbeam_channel::{bounded, Receiver, Sender};
+use failure::bail;
 
-use {RawMessage, Result};
+use crate::{RawMessage, Result};
 
 pub fn stdio_transport() -> (Receiver<RawMessage>, Sender<RawMessage>, Threads) {
     let (writer_sender, mut writer_receiver) = bounded::<RawMessage>(16);
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs
index 90528edfde..4b8b108167 100644
--- a/crates/ra_analysis/src/lib.rs
+++ b/crates/ra_analysis/src/lib.rs
@@ -1,14 +1,6 @@
 //! ra_analyzer crate is the brain of Rust analyzer. It relies on the `salsa`
 //! crate, which provides and incremental on-demand database of facts.
 
-extern crate fst;
-extern crate ra_editor;
-extern crate ra_syntax;
-extern crate rayon;
-extern crate relative_path;
-extern crate rustc_hash;
-extern crate salsa;
-
 macro_rules! ctry {
     ($expr:expr) => {
         match $expr {
diff --git a/crates/ra_cli/src/main.rs b/crates/ra_cli/src/main.rs
index 5ca86df4dd..939f7fe77d 100644
--- a/crates/ra_cli/src/main.rs
+++ b/crates/ra_cli/src/main.rs
@@ -1,11 +1,3 @@
-extern crate clap;
-#[macro_use]
-extern crate failure;
-extern crate join_to_string;
-extern crate ra_editor;
-extern crate ra_syntax;
-extern crate tools;
-
 use std::{fs, io::Read, path::Path, time::Instant};
 
 use clap::{App, Arg, SubCommand};
@@ -97,7 +89,7 @@ fn render_test(file: &Path, line: usize) -> Result<(String, String)> {
         *start_line <= line && line <= *start_line + t.text.lines().count()
     });
     let test = match test {
-        None => bail!("No test found at line {} at {}", line, file.display()),
+        None => failure::bail!("No test found at line {} at {}", line, file.display()),
         Some((_start_line, test)) => test,
     };
     let file = SourceFileNode::parse(&test.text);
diff --git a/crates/ra_editor/src/lib.rs b/crates/ra_editor/src/lib.rs
index c6b1161595..ce080ee971 100644
--- a/crates/ra_editor/src/lib.rs
+++ b/crates/ra_editor/src/lib.rs
@@ -1,12 +1,3 @@
-extern crate itertools;
-extern crate join_to_string;
-extern crate ra_syntax;
-extern crate rustc_hash;
-extern crate superslice;
-#[cfg(test)]
-#[macro_use]
-extern crate test_utils as _test_utils;
-
 mod code_actions;
 mod edit;
 mod extend_selection;
@@ -154,7 +145,7 @@ pub fn find_node_at_offset<'a, N: AstNode<'a>>(
 #[cfg(test)]
 mod tests {
     use super::*;
-    use crate::test_utils::{add_cursor, assert_eq_dbg, extract_offset};
+    use crate::test_utils::{add_cursor, assert_eq_dbg, extract_offset, assert_eq_text};
 
     #[test]
     fn test_highlighting() {
diff --git a/crates/ra_editor/src/typing.rs b/crates/ra_editor/src/typing.rs
index f894d83922..9703e03712 100644
--- a/crates/ra_editor/src/typing.rs
+++ b/crates/ra_editor/src/typing.rs
@@ -238,7 +238,7 @@ fn compute_ws(left: SyntaxNodeRef, right: SyntaxNodeRef) -> &'static str {
 #[cfg(test)]
 mod tests {
     use super::*;
-    use crate::test_utils::{add_cursor, check_action, extract_offset, extract_range};
+    use crate::test_utils::{add_cursor, check_action, extract_offset, extract_range, assert_eq_text};
 
     fn check_join_lines(before: &str, after: &str) {
         check_action(before, after, |file, offset| {
diff --git a/crates/ra_lsp_server/src/lib.rs b/crates/ra_lsp_server/src/lib.rs
index f9481e04d2..75c6fa1b8d 100644
--- a/crates/ra_lsp_server/src/lib.rs
+++ b/crates/ra_lsp_server/src/lib.rs
@@ -1,30 +1,3 @@
-#[macro_use]
-extern crate failure;
-#[macro_use]
-extern crate serde_derive;
-extern crate languageserver_types;
-extern crate serde;
-extern crate serde_json;
-#[macro_use]
-extern crate crossbeam_channel;
-extern crate rayon;
-#[macro_use]
-extern crate log;
-extern crate cargo_metadata;
-extern crate drop_bomb;
-#[macro_use]
-extern crate failure_derive;
-extern crate im;
-extern crate relative_path;
-extern crate rustc_hash;
-extern crate url_serde;
-extern crate walkdir;
-
-extern crate gen_lsp_server;
-extern crate ra_analysis;
-extern crate ra_editor;
-extern crate ra_syntax;
-
 mod caps;
 mod conv;
 mod main_loop;
diff --git a/crates/ra_lsp_server/src/main.rs b/crates/ra_lsp_server/src/main.rs
index 8301a10445..9ba9725620 100644
--- a/crates/ra_lsp_server/src/main.rs
+++ b/crates/ra_lsp_server/src/main.rs
@@ -1,15 +1,5 @@
-#[macro_use]
-extern crate log;
-#[macro_use]
-extern crate failure;
-#[macro_use]
-extern crate serde_derive;
-extern crate serde;
-extern crate flexi_logger;
-extern crate gen_lsp_server;
-extern crate ra_lsp_server;
-
-use serde::Deserialize;
+use serde_derive::Deserialize;
+use serde::Deserialize as _D;
 use flexi_logger::{Duplicate, Logger};
 use gen_lsp_server::{run_server, stdio_transport};
 use ra_lsp_server::Result;
@@ -21,15 +11,15 @@ fn main() -> Result<()> {
         .log_to_file()
         .directory("log")
         .start()?;
-    info!("lifecycle: server started");
+    log::info!("lifecycle: server started");
     match ::std::panic::catch_unwind(main_inner) {
         Ok(res) => {
-            info!("lifecycle: terminating process with {:?}", res);
+            log::info!("lifecycle: terminating process with {:?}", res);
             res
         }
         Err(_) => {
-            error!("server panicked");
-            bail!("server panicked")
+            log::error!("server panicked");
+            failure::bail!("server panicked")
         }
     }
 }
@@ -60,8 +50,8 @@ fn main_inner() -> Result<()> {
             ra_lsp_server::main_loop(false, root, publish_decorations, r, s)
         },
     )?;
-    info!("shutting down IO...");
+    log::info!("shutting down IO...");
     threads.join()?;
-    info!("... IO is down");
+    log::info!("... IO is down");
     Ok(())
 }
diff --git a/crates/ra_lsp_server/src/main_loop/mod.rs b/crates/ra_lsp_server/src/main_loop/mod.rs
index 36f08be2fe..0e18789068 100644
--- a/crates/ra_lsp_server/src/main_loop/mod.rs
+++ b/crates/ra_lsp_server/src/main_loop/mod.rs
@@ -3,7 +3,7 @@ mod subscriptions;
 
 use std::path::PathBuf;
 
-use crossbeam_channel::{unbounded, Receiver, Sender};
+use crossbeam_channel::{unbounded, select, Receiver, Sender};
 use gen_lsp_server::{
     handle_shutdown, ErrorCode, RawMessage, RawNotification, RawRequest, RawResponse,
 };
@@ -12,6 +12,8 @@ use ra_analysis::{Canceled, FileId, LibraryData};
 use rayon::{self, ThreadPool};
 use rustc_hash::FxHashSet;
 use serde::{de::DeserializeOwned, Serialize};
+use failure::{format_err, bail};
+use failure_derive::Fail;
 
 use crate::{
     main_loop::subscriptions::Subscriptions,
@@ -54,14 +56,14 @@ pub fn main_loop(
 ) -> Result<()> {
     let pool = rayon::ThreadPoolBuilder::new()
         .num_threads(4)
-        .panic_handler(|_| error!("thread panicked :("))
+        .panic_handler(|_| log::error!("thread panicked :("))
         .build()
         .unwrap();
     let (task_sender, task_receiver) = unbounded::<Task>();
     let (fs_worker, fs_watcher) = vfs::roots_loader();
     let (ws_worker, ws_watcher) = workspace_loader();
 
-    info!("server initialized, serving requests");
+    log::info!("server initialized, serving requests");
     let mut state = ServerWorldState::default();
 
     let mut pending_requests = FxHashSet::default();
@@ -82,12 +84,12 @@ pub fn main_loop(
         &mut subs,
     );
 
-    info!("waiting for tasks to finish...");
+    log::info!("waiting for tasks to finish...");
     task_receiver.for_each(|task| on_task(task, msg_sender, &mut pending_requests));
-    info!("...tasks have finished");
-    info!("joining threadpool...");
+    log::info!("...tasks have finished");
+    log::info!("joining threadpool...");
     drop(pool);
-    info!("...threadpool has finished");
+    log::info!("...threadpool has finished");
 
     let fs_res = fs_watcher.stop();
     let ws_res = ws_watcher.stop();
@@ -126,7 +128,7 @@ fn main_loop_inner(
             Ws(Result<CargoWorkspace>),
             Lib(LibraryData),
         }
-        trace!("selecting");
+        log::trace!("selecting");
         let event = select! {
             recv(msg_receiver, msg) => match msg {
                 Some(msg) => Event::Msg(msg),
@@ -147,7 +149,7 @@ fn main_loop_inner(
         match event {
             Event::Task(task) => on_task(task, msg_sender, pending_requests),
             Event::Fs(root, events) => {
-                info!("fs change, {}, {} events", root.display(), events.len());
+                log::info!("fs change, {}, {} events", root.display(), events.len());
                 if root == ws_root {
                     state.apply_fs_changes(events);
                 } else {
@@ -155,9 +157,9 @@ fn main_loop_inner(
                     let sender = libdata_sender.clone();
                     pool.spawn(move || {
                         let start = ::std::time::Instant::now();
-                        info!("indexing {} ... ", root.display());
+                        log::info!("indexing {} ... ", root.display());
                         let data = LibraryData::prepare(files, resolver);
-                        info!("indexed {:?} {}", start.elapsed(), root.display());
+                        log::info!("indexed {:?} {}", start.elapsed(), root.display());
                         sender.send(data);
                     });
                 }
@@ -195,14 +197,14 @@ fn main_loop_inner(
                             .map(|(_idx, root)| root);
 
                         for root in unique {
-                            debug!("sending root, {}", root.display());
+                            log::debug!("sending root, {}", root.display());
                             fs_worker.send(root.to_owned());
                         }
                     }
                     state.set_workspaces(workspaces);
                     state_changed = true;
                 }
-                Err(e) => warn!("loading workspace failed: {}", e),
+                Err(e) => log::warn!("loading workspace failed: {}", e),
             },
             Event::Lib(lib) => {
                 feedback(internal_mode, "library loaded", msg_sender);
@@ -217,7 +219,7 @@ fn main_loop_inner(
                     match on_request(state, pending_requests, pool, &task_sender, req)? {
                         None => (),
                         Some(req) => {
-                            error!("unknown request: {:?}", req);
+                            log::error!("unknown request: {:?}", req);
                             let resp = RawResponse::err(
                                 req.id,
                                 ErrorCode::MethodNotFound as i32,
@@ -231,7 +233,7 @@ fn main_loop_inner(
                     on_notification(msg_sender, state, pending_requests, subs, not)?;
                     state_changed = true;
                 }
-                RawMessage::Response(resp) => error!("unexpected response: {:?}", resp),
+                RawMessage::Response(resp) => log::error!("unexpected response: {:?}", resp),
             },
         };
 
@@ -370,7 +372,7 @@ fn on_notification(
         }
         Err(not) => not,
     };
-    error!("unhandled notification: {:?}", not);
+    log::error!("unhandled notification: {:?}", not);
     Ok(())
 }
 
@@ -455,7 +457,7 @@ fn update_file_notifications_on_threadpool(
             match handlers::publish_diagnostics(&world, file_id) {
                 Err(e) => {
                     if !is_canceled(&e) {
-                        error!("failed to compute diagnostics: {:?}", e);
+                        log::error!("failed to compute diagnostics: {:?}", e);
                     }
                 }
                 Ok(params) => {
@@ -467,7 +469,7 @@ fn update_file_notifications_on_threadpool(
                 match handlers::publish_decorations(&world, file_id) {
                     Err(e) => {
                         if !is_canceled(&e) {
-                            error!("failed to compute decorations: {:?}", e);
+                            log::error!("failed to compute decorations: {:?}", e);
                         }
                     }
                     Ok(params) => {
diff --git a/crates/ra_lsp_server/src/project_model.rs b/crates/ra_lsp_server/src/project_model.rs
index cabb336a31..3305d468aa 100644
--- a/crates/ra_lsp_server/src/project_model.rs
+++ b/crates/ra_lsp_server/src/project_model.rs
@@ -1,12 +1,14 @@
 use std::path::{Path, PathBuf};
 
+use serde_derive::Serialize;
 use cargo_metadata::{metadata_run, CargoOpt};
 use ra_syntax::SmolStr;
 use rustc_hash::{FxHashMap, FxHashSet};
+use failure::{format_err, bail};
 
 use crate::{
-    thread_watcher::{ThreadWatcher, Worker},
     Result,
+    thread_watcher::{ThreadWatcher, Worker},
 };
 
 #[derive(Debug, Clone)]
diff --git a/crates/ra_lsp_server/src/req.rs b/crates/ra_lsp_server/src/req.rs
index fcb7e94e16..999792ecba 100644
--- a/crates/ra_lsp_server/src/req.rs
+++ b/crates/ra_lsp_server/src/req.rs
@@ -1,3 +1,4 @@
+use serde_derive::{Serialize, Deserialize};
 use languageserver_types::{Location, Position, Range, TextDocumentIdentifier, Url};
 use rustc_hash::FxHashMap;
 use url_serde;
diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs
index 12faeb93af..c3f89ad5f0 100644
--- a/crates/ra_lsp_server/src/server_world.rs
+++ b/crates/ra_lsp_server/src/server_world.rs
@@ -9,6 +9,7 @@ use ra_analysis::{
     Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, FileResolver, LibraryData,
 };
 use rustc_hash::FxHashMap;
+use failure::{bail, format_err};
 
 use crate::{
     path_map::{PathMap, Root},
diff --git a/crates/ra_lsp_server/src/thread_watcher.rs b/crates/ra_lsp_server/src/thread_watcher.rs
index 5143c77ae6..99825d440d 100644
--- a/crates/ra_lsp_server/src/thread_watcher.rs
+++ b/crates/ra_lsp_server/src/thread_watcher.rs
@@ -2,6 +2,7 @@ use std::thread;
 
 use crossbeam_channel::{bounded, unbounded, Receiver, Sender};
 use drop_bomb::DropBomb;
+use failure::format_err;
 
 use crate::Result;
 
@@ -48,7 +49,7 @@ impl ThreadWatcher {
     }
 
     pub fn stop(mut self) -> Result<()> {
-        info!("waiting for {} to finish ...", self.name);
+        log::info!("waiting for {} to finish ...", self.name);
         let name = self.name;
         self.bomb.defuse();
         let res = self
@@ -56,8 +57,8 @@ impl ThreadWatcher {
             .join()
             .map_err(|_| format_err!("ThreadWatcher {} died", name));
         match &res {
-            Ok(()) => info!("... {} terminated with ok", name),
-            Err(_) => error!("... {} terminated with err", name),
+            Ok(()) => log::info!("... {} terminated with ok", name),
+            Err(_) => log::error!("... {} terminated with err", name),
         }
         res
     }
diff --git a/crates/ra_lsp_server/src/vfs.rs b/crates/ra_lsp_server/src/vfs.rs
index 6e317d8546..00ab3e6c3d 100644
--- a/crates/ra_lsp_server/src/vfs.rs
+++ b/crates/ra_lsp_server/src/vfs.rs
@@ -25,9 +25,9 @@ pub fn roots_loader() -> (Worker<PathBuf, (PathBuf, Vec<FileEvent>)>, ThreadWatc
         |input_receiver, output_sender| {
             input_receiver
                 .map(|path| {
-                    debug!("loading {} ...", path.as_path().display());
+                    log::debug!("loading {} ...", path.as_path().display());
                     let events = load_root(path.as_path());
-                    debug!("... loaded {}", path.as_path().display());
+                    log::debug!("... loaded {}", path.as_path().display());
                     (path, events)
                 })
                 .for_each(|it| output_sender.send(it))
@@ -41,7 +41,7 @@ fn load_root(path: &Path) -> Vec<FileEvent> {
         let entry = match entry {
             Ok(entry) => entry,
             Err(e) => {
-                warn!("watcher error: {}", e);
+                log::warn!("watcher error: {}", e);
                 continue;
             }
         };
@@ -55,7 +55,7 @@ fn load_root(path: &Path) -> Vec<FileEvent> {
         let text = match fs::read_to_string(path) {
             Ok(text) => text,
             Err(e) => {
-                warn!("watcher error: {}", e);
+                log::warn!("watcher error: {}", e);
                 continue;
             }
         };
diff --git a/crates/ra_syntax/Cargo.toml b/crates/ra_syntax/Cargo.toml
index 54ee723861..8ad8ed196c 100644
--- a/crates/ra_syntax/Cargo.toml
+++ b/crates/ra_syntax/Cargo.toml
@@ -1,5 +1,5 @@
 [package]
-edition = "2015"
+edition = "2018"
 name = "ra_syntax"
 version = "0.1.0"
 authors = ["Aleksey Kladov <aleksey.kladov@gmail.com>"]
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs
index 330f680533..0e5c9baadd 100644
--- a/crates/ra_syntax/src/lib.rs
+++ b/crates/ra_syntax/src/lib.rs
@@ -20,17 +20,6 @@
 #![allow(missing_docs)]
 //#![warn(unreachable_pub)] // rust-lang/rust#47816
 
-extern crate arrayvec;
-extern crate drop_bomb;
-extern crate itertools;
-extern crate parking_lot;
-extern crate rowan;
-extern crate unicode_xid;
-
-#[cfg(test)]
-#[macro_use]
-extern crate test_utils;
-
 pub mod algo;
 pub mod ast;
 mod lexer;
@@ -48,11 +37,11 @@ pub mod utils;
 mod validation;
 mod yellow;
 
+pub use rowan::{SmolStr, TextRange, TextUnit};
 pub use crate::{
     ast::AstNode,
     lexer::{tokenize, Token},
     reparsing::AtomEdit,
-    rowan::{SmolStr, TextRange, TextUnit},
     syntax_kinds::SyntaxKind,
     yellow::{
         Direction, OwnedRoot, RefRoot, SyntaxError, SyntaxNode, SyntaxNodeRef, TreeRoot, WalkEvent, Location,
diff --git a/crates/ra_syntax/src/parser_api.rs b/crates/ra_syntax/src/parser_api.rs
index 42046d36fd..c37c30e349 100644
--- a/crates/ra_syntax/src/parser_api.rs
+++ b/crates/ra_syntax/src/parser_api.rs
@@ -1,5 +1,6 @@
+use drop_bomb::DropBomb;
+
 use crate::{
-    drop_bomb::DropBomb,
     parser_impl::ParserImpl,
     token_set::TokenSet,
     SyntaxKind::{self, ERROR},
diff --git a/crates/ra_syntax/src/reparsing.rs b/crates/ra_syntax/src/reparsing.rs
index ddcb8f6f6b..732fb0e4ae 100644
--- a/crates/ra_syntax/src/reparsing.rs
+++ b/crates/ra_syntax/src/reparsing.rs
@@ -179,10 +179,10 @@ fn merge_errors(
 
 #[cfg(test)]
 mod tests {
-    use super::{
-        super::{test_utils::extract_range, text_utils::replace_range, utils::dump_tree, SourceFileNode},
-        reparse_block, reparse_leaf, AtomEdit, GreenNode, SyntaxError, SyntaxNodeRef,
-};
+    use test_utils::{extract_range, assert_eq_text};
+
+    use crate::{SourceFileNode, text_utils::replace_range, utils::dump_tree };
+    use super::*;
 
     fn do_check<F>(before: &str, replace_with: &str, reparser: F)
     where
diff --git a/crates/tools/src/lib.rs b/crates/tools/src/lib.rs
index 4ff783c509..c2123db996 100644
--- a/crates/tools/src/lib.rs
+++ b/crates/tools/src/lib.rs
@@ -1,7 +1,3 @@
-extern crate failure;
-extern crate itertools;
-extern crate teraron;
-
 use std::{
     path::{Path, PathBuf},
     process::{Command, Stdio},
@@ -12,7 +8,7 @@ use itertools::Itertools;
 
 pub use teraron::{Mode, Overwrite, Verify};
 
-pub type Result<T> = ::std::result::Result<T, failure::Error>;
+pub type Result<T> = std::result::Result<T, failure::Error>;
 
 pub const GRAMMAR: &str = "crates/ra_syntax/src/grammar.ron";
 pub const SYNTAX_KINDS: &str = "crates/ra_syntax/src/syntax_kinds/generated.rs.tera";
diff --git a/crates/tools/src/main.rs b/crates/tools/src/main.rs
index dc623a4640..7bd4a2d09c 100644
--- a/crates/tools/src/main.rs
+++ b/crates/tools/src/main.rs
@@ -1,16 +1,12 @@
-extern crate clap;
-extern crate failure;
-extern crate teraron;
-extern crate tools;
-extern crate walkdir;
-
-use clap::{App, Arg, SubCommand};
-use failure::bail;
 use std::{
     collections::HashMap,
     fs,
     path::{Path, PathBuf},
 };
+
+use clap::{App, Arg, SubCommand};
+use failure::bail;
+
 use tools::{collect_tests, generate, run, run_rustfmt, Mode, Overwrite, Result, Test, Verify};
 
 const GRAMMAR_DIR: &str = "./crates/ra_syntax/src/grammar";


Test patch:
diff --git a/crates/ra_analysis/tests/tests.rs b/crates/ra_analysis/tests/tests.rs
index 71d20dbe94..4ce2c5c85d 100644
--- a/crates/ra_analysis/tests/tests.rs
+++ b/crates/ra_analysis/tests/tests.rs
@@ -1,10 +1,3 @@
-extern crate ra_analysis;
-extern crate ra_editor;
-extern crate ra_syntax;
-extern crate relative_path;
-extern crate rustc_hash;
-extern crate test_utils;
-
 use ra_syntax::TextRange;
 use test_utils::assert_eq_dbg;
 
diff --git a/crates/ra_editor/src/test_utils.rs b/crates/ra_editor/src/test_utils.rs
index cbeb6433b1..f0a4f250a7 100644
--- a/crates/ra_editor/src/test_utils.rs
+++ b/crates/ra_editor/src/test_utils.rs
@@ -1,7 +1,8 @@
-use crate::LocalEdit;
-pub use crate::_test_utils::*;
 use ra_syntax::{SourceFileNode, TextRange, TextUnit};
 
+use crate::LocalEdit;
+pub use test_utils::*;
+
 pub fn check_action<F: Fn(&SourceFileNode, TextUnit) -> Option<LocalEdit>>(
     before: &str,
     after: &str,
diff --git a/crates/ra_lsp_server/tests/heavy_tests/main.rs b/crates/ra_lsp_server/tests/heavy_tests/main.rs
index 0f6084555e..cbc0c88443 100644
--- a/crates/ra_lsp_server/tests/heavy_tests/main.rs
+++ b/crates/ra_lsp_server/tests/heavy_tests/main.rs
@@ -1,13 +1,3 @@
-#[macro_use]
-extern crate crossbeam_channel;
-extern crate flexi_logger;
-extern crate gen_lsp_server;
-extern crate languageserver_types;
-extern crate ra_lsp_server;
-extern crate serde;
-extern crate serde_json;
-extern crate tempdir;
-
 mod support;
 
 use ra_lsp_server::req::{Runnables, RunnablesParams};
diff --git a/crates/ra_lsp_server/tests/heavy_tests/support.rs b/crates/ra_lsp_server/tests/heavy_tests/support.rs
index 88d379bfaa..019048a3a8 100644
--- a/crates/ra_lsp_server/tests/heavy_tests/support.rs
+++ b/crates/ra_lsp_server/tests/heavy_tests/support.rs
@@ -6,7 +6,7 @@ use std::{
     time::Duration,
 };
 
-use crossbeam_channel::{after, Receiver};
+use crossbeam_channel::{after, select, Receiver};
 use flexi_logger::Logger;
 use gen_lsp_server::{RawMessage, RawNotification, RawRequest};
 use languageserver_types::{
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs
index d9fbb9b5b5..e72ec9c470 100644
--- a/crates/test_utils/src/lib.rs
+++ b/crates/test_utils/src/lib.rs
@@ -1,12 +1,9 @@
-extern crate difference;
-extern crate itertools;
-extern crate text_unit;
+use std::fmt;
 
 use itertools::Itertools;
-use std::fmt;
 use text_unit::{TextRange, TextUnit};
 
-pub use self::difference::Changeset as __Changeset;
+pub use difference::Changeset as __Changeset;
 
 pub const CURSOR_MARKER: &str = "<|>";