Repository: rust-analyzer/rust-analyzer
Pull request #3780 (2020-03-31 00:52:01)

Simplify
I absolutely love tha fact that removing `.clone()` simplifies the code comparing to other languages where it's actually the contrary (ahem ~~`std::move()`~~)


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index bdbb316cd9..a3887ce99c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -11,9 +11,9 @@ dependencies = [
 
 [[package]]
 name = "anyhow"
-version = "1.0.28"
+version = "1.0.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9a60d744a80c30fcb657dfe2c1b22bcb3e814c1a1e3674f32bf5820b570fbff"
+checksum = "013a6e0a2cbe3d20f9c60b65458f7a7f7a5e636c5d0f45a5a6aee5d4b1f01785"
 
 [[package]]
 name = "anymap"
@@ -435,9 +435,9 @@ dependencies = [
 
 [[package]]
 name = "hermit-abi"
-version = "0.1.10"
+version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "725cf19794cf90aa94e65050cb4191ff5d8fa87a498383774c47b332e3af952e"
+checksum = "1010591b26bbfe835e9faeabeb11866061cc7dcebffd56ad7d0942d0e61aefd8"
 dependencies = [
  "libc",
 ]
@@ -792,9 +792,9 @@ dependencies = [
 
 [[package]]
 name = "paste"
-version = "0.1.9"
+version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "092d791bf7847f70bbd49085489fba25fc2c193571752bff9e36e74e72403932"
+checksum = "8292c1e1e81ddb552c4c90c36af201a0ce7e34995f55f0480f01052f242811c9"
 dependencies = [
  "paste-impl",
  "proc-macro-hack",
@@ -802,9 +802,9 @@ dependencies = [
 
 [[package]]
 name = "paste-impl"
-version = "0.1.9"
+version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "406c23fb4c45cc6f68a9bbabb8ec7bd6f8cfcbd17e9e8f72c2460282f8325729"
+checksum = "5e9c43f2645f06ee452544ad032886a75f3d1797b9487dcadcae9100ba58a51c"
 dependencies = [
  "proc-macro-hack",
  "proc-macro2",
@@ -848,9 +848,9 @@ checksum = "fcfdefadc3d57ca21cf17990a28ef4c0f7c61383a28cb7604cf4a18e6ede1420"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.10"
+version = "1.0.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3"
+checksum = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435"
 dependencies = [
  "unicode-xid",
 ]
@@ -886,6 +886,19 @@ dependencies = [
  "test_utils",
 ]
 
+[[package]]
+name = "ra_cargo_watch"
+version = "0.1.0"
+dependencies = [
+ "cargo_metadata",
+ "crossbeam-channel",
+ "insta",
+ "jod-thread",
+ "log",
+ "lsp-types",
+ "serde_json",
+]
+
 [[package]]
 name = "ra_cfg"
 version = "0.1.0"
@@ -910,19 +923,6 @@ dependencies = [
  "test_utils",
 ]
 
-[[package]]
-name = "ra_flycheck"
-version = "0.1.0"
-dependencies = [
- "cargo_metadata",
- "crossbeam-channel",
- "insta",
- "jod-thread",
- "log",
- "lsp-types",
- "serde_json",
-]
-
 [[package]]
 name = "ra_fmt"
 version = "0.1.0"
@@ -1075,12 +1075,7 @@ dependencies = [
 name = "ra_proc_macro"
 version = "0.1.0"
 dependencies = [
- "crossbeam-channel",
- "jod-thread",
- "log",
  "ra_tt",
- "serde",
- "serde_json",
 ]
 
 [[package]]
@@ -1101,9 +1096,9 @@ dependencies = [
  "cargo_metadata",
  "log",
  "ra_arena",
+ "ra_cargo_watch",
  "ra_cfg",
  "ra_db",
- "ra_flycheck",
  "ra_proc_macro",
  "rustc-hash",
  "serde",
@@ -1300,8 +1295,8 @@ dependencies = [
  "lsp-types",
  "parking_lot",
  "pico-args",
+ "ra_cargo_watch",
  "ra_db",
- "ra_flycheck",
  "ra_hir",
  "ra_hir_def",
  "ra_hir_ty",
@@ -1431,9 +1426,9 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.50"
+version = "1.0.48"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78a7a12c167809363ec3bd7329fc0a3369056996de43c4b37ef3cd54a6ce4867"
+checksum = "9371ade75d4c2d6cb154141b9752cf3781ec9c05e0e5cf35060e1e70ee7b9c25"
 dependencies = [
  "itoa",
  "ryu",
@@ -1656,9 +1651,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
 
 [[package]]
 name = "winapi-util"
-version = "0.1.4"
+version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa515c5163a99cc82bab70fd3bfdd36d827be85de63737b40fcef2ce084a436e"
+checksum = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80"
 dependencies = [
  "winapi 0.3.8",
 ]
diff --git a/crates/ra_arena/src/map.rs b/crates/ra_arena/src/map.rs
index 0f33907c0a..5e764113d2 100644
--- a/crates/ra_arena/src/map.rs
+++ b/crates/ra_arena/src/map.rs
@@ -14,8 +14,14 @@ pub struct ArenaMap<ID, V> {
 impl<T, V> ArenaMap<Idx<T>, V> {
     pub fn insert(&mut self, id: Idx<T>, t: V) {
         let idx = Self::to_idx(id);
-
-        self.v.resize_with((idx + 1).max(self.v.len()), || None);
+        if self.v.capacity() <= idx {
+            self.v.reserve(idx + 1 - self.v.capacity());
+        }
+        if self.v.len() <= idx {
+            while self.v.len() <= idx {
+                self.v.push(None);
+            }
+        }
         self.v[idx] = Some(t);
     }
 
diff --git a/crates/ra_assists/src/handlers/fill_match_arms.rs b/crates/ra_assists/src/handlers/fill_match_arms.rs
index 8d1af99336..41bb97928d 100644
--- a/crates/ra_assists/src/handlers/fill_match_arms.rs
+++ b/crates/ra_assists/src/handlers/fill_match_arms.rs
@@ -1,11 +1,15 @@
+//! FIXME: write short doc here
+
 use std::iter;
 
 use hir::{Adt, HasSource, ModuleDef, Semantics};
 use itertools::Itertools;
 use ra_ide_db::RootDatabase;
-use ra_syntax::ast::{self, make, AstNode, MatchArm, NameOwner, Pat};
 
 use crate::{Assist, AssistCtx, AssistId};
+use ra_syntax::ast::{self, make, AstNode, NameOwner};
+
+use ast::{MatchArm, Pat};
 
 // Assist: fill_match_arms
 //
@@ -713,28 +717,4 @@ mod tests {
             "#,
         );
     }
-
-    #[test]
-    fn fill_match_arms_placeholder() {
-        check_assist(
-            fill_match_arms,
-            r#"
-            enum A { One, Two, }
-            fn foo(a: A) {
-                match a<|> {
-                    _ => (),
-                }
-            }
-            "#,
-            r#"
-            enum A { One, Two, }
-            fn foo(a: A) {
-                match <|>a {
-                    A::One => {}
-                    A::Two => {}
-                }
-            }
-            "#,
-        );
-    }
 }
diff --git a/crates/ra_flycheck/Cargo.toml b/crates/ra_cargo_watch/Cargo.toml
similarity index 92%
rename from crates/ra_flycheck/Cargo.toml
rename to crates/ra_cargo_watch/Cargo.toml
index c9a9ddc122..300033a183 100644
--- a/crates/ra_flycheck/Cargo.toml
+++ b/crates/ra_cargo_watch/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 edition = "2018"
-name = "ra_flycheck"
+name = "ra_cargo_watch"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
 
diff --git a/crates/ra_flycheck/src/conv/test.rs b/crates/ra_cargo_watch/src/conv/test.rs
similarity index 100%
rename from crates/ra_flycheck/src/conv/test.rs
rename to crates/ra_cargo_watch/src/conv/test.rs
diff --git a/crates/ra_flycheck/src/lib.rs b/crates/ra_cargo_watch/src/lib.rs
similarity index 96%
rename from crates/ra_flycheck/src/lib.rs
rename to crates/ra_cargo_watch/src/lib.rs
index 77ede8f635..2692c1bf55 100644
--- a/crates/ra_flycheck/src/lib.rs
+++ b/crates/ra_cargo_watch/src/lib.rs
@@ -22,7 +22,7 @@ use crate::conv::{map_rust_diagnostic_to_lsp, MappedRustDiagnostic};
 pub use crate::conv::url_from_path_with_drive_lowercasing;
 
 #[derive(Clone, Debug)]
-pub struct CheckConfig {
+pub struct CheckOptions {
     pub enable: bool,
     pub args: Vec<String>,
     pub command: String,
@@ -42,11 +42,13 @@ pub struct CheckWatcher {
 }
 
 impl CheckWatcher {
-    pub fn new(config: CheckConfig, workspace_root: PathBuf) -> CheckWatcher {
+    pub fn new(options: &CheckOptions, workspace_root: PathBuf) -> CheckWatcher {
+        let options = options.clone();
+
         let (task_send, task_recv) = unbounded::<CheckTask>();
         let (cmd_send, cmd_recv) = unbounded::<CheckCommand>();
         let handle = jod_thread::spawn(move || {
-            let mut check = CheckWatcherThread::new(config, workspace_root);
+            let mut check = CheckWatcherThread::new(options, workspace_root);
             check.run(&task_send, &cmd_recv);
         });
         CheckWatcher { task_recv, cmd_send, handle: Some(handle) }
@@ -76,14 +78,14 @@ pub enum CheckCommand {
 }
 
 struct CheckWatcherThread {
-    options: CheckConfig,
+    options: CheckOptions,
     workspace_root: PathBuf,
     watcher: WatchThread,
     last_update_req: Option<Instant>,
 }
 
 impl CheckWatcherThread {
-    fn new(options: CheckConfig, workspace_root: PathBuf) -> CheckWatcherThread {
+    fn new(options: CheckOptions, workspace_root: PathBuf) -> CheckWatcherThread {
         CheckWatcherThread {
             options,
             workspace_root,
@@ -322,7 +324,7 @@ impl WatchThread {
         WatchThread { message_recv: never(), _handle: None }
     }
 
-    fn new(options: &CheckConfig, workspace_root: &Path) -> WatchThread {
+    fn new(options: &CheckOptions, workspace_root: &Path) -> WatchThread {
         let mut args: Vec<String> = vec![
             options.command.clone(),
             "--workspace".to_string(),
diff --git a/crates/ra_hir_expand/src/proc_macro.rs b/crates/ra_hir_expand/src/proc_macro.rs
index 97d1208ec6..4d270e0def 100644
--- a/crates/ra_hir_expand/src/proc_macro.rs
+++ b/crates/ra_hir_expand/src/proc_macro.rs
@@ -9,15 +9,6 @@ pub struct ProcMacroExpander {
     proc_macro_id: ProcMacroId,
 }
 
-macro_rules! err {
-    ($fmt:literal, $($tt:tt),*) => {
-        mbe::ExpandError::ProcMacroError(tt::ExpansionError::Unknown(format!($fmt, $($tt),*)))
-    };
-    ($fmt:literal) => {
-        mbe::ExpandError::ProcMacroError(tt::ExpansionError::Unknown($fmt.to_string()))
-    }
-}
-
 impl ProcMacroExpander {
     pub fn new(krate: CrateId, proc_macro_id: ProcMacroId) -> ProcMacroExpander {
         ProcMacroExpander { krate, proc_macro_id }
@@ -34,24 +25,8 @@ impl ProcMacroExpander {
             .proc_macro
             .get(self.proc_macro_id.0 as usize)
             .clone()
-            .ok_or_else(|| err!("No derive macro found."))?;
-
-        let tt = remove_derive_atr(tt, &proc_macro.name)
-            .ok_or_else(|| err!("Fail to remove derive for custom derive"))?;
+            .ok_or_else(|| mbe::ExpandError::ConversionError)?;
 
         proc_macro.expander.expand(&tt, None).map_err(mbe::ExpandError::from)
     }
 }
-
-fn remove_derive_atr(tt: &tt::Subtree, _name: &str) -> Option<tt::Subtree> {
-    // FIXME: proper handle the remove derive
-    // We assume the first 2 tokens are #[derive(name)]
-    if tt.token_trees.len() > 2 {
-        let mut tt = tt.clone();
-        tt.token_trees.remove(0);
-        tt.token_trees.remove(0);
-        return Some(tt);
-    }
-
-    None
-}
diff --git a/crates/ra_hir_ty/src/display.rs b/crates/ra_hir_ty/src/display.rs
index c3d92a268f..13ecd537ad 100644
--- a/crates/ra_hir_ty/src/display.rs
+++ b/crates/ra_hir_ty/src/display.rs
@@ -190,8 +190,6 @@ impl HirDisplay for ApplicationTy {
                 };
                 write!(f, "{}", name)?;
                 if self.parameters.len() > 0 {
-                    write!(f, "<")?;
-
                     let mut non_default_parameters = Vec::with_capacity(self.parameters.len());
                     let parameters_to_write = if f.omit_verbose_types() {
                         match self
@@ -200,8 +198,8 @@ impl HirDisplay for ApplicationTy {
                             .map(|generic_def_id| f.db.generic_defaults(generic_def_id))
                             .filter(|defaults| !defaults.is_empty())
                         {
-                            Option::None => self.parameters.0.as_ref(),
-                            Option::Some(default_parameters) => {
+                            None => self.parameters.0.as_ref(),
+                            Some(default_parameters) => {
                                 for (i, parameter) in self.parameters.iter().enumerate() {
                                     match (parameter, default_parameters.get(i)) {
                                         (&Ty::Unknown, _) | (_, None) => {
@@ -221,7 +219,7 @@ impl HirDisplay for ApplicationTy {
                     } else {
                         self.parameters.0.as_ref()
                     };
-
+                    write!(f, "<")?;
                     f.write_joined(parameters_to_write, ", ")?;
                     write!(f, ">")?;
                 }
@@ -231,9 +229,9 @@ impl HirDisplay for ApplicationTy {
                     AssocContainerId::TraitId(it) => it,
                     _ => panic!("not an associated type"),
                 };
-                let trait_name = f.db.trait_data(trait_).name.clone();
-                let name = f.db.type_alias_data(type_alias).name.clone();
-                write!(f, "{}::{}", trait_name, name)?;
+                let trait_ = f.db.trait_data(trait_);
+                let type_alias = f.db.type_alias_data(type_alias);
+                write!(f, "{}::{}", trait_.name, type_alias.name)?;
                 if self.parameters.len() > 0 {
                     write!(f, "<")?;
                     f.write_joined(&*self.parameters.0, ", ")?;
@@ -266,8 +264,8 @@ impl HirDisplay for ProjectionTy {
             return write!(f, "{}", TYPE_HINT_TRUNCATION);
         }
 
-        let trait_name = f.db.trait_data(self.trait_(f.db)).name.clone();
-        write!(f, "<{} as {}", self.parameters[0].display(f.db), trait_name,)?;
+        let trait_ = f.db.trait_data(self.trait_(f.db));
+        write!(f, "<{} as {}", self.parameters[0].display(f.db), trait_.name)?;
         if self.parameters.len() > 1 {
             write!(f, "<")?;
             f.write_joined(&self.parameters[1..], ", ")?;
@@ -312,7 +310,7 @@ impl HirDisplay for Ty {
                     Ty::Opaque(_) => write!(f, "impl ")?,
                     _ => unreachable!(),
                 };
-                write_bounds_like_dyn_trait(&predicates, f)?;
+                write_bounds_like_dyn_trait(predicates, f)?;
             }
             Ty::Unknown => write!(f, "{{unknown}}")?,
             Ty::Infer(..) => write!(f, "_")?,
@@ -345,7 +343,7 @@ fn write_bounds_like_dyn_trait(
                 // We assume that the self type is $0 (i.e. the
                 // existential) here, which is the only thing that's
                 // possible in actual Rust, and hence don't print it
-                write!(f, "{}", f.db.trait_data(trait_ref.trait_).name.clone())?;
+                write!(f, "{}", f.db.trait_data(trait_ref.trait_).name)?;
                 if trait_ref.substs.len() > 1 {
                     write!(f, "<")?;
                     f.write_joined(&trait_ref.substs[1..], ", ")?;
@@ -362,9 +360,8 @@ fn write_bounds_like_dyn_trait(
                     write!(f, "<")?;
                     angle_open = true;
                 }
-                let name =
-                    f.db.type_alias_data(projection_pred.projection_ty.associated_ty).name.clone();
-                write!(f, "{} = ", name)?;
+                let type_alias = f.db.type_alias_data(projection_pred.projection_ty.associated_ty);
+                write!(f, "{} = ", type_alias.name)?;
                 projection_pred.ty.hir_fmt(f)?;
             }
             GenericPredicate::Error => {
@@ -398,7 +395,7 @@ impl TraitRef {
         } else {
             write!(f, ": ")?;
         }
-        write!(f, "{}", f.db.trait_data(self.trait_).name.clone())?;
+        write!(f, "{}", f.db.trait_data(self.trait_).name)?;
         if self.substs.len() > 1 {
             write!(f, "<")?;
             f.write_joined(&self.substs[1..], ", ")?;
diff --git a/crates/ra_ide/src/completion.rs b/crates/ra_ide/src/completion.rs
index b683572fbf..cd0757be5f 100644
--- a/crates/ra_ide/src/completion.rs
+++ b/crates/ra_ide/src/completion.rs
@@ -34,15 +34,15 @@ pub use crate::completion::completion_item::{
 };
 
 #[derive(Clone, Debug, PartialEq, Eq)]
-pub struct CompletionConfig {
+pub struct CompletionOptions {
     pub enable_postfix_completions: bool,
     pub add_call_parenthesis: bool,
     pub add_call_argument_snippets: bool,
 }
 
-impl Default for CompletionConfig {
+impl Default for CompletionOptions {
     fn default() -> Self {
-        CompletionConfig {
+        CompletionOptions {
             enable_postfix_completions: true,
             add_call_parenthesis: true,
             add_call_argument_snippets: true,
@@ -75,9 +75,9 @@ impl Default for CompletionConfig {
 pub(crate) fn completions(
     db: &RootDatabase,
     position: FilePosition,
-    config: &CompletionConfig,
+    options: &CompletionOptions,
 ) -> Option<Completions> {
-    let ctx = CompletionContext::new(db, position, config)?;
+    let ctx = CompletionContext::new(db, position, options)?;
 
     let mut acc = Completions::default();
 
diff --git a/crates/ra_ide/src/completion/complete_postfix.rs b/crates/ra_ide/src/completion/complete_postfix.rs
index 29c2881c62..0a00054b23 100644
--- a/crates/ra_ide/src/completion/complete_postfix.rs
+++ b/crates/ra_ide/src/completion/complete_postfix.rs
@@ -15,7 +15,7 @@ use crate::{
 };
 
 pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
-    if !ctx.config.enable_postfix_completions {
+    if !ctx.options.enable_postfix_completions {
         return;
     }
 
diff --git a/crates/ra_ide/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs
index fdc0da2c5e..319e33b615 100644
--- a/crates/ra_ide/src/completion/completion_context.rs
+++ b/crates/ra_ide/src/completion/completion_context.rs
@@ -11,7 +11,7 @@ use ra_syntax::{
 };
 use ra_text_edit::AtomTextEdit;
 
-use crate::{completion::CompletionConfig, FilePosition};
+use crate::{completion::CompletionOptions, FilePosition};
 
 /// `CompletionContext` is created early during completion to figure out, where
 /// exactly is the cursor, syntax-wise.
@@ -19,7 +19,7 @@ use crate::{completion::CompletionConfig, FilePosition};
 pub(crate) struct CompletionContext<'a> {
     pub(super) sema: Semantics<'a, RootDatabase>,
     pub(super) db: &'a RootDatabase,
-    pub(super) config: &'a CompletionConfig,
+    pub(super) options: &'a CompletionOptions,
     pub(super) offset: TextUnit,
     /// The token before the cursor, in the original file.
     pub(super) original_token: SyntaxToken,
@@ -61,7 +61,7 @@ impl<'a> CompletionContext<'a> {
     pub(super) fn new(
         db: &'a RootDatabase,
         position: FilePosition,
-        config: &'a CompletionConfig,
+        options: &'a CompletionOptions,
     ) -> Option<CompletionContext<'a>> {
         let sema = Semantics::new(db);
 
@@ -85,7 +85,7 @@ impl<'a> CompletionContext<'a> {
         let mut ctx = CompletionContext {
             sema,
             db,
-            config,
+            options,
             original_token,
             token,
             offset: position.offset,
diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs
index 1c7c0924db..60f1b83f33 100644
--- a/crates/ra_ide/src/completion/presentation.rs
+++ b/crates/ra_ide/src/completion/presentation.rs
@@ -106,7 +106,7 @@ impl Completions {
         };
 
         // Add `<>` for generic types
-        if ctx.is_path_type && !ctx.has_type_args && ctx.config.add_call_parenthesis {
+        if ctx.is_path_type && !ctx.has_type_args && ctx.options.add_call_parenthesis {
             let has_non_default_type_params = match resolution {
                 ScopeDef::ModuleDef(Adt(it)) => it.has_non_default_type_params(ctx.db),
                 ScopeDef::ModuleDef(TypeAlias(it)) => it.has_non_default_type_params(ctx.db),
@@ -211,14 +211,14 @@ impl Completions {
                 .detail(function_signature.to_string());
 
         // If not an import, add parenthesis automatically.
-        if ctx.use_item_syntax.is_none() && !ctx.is_call && ctx.config.add_call_parenthesis {
+        if ctx.use_item_syntax.is_none() && !ctx.is_call && ctx.options.add_call_parenthesis {
             tested_by!(inserts_parens_for_function_calls);
 
             let (snippet, label) = if params.is_empty() || has_self_param && params.len() == 1 {
                 (format!("{}()$0", name), format!("{}()", name))
             } else {
                 builder = builder.trigger_call_info();
-                let snippet = if ctx.config.add_call_argument_snippets {
+                let snippet = if ctx.options.add_call_argument_snippets {
                     let to_skip = if has_self_param { 1 } else { 0 };
                     let function_params_snippet = function_signature
                         .parameter_names
@@ -311,7 +311,7 @@ mod tests {
 
     use crate::completion::{
         test_utils::{do_completion, do_completion_with_options},
-        CompletionConfig, CompletionItem, CompletionKind,
+        CompletionItem, CompletionKind, CompletionOptions,
     };
 
     fn do_reference_completion(ra_fixture: &str) -> Vec<CompletionItem> {
@@ -320,7 +320,7 @@ mod tests {
 
     fn do_reference_completion_with_options(
         ra_fixture: &str,
-        options: CompletionConfig,
+        options: CompletionOptions,
     ) -> Vec<CompletionItem> {
         do_completion_with_options(ra_fixture, CompletionKind::Reference, &options)
     }
@@ -589,7 +589,7 @@ mod tests {
                     s.f<|>
                 }
                 ",
-                CompletionConfig {
+                CompletionOptions {
                     add_call_argument_snippets: false,
                     .. Default::default()
                 }
diff --git a/crates/ra_ide/src/inlay_hints.rs b/crates/ra_ide/src/inlay_hints.rs
index d06fc03d3e..f4f0751c05 100644
--- a/crates/ra_ide/src/inlay_hints.rs
+++ b/crates/ra_ide/src/inlay_hints.rs
@@ -11,14 +11,14 @@ use ra_syntax::{
 use crate::{FileId, FunctionSignature};
 
 #[derive(Clone, Debug, PartialEq, Eq)]
-pub struct InlayHintsConfig {
+pub struct InlayHintsOptions {
     pub type_hints: bool,
     pub parameter_hints: bool,
     pub chaining_hints: bool,
     pub max_length: Option<usize>,
 }
 
-impl Default for InlayHintsConfig {
+impl Default for InlayHintsOptions {
     fn default() -> Self {
         Self { type_hints: true, parameter_hints: true, chaining_hints: true, max_length: None }
     }
@@ -41,7 +41,7 @@ pub struct InlayHint {
 pub(crate) fn inlay_hints(
     db: &RootDatabase,
     file_id: FileId,
-    config: &InlayHintsConfig,
+    options: &InlayHintsOptions,
 ) -> Vec<InlayHint> {
     let _p = profile("inlay_hints");
     let sema = Semantics::new(db);
@@ -50,14 +50,14 @@ pub(crate) fn inlay_hints(
     let mut res = Vec::new();
     for node in file.syntax().descendants() {
         if let Some(expr) = ast::Expr::cast(node.clone()) {
-            get_chaining_hints(&mut res, &sema, config, expr);
+            get_chaining_hints(&mut res, &sema, options, expr);
         }
 
         match_ast! {
             match node {
-                ast::CallExpr(it) => { get_param_name_hints(&mut res, &sema, config, ast::Expr::from(it)); },
-                ast::MethodCallExpr(it) => { get_param_name_hints(&mut res, &sema, config, ast::Expr::from(it)); },
-                ast::BindPat(it) => { get_bind_pat_hints(&mut res, &sema, config, it); },
+                ast::CallExpr(it) => { get_param_name_hints(&mut res, &sema, options, ast::Expr::from(it)); },
+                ast::MethodCallExpr(it) => { get_param_name_hints(&mut res, &sema, options, ast::Expr::from(it)); },
+                ast::BindPat(it) => { get_bind_pat_hints(&mut res, &sema, options, it); },
                 _ => (),
             }
         }
@@ -68,10 +68,10 @@ pub(crate) fn inlay_hints(
 fn get_chaining_hints(
     acc: &mut Vec<InlayHint>,
     sema: &Semantics<RootDatabase>,
-    config: &InlayHintsConfig,
+    options: &InlayHintsOptions,
     expr: ast::Expr,
 ) -> Option<()> {
-    if !config.chaining_hints {
+    if !options.chaining_hints {
         return None;
     }
 
@@ -95,7 +95,7 @@ fn get_chaining_hints(
     let next = tokens.next()?.kind();
     let next_next = tokens.next()?.kind();
     if next == SyntaxKind::WHITESPACE && next_next == SyntaxKind::DOT {
-        let label = ty.display_truncated(sema.db, config.max_length).to_string();
+        let label = ty.display_truncated(sema.db, options.max_length).to_string();
         acc.push(InlayHint {
             range: expr.syntax().text_range(),
             kind: InlayKind::ChainingHint,
@@ -108,10 +108,10 @@ fn get_chaining_hints(
 fn get_param_name_hints(
     acc: &mut Vec<InlayHint>,
     sema: &Semantics<RootDatabase>,
-    config: &InlayHintsConfig,
+    options: &InlayHintsOptions,
     expr: ast::Expr,
 ) -> Option<()> {
-    if !config.parameter_hints {
+    if !options.parameter_hints {
         return None;
     }
 
@@ -148,10 +148,10 @@ fn get_param_name_hints(
 fn get_bind_pat_hints(
     acc: &mut Vec<InlayHint>,
     sema: &Semantics<RootDatabase>,
-    config: &InlayHintsConfig,
+    options: &InlayHintsOptions,
     pat: ast::BindPat,
 ) -> Option<()> {
-    if !config.type_hints {
+    if !options.type_hints {
         return None;
     }
 
@@ -164,7 +164,7 @@ fn get_bind_pat_hints(
     acc.push(InlayHint {
         range: pat.syntax().text_range(),
         kind: InlayKind::TypeHint,
-        label: ty.display_truncated(sema.db, config.max_length).to_string().into(),
+        label: ty.display_truncated(sema.db, options.max_length).to_string().into(),
     });
     Some(())
 }
@@ -270,7 +270,7 @@ fn get_fn_signature(sema: &Semantics<RootDatabase>, expr: &ast::Expr) -> Option<
 
 #[cfg(test)]
 mod tests {
-    use crate::inlay_hints::InlayHintsConfig;
+    use crate::inlay_hints::InlayHintsOptions;
     use insta::assert_debug_snapshot;
 
     use crate::mock_analysis::single_file;
@@ -284,7 +284,7 @@ mod tests {
                 let _x = foo(4, 4);
             }"#,
         );
-        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig{ parameter_hints: true, type_hints: false, chaining_hints: false, max_length: None}).unwrap(), @r###"
+        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions{ parameter_hints: true, type_hints: false, chaining_hints: false, max_length: None}).unwrap(), @r###"
         [
             InlayHint {
                 range: [106; 107),
@@ -308,7 +308,7 @@ mod tests {
                 let _x = foo(4, 4);
             }"#,
         );
-        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig{ type_hints: false, parameter_hints: false, chaining_hints: false, max_length: None}).unwrap(), @r###"[]"###);
+        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions{ type_hints: false, parameter_hints: false, chaining_hints: false, max_length: None}).unwrap(), @r###"[]"###);
     }
 
     #[test]
@@ -320,7 +320,7 @@ mod tests {
                 let _x = foo(4, 4);
             }"#,
         );
-        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig{ type_hints: true, parameter_hints: false, chaining_hints: false, max_length: None}).unwrap(), @r###"
+        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions{ type_hints: true, parameter_hints: false, chaining_hints: false, max_length: None}).unwrap(), @r###"
         [
             InlayHint {
                 range: [97; 99),
@@ -344,7 +344,7 @@ fn main() {
 }"#,
         );
 
-        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###"
+        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions::default()).unwrap(), @r###"
         [
             InlayHint {
                 range: [69; 71),
@@ -401,7 +401,7 @@ fn main() {
 }"#,
         );
 
-        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###"
+        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions::default()).unwrap(), @r###"
         [
             InlayHint {
                 range: [193; 197),
@@ -481,7 +481,7 @@ fn main() {
 }"#,
         );
 
-        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###"
+        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions::default()).unwrap(), @r###"
         [
             InlayHint {
                 range: [21; 30),
@@ -545,7 +545,7 @@ fn main() {
 }"#,
         );
 
-        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###"
+        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions::default()).unwrap(), @r###"
         [
             InlayHint {
                 range: [21; 30),
@@ -595,7 +595,7 @@ fn main() {
 }"#,
         );
 
-        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###"
+        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions::default()).unwrap(), @r###"
         [
             InlayHint {
                 range: [188; 192),
@@ -690,7 +690,7 @@ fn main() {
 }"#,
         );
 
-        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###"
+        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions::default()).unwrap(), @r###"
         [
             InlayHint {
                 range: [188; 192),
@@ -785,7 +785,7 @@ fn main() {
 }"#,
         );
 
-        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###"
+        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions::default()).unwrap(), @r###"
         [
             InlayHint {
                 range: [252; 256),
@@ -857,7 +857,7 @@ fn main() {
 }"#,
         );
 
-        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig { max_length: Some(8), ..Default::default() }).unwrap(), @r###"
+        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions { max_length: Some(8), ..Default::default() }).unwrap(), @r###"
         [
             InlayHint {
                 range: [74; 75),
@@ -945,7 +945,7 @@ fn main() {
 }"#,
         );
 
-        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig::default()).unwrap(), @r###"
+        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions::default()).unwrap(), @r###"
         [
             InlayHint {
                 range: [798; 809),
@@ -1067,7 +1067,7 @@ fn main() {
 }"#,
         );
 
-        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig { max_length: Some(8), ..Default::default() }).unwrap(), @r###"
+        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions { max_length: Some(8), ..Default::default() }).unwrap(), @r###"
         []
         "###
         );
@@ -1093,7 +1093,7 @@ fn main() {
 }"#,
         );
 
-        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig { max_length: Some(8), ..Default::default() }).unwrap(), @r###"
+        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions { max_length: Some(8), ..Default::default() }).unwrap(), @r###"
         []
         "###
         );
@@ -1115,7 +1115,7 @@ fn main() {
                     .into_c();
             }"#,
         );
-        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig{ parameter_hints: false, type_hints: false, chaining_hints: true, max_length: None}).unwrap(), @r###"
+        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions{ parameter_hints: false, type_hints: false, chaining_hints: true, max_length: None}).unwrap(), @r###"
         [
             InlayHint {
                 range: [232; 269),
@@ -1144,7 +1144,7 @@ fn main() {
                 let c = A(B(C)).into_b().into_c();
             }"#,
         );
-        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig{ parameter_hints: false, type_hints: false, chaining_hints: true, max_length: None}).unwrap(), @r###"[]"###);
+        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions{ parameter_hints: false, type_hints: false, chaining_hints: true, max_length: None}).unwrap(), @r###"[]"###);
     }
 
     #[test]
@@ -1162,7 +1162,7 @@ fn main() {
                     .0;
             }"#,
         );
-        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig{ parameter_hints: false, type_hints: false, chaining_hints: true, max_length: None}).unwrap(), @r###"
+        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions{ parameter_hints: false, type_hints: false, chaining_hints: true, max_length: None}).unwrap(), @r###"
         [
             InlayHint {
                 range: [150; 221),
@@ -1204,7 +1204,7 @@ fn main() {
                     .into_c();
             }"#,
         );
-        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsConfig{ parameter_hints: false, type_hints: false, chaining_hints: true, max_length: None}).unwrap(), @r###"
+        assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions{ parameter_hints: false, type_hints: false, chaining_hints: true, max_length: None}).unwrap(), @r###"
         [
             InlayHint {
                 range: [403; 452),
diff --git a/crates/ra_ide/src/lib.rs b/crates/ra_ide/src/lib.rs
index 2853810865..937c9caa51 100644
--- a/crates/ra_ide/src/lib.rs
+++ b/crates/ra_ide/src/lib.rs
@@ -62,13 +62,13 @@ use crate::display::ToNav;
 pub use crate::{
     assists::{Assist, AssistId},
     call_hierarchy::CallItem,
-    completion::{CompletionConfig, CompletionItem, CompletionItemKind, InsertTextFormat},
+    completion::{CompletionItem, CompletionItemKind, CompletionOptions, InsertTextFormat},
     diagnostics::Severity,
     display::{file_structure, FunctionSignature, NavigationTarget, StructureNode},
     expand_macro::ExpandedMacro,
     folding_ranges::{Fold, FoldKind},
     hover::HoverResult,
-    inlay_hints::{InlayHint, InlayHintsConfig, InlayKind},
+    inlay_hints::{InlayHint, InlayHintsOptions, InlayKind},
     references::{Declaration, Reference, ReferenceAccess, ReferenceKind, ReferenceSearchResult},
     runnables::{Runnable, RunnableKind, TestId},
     source_change::{FileSystemEdit, SourceChange, SourceFileEdit},
@@ -325,9 +325,9 @@ impl Analysis {
     pub fn inlay_hints(
         &self,
         file_id: FileId,
-        config: &InlayHintsConfig,
+        inlay_hint_opts: &InlayHintsOptions,
     ) -> Cancelable<Vec<InlayHint>> {
-        self.with_db(|db| inlay_hints::inlay_hints(db, file_id, config))
+        self.with_db(|db| inlay_hints::inlay_hints(db, file_id, inlay_hint_opts))
     }
 
     /// Returns the set of folding ranges.
@@ -450,9 +450,9 @@ impl Analysis {
     pub fn completions(
         &self,
         position: FilePosition,
-        config: &CompletionConfig,
+        options: &CompletionOptions,
     ) -> Cancelable<Option<Vec<CompletionItem>>> {
-        self.with_db(|db| completion::completions(db, position, config).map(Into::into))
+        self.with_db(|db| completion::completions(db, position, options).map(Into::into))
     }
 
     /// Computes assists (aka code actions aka intentions) for the given
diff --git a/crates/ra_proc_macro/Cargo.toml b/crates/ra_proc_macro/Cargo.toml
index d009ceb82e..bc2c37296d 100644
--- a/crates/ra_proc_macro/Cargo.toml
+++ b/crates/ra_proc_macro/Cargo.toml
@@ -10,8 +10,3 @@ doctest = false
 
 [dependencies]
 ra_tt = { path = "../ra_tt" }
-serde = { version = "1.0", features = ["derive"] }
-serde_json = "1.0"
-log = "0.4.8"
-crossbeam-channel = "0.4.0"
-jod-thread = "0.1.1"
diff --git a/crates/ra_proc_macro/src/lib.rs b/crates/ra_proc_macro/src/lib.rs
index 51fbb046a9..5e21dd4872 100644
--- a/crates/ra_proc_macro/src/lib.rs
+++ b/crates/ra_proc_macro/src/lib.rs
@@ -5,104 +5,55 @@
 //! is used to provide basic infrastructure  for communication between two
 //! processes: Client (RA itself), Server (the external program)
 
-mod rpc;
-mod process;
-pub mod msg;
-
-use process::{ProcMacroProcessSrv, ProcMacroProcessThread};
 use ra_tt::{SmolStr, Subtree};
-use rpc::ProcMacroKind;
 use std::{
     path::{Path, PathBuf},
     sync::Arc,
 };
 
-pub use rpc::{ExpansionResult, ExpansionTask};
-
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, PartialEq, Eq)]
 pub struct ProcMacroProcessExpander {
     process: Arc<ProcMacroProcessSrv>,
-    dylib_path: PathBuf,
     name: SmolStr,
 }
 
-impl Eq for ProcMacroProcessExpander {}
-impl PartialEq for ProcMacroProcessExpander {
-    fn eq(&self, other: &Self) -> bool {
-        self.name == other.name
-            && self.dylib_path == other.dylib_path
-            && Arc::ptr_eq(&self.process, &other.process)
-    }
-}
-
 impl ra_tt::TokenExpander for ProcMacroProcessExpander {
     fn expand(
         &self,
-        subtree: &Subtree,
+        _subtree: &Subtree,
         _attr: Option<&Subtree>,
     ) -> Result<Subtree, ra_tt::ExpansionError> {
-        self.process.custom_derive(&self.dylib_path, subtree, &self.name)
+        // FIXME: do nothing for now
+        Ok(Subtree::default())
     }
 }
 
-#[derive(Debug)]
-enum ProcMacroClientKind {
-    Process { process: Arc<ProcMacroProcessSrv>, thread: ProcMacroProcessThread },
-    Dummy,
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct ProcMacroProcessSrv {
+    path: PathBuf,
 }
 
-#[derive(Debug)]
-pub struct ProcMacroClient {
-    kind: ProcMacroClientKind,
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub enum ProcMacroClient {
+    Process { process: Arc<ProcMacroProcessSrv> },
+    Dummy,
 }
 
 impl ProcMacroClient {
-    pub fn extern_process(process_path: &Path) -> Result<ProcMacroClient, std::io::Error> {
-        let (thread, process) = ProcMacroProcessSrv::run(process_path)?;
-        Ok(ProcMacroClient {
-            kind: ProcMacroClientKind::Process { process: Arc::new(process), thread },
-        })
+    pub fn extern_process(process_path: &Path) -> ProcMacroClient {
+        let process = ProcMacroProcessSrv { path: process_path.into() };
+        ProcMacroClient::Process { process: Arc::new(process) }
     }
 
     pub fn dummy() -> ProcMacroClient {
-        ProcMacroClient { kind: ProcMacroClientKind::Dummy }
+        ProcMacroClient::Dummy
     }
 
     pub fn by_dylib_path(
         &self,
-        dylib_path: &Path,
+        _dylib_path: &Path,
     ) -> Vec<(SmolStr, Arc<dyn ra_tt::TokenExpander>)> {
-        match &self.kind {
-            ProcMacroClientKind::Dummy => vec![],
-            ProcMacroClientKind::Process { process, .. } => {
-                let macros = match process.find_proc_macros(dylib_path) {
-                    Err(err) => {
-                        eprintln!("Fail to find proc macro. Error: {:#?}", err);
-                        return vec![];
-                    }
-                    Ok(macros) => macros,
-                };
-
-                macros
-                    .into_iter()
-                    .filter_map(|(name, kind)| {
-                        // FIXME: Support custom derive only for now.
-                        match kind {
-                            ProcMacroKind::CustomDerive => {
-                                let name = SmolStr::new(&name);
-                                let expander: Arc<dyn ra_tt::TokenExpander> =
-                                    Arc::new(ProcMacroProcessExpander {
-                                        process: process.clone(),
-                                        name: name.clone(),
-                                        dylib_path: dylib_path.into(),
-                                    });
-                                Some((name, expander))
-                            }
-                            _ => None,
-                        }
-                    })
-                    .collect()
-            }
-        }
+        // FIXME: return empty for now
+        vec![]
     }
 }
diff --git a/crates/ra_proc_macro/src/msg.rs b/crates/ra_proc_macro/src/msg.rs
deleted file mode 100644
index aa95bcc8f7..0000000000
--- a/crates/ra_proc_macro/src/msg.rs
+++ /dev/null
@@ -1,93 +0,0 @@
-//! Defines messages for cross-process message based on `ndjson` wire protocol
-
-use std::{
-    convert::TryFrom,
-    io::{self, BufRead, Write},
-};
-
-use crate::{
-    rpc::{ListMacrosResult, ListMacrosTask},
-    ExpansionResult, ExpansionTask,
-};
-use serde::{de::DeserializeOwned, Deserialize, Serialize};
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub enum Request {
-    ListMacro(ListMacrosTask),
-    ExpansionMacro(ExpansionTask),
-}
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub enum Response {
-    Error(ResponseError),
-    ListMacro(ListMacrosResult),
-    ExpansionMacro(ExpansionResult),
-}
-
-macro_rules! impl_try_from_response {
-    ($ty:ty, $tag:ident) => {
-        impl TryFrom<Response> for $ty {
-            type Error = &'static str;
-            fn try_from(value: Response) -> Result<Self, Self::Error> {
-                match value {
-                    Response::$tag(res) => Ok(res),
-                    _ => Err("Fail to convert from response"),
-                }
-            }
-        }
-    };
-}
-
-impl_try_from_response!(ListMacrosResult, ListMacro);
-impl_try_from_response!(ExpansionResult, ExpansionMacro);
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct ResponseError {
-    pub code: ErrorCode,
-    pub message: String,
-}
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub enum ErrorCode {
-    ServerErrorEnd,
-    ExpansionError,
-}
-
-pub trait Message: Sized + Serialize + DeserializeOwned {
-    fn read(r: &mut impl BufRead) -> io::Result<Option<Self>> {
-        let text = match read_json(r)? {
-            None => return Ok(None),
-            Some(text) => text,
-        };
-        let msg = serde_json::from_str(&text)?;
-        Ok(Some(msg))
-    }
-    fn write(self, w: &mut impl Write) -> io::Result<()> {
-        let text = serde_json::to_string(&self)?;
-        write_json(w, &text)
-    }
-}
-
-impl Message for Request {}
-impl Message for Response {}
-
-fn read_json(inp: &mut impl BufRead) -> io::Result<Option<String>> {
-    let mut buf = String::new();
-    if inp.read_line(&mut buf)? == 0 {
-        return Ok(None);
-    }
-    // Remove ending '\n'
-    let buf = &buf[..buf.len() - 1];
-    if buf.is_empty() {
-        return Ok(None);
-    }
-    Ok(Some(buf.to_string()))
-}
-
-fn write_json(out: &mut impl Write, msg: &str) -> io::Result<()> {
-    log::debug!("> {}", msg);
-    out.write_all(msg.as_bytes())?;
-    out.write_all(b"\n")?;
-    out.flush()?;
-    Ok(())
-}
diff --git a/crates/ra_proc_macro/src/process.rs b/crates/ra_proc_macro/src/process.rs
deleted file mode 100644
index e8c85be38a..0000000000
--- a/crates/ra_proc_macro/src/process.rs
+++ /dev/null
@@ -1,196 +0,0 @@
-//! Handle process life-time and message passing for proc-macro client
-
-use crossbeam_channel::{bounded, Receiver, Sender};
-use ra_tt::Subtree;
-
-use crate::msg::{ErrorCode, Message, Request, Response, ResponseError};
-use crate::rpc::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask, ProcMacroKind};
-
-use io::{BufRead, BufReader};
-use std::{
-    convert::{TryFrom, TryInto},
-    io::{self, Write},
-    path::{Path, PathBuf},
-    process::{Child, Command, Stdio},
-    sync::{Arc, Weak},
-};
-
-#[derive(Debug, Default)]
-pub(crate) struct ProcMacroProcessSrv {
-    inner: Option<Weak<Sender<Task>>>,
-}
-
-#[derive(Debug)]
-pub(crate) struct ProcMacroProcessThread {
-    // XXX: drop order is significant
-    sender: Arc<Sender<Task>>,
-    handle: jod_thread::JoinHandle<()>,
-}
-
-struct Task {
-    req: Request,
-    result_tx: Sender<Option<Response>>,
-}
-
-struct Process {
-    path: PathBuf,
-    child: Child,
-}
-
-impl Drop for Process {
-    fn drop(&mut self) {
-        let _ = self.child.kill();
-    }
-}
-
-impl Process {
-    fn run(process_path: &Path) -> Result<Process, io::Error> {
-        let child = Command::new(process_path.clone())
-            .stdin(Stdio::piped())
-            .stdout(Stdio::piped())
-            .stderr(Stdio::null())
-            .spawn()?;
-
-        Ok(Process { path: process_path.into(), child })
-    }
-
-    fn restart(&mut self) -> Result<(), io::Error> {
-        let _ = self.child.kill();
-        self.child = Command::new(self.path.clone())
-            .stdin(Stdio::piped())
-            .stdout(Stdio::piped())
-            .stderr(Stdio::null())
-            .spawn()?;
-        Ok(())
-    }
-
-    fn stdio(&mut self) -> Option<(impl Write, impl BufRead)> {
-        let stdin = self.child.stdin.take()?;
-        let stdout = self.child.stdout.take()?;
-        let read = BufReader::new(stdout);
-
-        Some((stdin, read))
-    }
-}
-
-impl ProcMacroProcessSrv {
-    pub fn run(
-        process_path: &Path,
-    ) -> Result<(ProcMacroProcessThread, ProcMacroProcessSrv), io::Error> {
-        let process = Process::run(process_path)?;
-
-        let (task_tx, task_rx) = bounded(0);
-        let handle = jod_thread::spawn(move || {
-            client_loop(task_rx, process);
-        });
-
-        let task_tx = Arc::new(task_tx);
-        let srv = ProcMacroProcessSrv { inner: Some(Arc::downgrade(&task_tx)) };
-        let thread = ProcMacroProcessThread { handle, sender: task_tx };
-
-        Ok((thread, srv))
-    }
-
-    pub fn find_proc_macros(
-        &self,
-        dylib_path: &Path,
-    ) -> Result<Vec<(String, ProcMacroKind)>, ra_tt::ExpansionError> {
-        let task = ListMacrosTask { lib: dylib_path.to_path_buf() };
-
-        let result: ListMacrosResult = self.send_task(Request::ListMacro(task))?;
-        Ok(result.macros)
-    }
-
-    pub fn custom_derive(
-        &self,
-        dylib_path: &Path,
-        subtree: &Subtree,
-        derive_name: &str,
-    ) -> Result<Subtree, ra_tt::ExpansionError> {
-        let task = ExpansionTask {
-            macro_body: subtree.clone(),
-            macro_name: derive_name.to_string(),
-            attributes: None,
-            lib: dylib_path.to_path_buf(),
-        };
-
-        let result: ExpansionResult = self.send_task(Request::ExpansionMacro(task))?;
-        Ok(result.expansion)
-    }
-
-    pub fn send_task<R>(&self, req: Request) -> Result<R, ra_tt::ExpansionError>
-    where
-        R: TryFrom<Response, Error = &'static str>,
-    {
-        let sender = match &self.inner {
-            None => return Err(ra_tt::ExpansionError::Unknown("No sender is found.".to_string())),
-            Some(it) => it,
-        };
-
-        let (result_tx, result_rx) = bounded(0);
-        let sender = match sender.upgrade() {
-            None => {
-                return Err(ra_tt::ExpansionError::Unknown("Proc macro process is closed.".into()))
-            }
-            Some(it) => it,
-        };
-        sender.send(Task { req: req.into(), result_tx }).unwrap();
-        let res = result_rx
-            .recv()
-            .map_err(|_| ra_tt::ExpansionError::Unknown("Proc macro thread is closed.".into()))?;
-
-        match res {
-            Some(Response::Error(err)) => {
-                return Err(ra_tt::ExpansionError::ExpansionError(err.message));
-            }
-            Some(res) => Ok(res.try_into().map_err(|err| {
-                ra_tt::ExpansionError::Unknown(format!(
-                    "Fail to get response, reason : {:#?} ",
-                    err
-                ))
-            })?),
-            None => Err(ra_tt::ExpansionError::Unknown("Empty result".into())),
-        }
-    }
-}
-
-fn client_loop(task_rx: Receiver<Task>, mut process: Process) {
-    let (mut stdin, mut stdout) = match process.stdio() {
-        None => return,
-        Some(it) => it,
-    };
-
-    for task in task_rx {
-        let Task { req, result_tx } = task;
-
-        match send_request(&mut stdin, &mut stdout, req) {
-            Ok(res) => result_tx.send(res).unwrap(),
-            Err(_err) => {
-                let res = Response::Error(ResponseError {
-                    code: ErrorCode::ServerErrorEnd,
-                    message: "Server closed".into(),
-                });
-                result_tx.send(res.into()).unwrap();
-                // Restart the process
-                if process.restart().is_err() {
-                    break;
-                }
-                let stdio = match process.stdio() {
-                    None => break,
-                    Some(it) => it,
-                };
-                stdin = stdio.0;
-                stdout = stdio.1;
-            }
-        }
-    }
-}
-
-fn send_request(
-    mut writer: &mut impl Write,
-    mut reader: &mut impl BufRead,
-    req: Request,
-) -> Result<Option<Response>, io::Error> {
-    req.write(&mut writer)?;
-    Ok(Response::read(&mut reader)?)
-}
diff --git a/crates/ra_proc_macro/src/rpc.rs b/crates/ra_proc_macro/src/rpc.rs
deleted file mode 100644
index 66b3f55db3..0000000000
--- a/crates/ra_proc_macro/src/rpc.rs
+++ /dev/null
@@ -1,266 +0,0 @@
-//! Data struture serialization related stuffs for RPC
-//!
-//! Define all necessary rpc serialization data structure,
-//! which include ra_tt related data and some task messages.
-//! Although adding Serialize and Deserialize trait to ra_tt directly seem to be much easier,
-//! we deliberately duplicate the ra_tt struct with #[serde(with = "XXDef")]
-//! for separation of code responsibility.
-
-use ra_tt::{
-    Delimiter, DelimiterKind, Ident, Leaf, Literal, Punct, SmolStr, Spacing, Subtree, TokenId,
-    TokenTree,
-};
-use serde::{Deserialize, Serialize};
-use std::path::PathBuf;
-
-#[derive(Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
-pub struct ListMacrosTask {
-    pub lib: PathBuf,
-}
-
-#[derive(Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
-pub enum ProcMacroKind {
-    CustomDerive,
-    FuncLike,
-    Attr,
-}
-
-#[derive(Clone, Eq, PartialEq, Debug, Default, Serialize, Deserialize)]
-pub struct ListMacrosResult {
-    pub macros: Vec<(String, ProcMacroKind)>,
-}
-
-#[derive(Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
-pub struct ExpansionTask {
-    /// Argument of macro call.
-    ///
-    /// In custom derive that would be a struct or enum; in attribute-like macro - underlying
-    /// item; in function-like macro - the macro body.
-    #[serde(with = "SubtreeDef")]
-    pub macro_body: Subtree,
-
-    /// Names of macros to expand.
-    ///
-    /// In custom derive those are names of derived traits (`Serialize`, `Getters`, etc.). In
-    /// attribute-like and functiona-like macros - single name of macro itself (`show_streams`).
-    pub macro_name: String,
-
-    /// Possible attributes for the attribute-like macros.
-    #[serde(with = "opt_subtree_def")]
-    pub attributes: Option<Subtree>,
-
-    pub lib: PathBuf,
-}
-
-#[derive(Clone, Eq, PartialEq, Debug, Default, Serialize, Deserialize)]
-pub struct ExpansionResult {
-    #[serde(with = "SubtreeDef")]
-    pub expansion: Subtree,
-}
-
-#[derive(Serialize, Deserialize)]
-#[serde(remote = "DelimiterKind")]
-enum DelimiterKindDef {
-    Parenthesis,
-    Brace,
-    Bracket,
-}
-
-#[derive(Serialize, Deserialize)]
-#[serde(remote = "TokenId")]
-struct TokenIdDef(u32);
-
-#[derive(Serialize, Deserialize)]
-#[serde(remote = "Delimiter")]
-struct DelimiterDef {
-    #[serde(with = "TokenIdDef")]
-    pub id: TokenId,
-    #[serde(with = "DelimiterKindDef")]
-    pub kind: DelimiterKind,
-}
-
-#[derive(Serialize, Deserialize)]
-#[serde(remote = "Subtree")]
-struct SubtreeDef {
-    #[serde(default, with = "opt_delimiter_def")]
-    pub delimiter: Option<Delimiter>,
-    #[serde(with = "vec_token_tree")]
-    pub token_trees: Vec<TokenTree>,
-}
-
-#[derive(Serialize, Deserialize)]
-#[serde(remote = "TokenTree")]
-enum TokenTreeDef {
-    #[serde(with = "LeafDef")]
-    Leaf(Leaf),
-    #[serde(with = "SubtreeDef")]
-    Subtree(Subtree),
-}
-
-#[derive(Serialize, Deserialize)]
-#[serde(remote = "Leaf")]
-enum LeafDef {
-    #[serde(with = "LiteralDef")]
-    Literal(Literal),
-    #[serde(with = "PunctDef")]
-    Punct(Punct),
-    #[serde(with = "IdentDef")]
-    Ident(Ident),
-}
-
-#[derive(Serialize, Deserialize)]
-#[serde(remote = "Literal")]
-struct LiteralDef {
-    pub text: SmolStr,
-    #[serde(with = "TokenIdDef")]
-    pub id: TokenId,
-}
-
-#[derive(Serialize, Deserialize)]
-#[serde(remote = "Punct")]
-struct PunctDef {
-    pub char: char,
-    #[serde(with = "SpacingDef")]
-    pub spacing: Spacing,
-    #[serde(with = "TokenIdDef")]
-    pub id: TokenId,
-}
-
-#[derive(Serialize, Deserialize)]
-#[serde(remote = "Spacing")]
-enum SpacingDef {
-    Alone,
-    Joint,
-}
-
-#[derive(Serialize, Deserialize)]
-#[serde(remote = "Ident")]
-struct IdentDef {
-    pub text: SmolStr,
-    #[serde(with = "TokenIdDef")]
-    pub id: TokenId,
-}
-
-mod opt_delimiter_def {
-    use super::{Delimiter, DelimiterDef};
-    use serde::{Deserialize, Deserializer, Serialize, Serializer};
-
-    pub fn serialize<S>(value: &Option<Delimiter>, serializer: S) -> Result<S::Ok, S::Error>
-    where
-        S: Serializer,
-    {
-        #[derive(Serialize)]
-        struct Helper<'a>(#[serde(with = "DelimiterDef")] &'a Delimiter);
-        value.as_ref().map(Helper).serialize(serializer)
-    }
-
-    pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Delimiter>, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        #[derive(Deserialize)]
-        struct Helper(#[serde(with = "DelimiterDef")] Delimiter);
-        let helper = Option::deserialize(deserializer)?;
-        Ok(helper.map(|Helper(external)| external))
-    }
-}
-
-mod opt_subtree_def {
-    use super::{Subtree, SubtreeDef};
-    use serde::{Deserialize, Deserializer, Serialize, Serializer};
-
-    pub fn serialize<S>(value: &Option<Subtree>, serializer: S) -> Result<S::Ok, S::Error>
-    where
-        S: Serializer,
-    {
-        #[derive(Serialize)]
-        struct Helper<'a>(#[serde(with = "SubtreeDef")] &'a Subtree);
-        value.as_ref().map(Helper).serialize(serializer)
-    }
-
-    pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Subtree>, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        #[derive(Deserialize)]
-        struct Helper(#[serde(with = "SubtreeDef")] Subtree);
-        let helper = Option::deserialize(deserializer)?;
-        Ok(helper.map(|Helper(external)| external))
-    }
-}
-
-mod vec_token_tree {
-    use super::{TokenTree, TokenTreeDef};
-    use serde::{ser::SerializeSeq, Deserialize, Deserializer, Serialize, Serializer};
-
-    pub fn serialize<S>(value: &Vec<TokenTree>, serializer: S) -> Result<S::Ok, S::Error>
-    where
-        S: Serializer,
-    {
-        #[derive(Serialize)]
-        struct Helper<'a>(#[serde(with = "TokenTreeDef")] &'a TokenTree);
-
-        let items: Vec<_> = value.iter().map(Helper).collect();
-        let mut seq = serializer.serialize_seq(Some(items.len()))?;
-        for element in items {
-            seq.serialize_element(&element)?;
-        }
-        seq.end()
-    }
-
-    pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<TokenTree>, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        #[derive(Deserialize)]
-        struct Helper(#[serde(with = "TokenTreeDef")] TokenTree);
-
-        let helper = Vec::deserialize(deserializer)?;
-        Ok(helper.into_iter().map(|Helper(external)| external).collect())
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    fn fixture_token_tree() -> Subtree {
-        let mut subtree = Subtree::default();
-        subtree
-            .token_trees
-            .push(TokenTree::Leaf(Ident { text: "struct".into(), id: TokenId(0) }.into()));
-        subtree
-            .token_trees
-            .push(TokenTree::Leaf(Ident { text: "Foo".into(), id: TokenId(1) }.into()));
-        subtree.token_trees.push(TokenTree::Subtree(
-            Subtree {
-                delimiter: Some(Delimiter { id: TokenId(2), kind: DelimiterKind::Brace }),
-                token_trees: vec![],
-            }
-            .into(),
-        ));
-        subtree
-    }
-
-    #[test]
-    fn test_proc_macro_rpc_works() {
-        let tt = fixture_token_tree();
-        let task = ExpansionTask {
-            macro_body: tt.clone(),
-            macro_name: Default::default(),
-            attributes: None,
-            lib: Default::default(),
-        };
-
-        let json = serde_json::to_string(&task).unwrap();
-        let back: ExpansionTask = serde_json::from_str(&json).unwrap();
-
-        assert_eq!(task.macro_body, back.macro_body);
-
-        let result = ExpansionResult { expansion: tt.clone() };
-        let json = serde_json::to_string(&result).unwrap();
-        let back: ExpansionResult = serde_json::from_str(&json).unwrap();
-
-        assert_eq!(result, back);
-    }
-}
diff --git a/crates/ra_project_model/Cargo.toml b/crates/ra_project_model/Cargo.toml
index c3b7a8f74c..cdcdd63c91 100644
--- a/crates/ra_project_model/Cargo.toml
+++ b/crates/ra_project_model/Cargo.toml
@@ -16,7 +16,7 @@ cargo_metadata = "0.9.1"
 ra_arena = { path = "../ra_arena" }
 ra_db = { path = "../ra_db" }
 ra_cfg = { path = "../ra_cfg" }
-ra_flycheck = { path = "../ra_flycheck" }
+ra_cargo_watch = { path = "../ra_cargo_watch" }
 ra_proc_macro =  { path = "../ra_proc_macro" }
 
 serde = { version = "1.0.104", features = ["derive"] }
diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs
index 78ea2ab584..291594e2a2 100644
--- a/crates/ra_project_model/src/cargo_workspace.rs
+++ b/crates/ra_project_model/src/cargo_workspace.rs
@@ -1,7 +1,6 @@
 //! FIXME: write short doc here
 
 use std::{
-    ffi::OsStr,
     ops,
     path::{Path, PathBuf},
 };
@@ -9,8 +8,8 @@ use std::{
 use anyhow::{Context, Result};
 use cargo_metadata::{BuildScript, CargoOpt, Message, MetadataCommand, PackageId};
 use ra_arena::{Arena, Idx};
+use ra_cargo_watch::run_cargo;
 use ra_db::Edition;
-use ra_flycheck::run_cargo;
 use rustc_hash::FxHashMap;
 use serde::Deserialize;
 
@@ -76,7 +75,6 @@ pub type Target = Idx<TargetData>;
 
 #[derive(Debug, Clone)]
 pub struct PackageData {
-    pub id: String,
     pub name: String,
     pub manifest: PathBuf,
     pub targets: Vec<Target>,
@@ -182,7 +180,6 @@ impl CargoWorkspace {
                 .with_context(|| format!("Failed to parse edition {}", edition))?;
             let pkg = packages.alloc(PackageData {
                 name,
-                id: id.to_string(),
                 manifest: manifest_path,
                 targets: Vec::new(),
                 is_member,
@@ -252,18 +249,6 @@ impl CargoWorkspace {
     pub fn workspace_root(&self) -> &Path {
         &self.workspace_root
     }
-
-    pub fn package_flag(&self, package: &PackageData) -> String {
-        if self.is_unique(&*package.name) {
-            package.name.clone()
-        } else {
-            package.id.clone()
-        }
-    }
-
-    fn is_unique(&self, name: &str) -> bool {
-        self.packages.iter().filter(|(_, v)| v.name == name).count() == 1
-    }
 }
 
 #[derive(Debug, Clone, Default)]
@@ -300,10 +285,7 @@ pub fn load_extern_resources(cargo_toml: &Path, cargo_features: &CargoFeatures)
             Message::CompilerArtifact(message) => {
                 if message.target.kind.contains(&"proc-macro".to_string()) {
                     let package_id = message.package_id;
-                    // Skip rmeta file
-                    if let Some(filename) =
-                        message.filenames.iter().filter(|name| is_dylib(name)).next()
-                    {
+                    if let Some(filename) = message.filenames.get(0) {
                         acc.proc_dylib_paths.insert(package_id, filename.clone());
                     }
                 }
@@ -320,11 +302,3 @@ pub fn load_extern_resources(cargo_toml: &Path, cargo_features: &CargoFeatures)
 
     acc
 }
-
-// FIXME: File a better way to know if it is a dylib
-fn is_dylib(path: &Path) -> bool {
-    match path.extension().and_then(OsStr::to_str).map(|it| it.to_string().to_lowercase()) {
-        None => false,
-        Some(ext) => matches!(ext.as_str(), "dll" | "dylib" | "so"),
-    }
-}
diff --git a/crates/ra_syntax/src/ast/edit.rs b/crates/ra_syntax/src/ast/edit.rs
index b69cae234c..3d023f1891 100644
--- a/crates/ra_syntax/src/ast/edit.rs
+++ b/crates/ra_syntax/src/ast/edit.rs
@@ -369,32 +369,21 @@ impl ast::MatchArmList {
 
     #[must_use]
     pub fn remove_placeholder(&self) -> ast::MatchArmList {
-        let placeholder =
-            self.arms().find(|arm| matches!(arm.pat(), Some(ast::Pat::PlaceholderPat(_))));
+        let placeholder = self.arms().find(|arm| {
+            if let Some(ast::Pat::PlaceholderPat(_)) = arm.pat() {
+                return true;
+            }
+            false
+        });
         if let Some(placeholder) = placeholder {
-            self.remove_arm(&placeholder)
+            let s: SyntaxElement = placeholder.syntax().clone().into();
+            let e = s.clone();
+            self.replace_children(s..=e, &mut iter::empty())
         } else {
             self.clone()
         }
     }
 
-    #[must_use]
-    fn remove_arm(&self, arm: &ast::MatchArm) -> ast::MatchArmList {
-        let start = arm.syntax().clone();
-        let end = if let Some(comma) = start
-            .siblings_with_tokens(Direction::Next)
-            .skip(1)
-            .skip_while(|it| it.kind().is_trivia())
-            .next()
-            .filter(|it| it.kind() == T![,])
-        {
-            comma
-        } else {
-            start.clone().into()
-        };
-        self.replace_children(start.into()..=end, None)
-    }
-
     #[must_use]
     pub fn append_arm(&self, item: ast::MatchArm) -> ast::MatchArmList {
         let r_curly = match self.syntax().children_with_tokens().find(|it| it.kind() == T!['}']) {
diff --git a/crates/ra_syntax/src/parsing/text_tree_sink.rs b/crates/ra_syntax/src/parsing/text_tree_sink.rs
index 87bb21cd9a..dd202601d9 100644
--- a/crates/ra_syntax/src/parsing/text_tree_sink.rs
+++ b/crates/ra_syntax/src/parsing/text_tree_sink.rs
@@ -149,21 +149,10 @@ fn n_attached_trivias<'a>(
         MACRO_CALL | CONST_DEF | TYPE_ALIAS_DEF | STRUCT_DEF | ENUM_DEF | ENUM_VARIANT | FN_DEF
         | TRAIT_DEF | MODULE | RECORD_FIELD_DEF | STATIC_DEF => {
             let mut res = 0;
-            let mut trivias = trivias.enumerate().peekable();
-
-            while let Some((i, (kind, text))) = trivias.next() {
+            for (i, (kind, text)) in trivias.enumerate() {
                 match kind {
                     WHITESPACE => {
                         if text.contains("\n\n") {
-                            // we check whether the next token is a doc-comment
-                            // and skip the whitespace in this case
-                            if let Some((peek_kind, peek_text)) =
-                                trivias.peek().map(|(_, pair)| pair)
-                            {
-                                if *peek_kind == COMMENT && peek_text.starts_with("///") {
-                                    continue;
-                                }
-                            }
                             break;
                         }
                     }
diff --git a/crates/ra_tt/src/lib.rs b/crates/ra_tt/src/lib.rs
index bd484aa30a..1015ce0a60 100644
--- a/crates/ra_tt/src/lib.rs
+++ b/crates/ra_tt/src/lib.rs
@@ -189,12 +189,7 @@ impl Subtree {
 pub mod buffer;
 
 #[derive(Debug, PartialEq, Eq)]
-pub enum ExpansionError {
-    IOError(String),
-    JsonError(String),
-    Unknown(String),
-    ExpansionError(String),
-}
+pub enum ExpansionError {}
 
 pub trait TokenExpander: Debug + Send + Sync + RefUnwindSafe {
     fn expand(&self, subtree: &Subtree, attrs: Option<&Subtree>)
diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml
index f5f7734325..8fe6799d23 100644
--- a/crates/rust-analyzer/Cargo.toml
+++ b/crates/rust-analyzer/Cargo.toml
@@ -33,7 +33,7 @@ threadpool = "1.7.1"
 stdx = { path = "../stdx" }
 
 lsp-server = "0.3.1"
-ra_flycheck = { path = "../ra_flycheck" }
+ra_cargo_watch = { path = "../ra_cargo_watch" }
 ra_ide = { path = "../ra_ide" }
 ra_prof = { path = "../ra_prof" }
 ra_project_model = { path = "../ra_project_model" }
diff --git a/crates/rust-analyzer/src/cargo_target_spec.rs b/crates/rust-analyzer/src/cargo_target_spec.rs
index 942c303287..f87bdcec5c 100644
--- a/crates/rust-analyzer/src/cargo_target_spec.rs
+++ b/crates/rust-analyzer/src/cargo_target_spec.rs
@@ -77,7 +77,7 @@ impl CargoTargetSpec {
             ProjectWorkspace::Cargo { cargo, .. } => {
                 let tgt = cargo.target_by_root(&path)?;
                 Some(CargoTargetSpec {
-                    package: cargo.package_flag(&cargo[cargo[tgt].package]),
+                    package: cargo[cargo[tgt].package].name.clone(),
                     target: cargo[tgt].name.clone(),
                     target_kind: cargo[tgt].kind,
                 })
diff --git a/crates/rust-analyzer/src/cli/analysis_bench.rs b/crates/rust-analyzer/src/cli/analysis_bench.rs
index 7667873d5f..7164b0adeb 100644
--- a/crates/rust-analyzer/src/cli/analysis_bench.rs
+++ b/crates/rust-analyzer/src/cli/analysis_bench.rs
@@ -12,7 +12,7 @@ use ra_db::{
     salsa::{Database, Durability},
     FileId, SourceDatabaseExt,
 };
-use ra_ide::{Analysis, AnalysisChange, AnalysisHost, CompletionConfig, FilePosition, LineCol};
+use ra_ide::{Analysis, AnalysisChange, AnalysisHost, CompletionOptions, FilePosition, LineCol};
 
 use crate::cli::{load_cargo::load_cargo, Verbosity};
 
@@ -102,7 +102,7 @@ pub fn analysis_bench(
             let file_position = FilePosition { file_id, offset };
 
             if is_completion {
-                let options = CompletionConfig::default();
+                let options = CompletionOptions::default();
                 let res = do_work(&mut host, file_id, |analysis| {
                     analysis.completions(file_position, &options)
                 });
diff --git a/crates/rust-analyzer/src/conv.rs b/crates/rust-analyzer/src/conv.rs
index e8dc953c38..6edc03fe0f 100644
--- a/crates/rust-analyzer/src/conv.rs
+++ b/crates/rust-analyzer/src/conv.rs
@@ -579,7 +579,7 @@ impl TryConvWith<&WorldSnapshot> for (FileId, RangeInfo<Vec<NavigationTarget>>)
             .into_iter()
             .map(|nav| (file_id, RangeInfo::new(range, nav)))
             .try_conv_with_to_vec(world)?;
-        if world.config.supports_location_link {
+        if world.options.supports_location_link {
             Ok(links.into())
         } else {
             let locations: Vec<Location> = links
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index bb33fb27d5..79ea90cc94 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -21,8 +21,8 @@ use lsp_types::{
     WorkDoneProgressBegin, WorkDoneProgressCreateParams, WorkDoneProgressEnd,
     WorkDoneProgressReport,
 };
-use ra_flycheck::{url_from_path_with_drive_lowercasing, CheckConfig, CheckTask};
-use ra_ide::{Canceled, FileId, InlayHintsConfig, LibraryData, SourceRootId};
+use ra_cargo_watch::{url_from_path_with_drive_lowercasing, CheckOptions, CheckTask};
+use ra_ide::{Canceled, FileId, InlayHintsOptions, LibraryData, SourceRootId};
 use ra_prof::profile;
 use ra_vfs::{VfsFile, VfsTask, Watch};
 use relative_path::RelativePathBuf;
@@ -38,7 +38,7 @@ use crate::{
         subscriptions::Subscriptions,
     },
     req,
-    world::{Config, WorldSnapshot, WorldState},
+    world::{Options, WorldSnapshot, WorldState},
     Result, ServerConfig,
 };
 use req::ConfigurationParams;
@@ -81,11 +81,11 @@ fn get_feature_flags(config: &ServerConfig, connection: &Connection) -> FeatureF
     ff
 }
 
-fn get_config(
+fn get_options(
     config: &ServerConfig,
     text_document_caps: Option<&TextDocumentClientCapabilities>,
-) -> Config {
-    Config {
+) -> Options {
+    Options {
         publish_decorations: config.publish_decorations,
         supports_location_link: text_document_caps
             .and_then(|it| it.definition)
@@ -95,13 +95,13 @@ fn get_config(
             .and_then(|it| it.folding_range.as_ref())
             .and_then(|it| it.line_folding_only)
             .unwrap_or(false),
-        inlay_hints: InlayHintsConfig {
+        inlay_hints: InlayHintsOptions {
             type_hints: config.inlay_hints_type,
             parameter_hints: config.inlay_hints_parameter,
             chaining_hints: config.inlay_hints_chaining,
             max_length: config.inlay_hints_max_length,
         },
-        check: CheckConfig {
+        cargo_watch: CheckOptions {
             enable: config.cargo_watch_enable,
             args: config.cargo_watch_args.clone(),
             command: config.cargo_watch_command.clone(),
@@ -109,7 +109,6 @@ fn get_config(
         },
         rustfmt_args: config.rustfmt_args.clone(),
         vscode_lldb: config.vscode_lldb,
-        proc_macro_srv: None, // FIXME: get this from config
     }
 }
 
@@ -211,7 +210,7 @@ pub fn main_loop(
             config.lru_capacity,
             &globs,
             Watch(!config.use_client_watching),
-            get_config(&config, text_document_caps),
+            get_options(&config, text_document_caps),
             feature_flags,
         )
     };
@@ -436,7 +435,7 @@ fn loop_turn(
                                 .to_owned();
                             world_state.update_configuration(
                                 new_config.lru_capacity,
-                                get_config(&new_config, text_document_caps),
+                                get_options(&new_config, text_document_caps),
                                 get_feature_flags(&new_config, connection),
                             );
                         }
@@ -499,7 +498,7 @@ fn loop_turn(
         update_file_notifications_on_threadpool(
             pool,
             world_state.snapshot(),
-            world_state.config.publish_decorations,
+            world_state.options.publish_decorations,
             task_sender.clone(),
             loop_state.subscriptions.subscriptions(),
         )
@@ -809,14 +808,14 @@ fn send_startup_progress(sender: &Sender<Message>, loop_state: &mut LoopState) {
         ),
         _ => {}
     }
+}
 
-    fn send_startup_progress_notif(sender: &Sender<Message>, work_done_progress: WorkDoneProgress) {
-        let notif = notification_new::<req::Progress>(req::ProgressParams {
-            token: req::ProgressToken::String("rustAnalyzer/startup".into()),
-            value: req::ProgressParamsValue::WorkDone(work_done_progress),
-        });
-        sender.send(notif.into()).unwrap();
-    }
+fn send_startup_progress_notif(sender: &Sender<Message>, work_done_progress: WorkDoneProgress) {
+    let notif = notification_new::<req::Progress>(req::ProgressParams {
+        token: req::ProgressToken::String("rustAnalyzer/startup".into()),
+        value: req::ProgressParamsValue::WorkDone(work_done_progress),
+    });
+    sender.send(notif.into()).unwrap();
 }
 
 struct PoolDispatcher<'a> {
diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs
index d5cb5d1372..f60a3f0a0b 100644
--- a/crates/rust-analyzer/src/main_loop/handlers.rs
+++ b/crates/rust-analyzer/src/main_loop/handlers.rs
@@ -19,7 +19,7 @@ use lsp_types::{
     TextEdit, WorkspaceEdit,
 };
 use ra_ide::{
-    Assist, AssistId, CompletionConfig, FileId, FilePosition, FileRange, Query, RangeInfo,
+    Assist, AssistId, CompletionOptions, FileId, FilePosition, FileRange, Query, RangeInfo,
     Runnable, RunnableKind, SearchScope,
 };
 use ra_prof::profile;
@@ -425,7 +425,7 @@ pub fn handle_completion(
         return Ok(None);
     }
 
-    let config = CompletionConfig {
+    let options = CompletionOptions {
         enable_postfix_completions: world.feature_flags.get("completion.enable-postfix"),
         add_call_parenthesis: world.feature_flags.get("completion.insertion.add-call-parenthesis"),
         add_call_argument_snippets: world
@@ -433,7 +433,7 @@ pub fn handle_completion(
             .get("completion.insertion.add-argument-snippets"),
     };
 
-    let items = match world.analysis().completions(position, &config)? {
+    let items = match world.analysis().completions(position, &options)? {
         None => return Ok(None),
         Some(items) => items,
     };
@@ -457,7 +457,7 @@ pub fn handle_folding_range(
     let ctx = FoldConvCtx {
         text: &text,
         line_index: &line_index,
-        line_folding_only: world.config.line_folding_only,
+        line_folding_only: world.options.line_folding_only,
     };
     let res = Some(folds.into_iter().map_conv_with(&ctx).collect());
     Ok(res)
@@ -611,7 +611,7 @@ pub fn handle_formatting(
     let end_position = TextUnit::of_str(&file).conv_with(&file_line_index);
 
     let mut rustfmt = process::Command::new("rustfmt");
-    rustfmt.args(&world.config.rustfmt_args);
+    rustfmt.args(&world.options.rustfmt_args);
     if let Some(&crate_id) = crate_ids.first() {
         // Assume all crates are in the same edition
         let edition = world.analysis().crate_edition(crate_id)?;
@@ -815,7 +815,7 @@ pub fn handle_code_lens(
         };
         lenses.push(lens);
 
-        if world.config.vscode_lldb {
+        if world.options.vscode_lldb {
             if r.args[0] == "run" {
                 r.args[0] = "build".into();
             } else {
@@ -1028,7 +1028,7 @@ pub fn handle_inlay_hints(
     let analysis = world.analysis();
     let line_index = analysis.file_line_index(file_id)?;
     Ok(analysis
-        .inlay_hints(file_id, &world.config.inlay_hints)?
+        .inlay_hints(file_id, &world.options.inlay_hints)?
         .into_iter()
         .map_conv_with(&line_index)
         .collect())
diff --git a/crates/rust-analyzer/src/world.rs b/crates/rust-analyzer/src/world.rs
index acb729bae7..ad096a1d89 100644
--- a/crates/rust-analyzer/src/world.rs
+++ b/crates/rust-analyzer/src/world.rs
@@ -11,9 +11,9 @@ use std::{
 use crossbeam_channel::{unbounded, Receiver};
 use lsp_types::Url;
 use parking_lot::RwLock;
-use ra_flycheck::{url_from_path_with_drive_lowercasing, CheckConfig, CheckWatcher};
+use ra_cargo_watch::{url_from_path_with_drive_lowercasing, CheckOptions, CheckWatcher};
 use ra_ide::{
-    Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, InlayHintsConfig, LibraryData,
+    Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, InlayHintsOptions, LibraryData,
     SourceRootId,
 };
 use ra_project_model::{get_rustc_cfg_options, ProcMacroClient, ProjectWorkspace};
@@ -31,7 +31,7 @@ use crate::{
 use ra_db::ExternSourceId;
 use rustc_hash::{FxHashMap, FxHashSet};
 
-fn create_watcher(workspaces: &[ProjectWorkspace], config: &Config) -> Option<CheckWatcher> {
+fn create_watcher(workspaces: &[ProjectWorkspace], options: &Options) -> Option<CheckWatcher> {
     // FIXME: Figure out the multi-workspace situation
     workspaces
         .iter()
@@ -41,7 +41,7 @@ fn create_watcher(workspaces: &[ProjectWorkspace], config: &Config) -> Option<Ch
         })
         .map(|cargo| {
             let cargo_project_root = cargo.workspace_root().to_path_buf();
-            Some(CheckWatcher::new(config.check.clone(), cargo_project_root))
+            Some(CheckWatcher::new(&options.cargo_watch, cargo_project_root))
         })
         .unwrap_or_else(|| {
             log::warn!("Cargo check watching only supported for cargo workspaces, disabling");
@@ -50,15 +50,14 @@ fn create_watcher(workspaces: &[ProjectWorkspace], config: &Config) -> Option<Ch
 }
 
 #[derive(Debug, Clone)]
-pub struct Config {
+pub struct Options {
     pub publish_decorations: bool,
     pub supports_location_link: bool,
     pub line_folding_only: bool,
-    pub inlay_hints: InlayHintsConfig,
+    pub inlay_hints: InlayHintsOptions,
     pub rustfmt_args: Vec<String>,
-    pub check: CheckConfig,
+    pub cargo_watch: CheckOptions,
     pub vscode_lldb: bool,
-    pub proc_macro_srv: Option<String>,
 }
 
 /// `WorldState` is the primary mutable state of the language server
@@ -68,7 +67,7 @@ pub struct Config {
 /// incremental salsa database.
 #[derive(Debug)]
 pub struct WorldState {
-    pub config: Config,
+    pub options: Options,
     pub feature_flags: Arc<FeatureFlags>,
     pub roots: Vec<PathBuf>,
     pub workspaces: Arc<Vec<ProjectWorkspace>>,
@@ -82,7 +81,7 @@ pub struct WorldState {
 
 /// An immutable snapshot of the world's state at a point in time.
 pub struct WorldSnapshot {
-    pub config: Config,
+    pub options: Options,
     pub feature_flags: Arc<FeatureFlags>,
     pub workspaces: Arc<Vec<ProjectWorkspace>>,
     pub analysis: Analysis,
@@ -98,7 +97,7 @@ impl WorldState {
         lru_capacity: Option<usize>,
         exclude_globs: &[Glob],
         watch: Watch,
-        config: Config,
+        options: Options,
         feature_flags: FeatureFlags,
     ) -> WorldState {
         let mut change = AnalysisChange::new();
@@ -168,23 +167,8 @@ impl WorldState {
             vfs_file.map(|f| FileId(f.0))
         };
 
-        let proc_macro_client = match &config.proc_macro_srv {
-            None => ProcMacroClient::dummy(),
-            Some(srv) => {
-                let path = Path::new(&srv);
-                match ProcMacroClient::extern_process(path) {
-                    Ok(it) => it,
-                    Err(err) => {
-                        log::error!(
-                            "Fail to run ra_proc_macro_srv from path {}, error : {}",
-                            path.to_string_lossy(),
-                            err
-                        );
-                        ProcMacroClient::dummy()
-                    }
-                }
-            }
-        };
+        let proc_macro_client =
+            ProcMacroClient::extern_process(std::path::Path::new("ra_proc_macro_srv"));
 
         workspaces
             .iter()
@@ -201,12 +185,12 @@ impl WorldState {
             });
         change.set_crate_graph(crate_graph);
 
-        let check_watcher = create_watcher(&workspaces, &config);
+        let check_watcher = create_watcher(&workspaces, &options);
 
         let mut analysis_host = AnalysisHost::new(lru_capacity);
         analysis_host.apply_change(change);
         WorldState {
-            config: config,
+            options,
             feature_flags: Arc::new(feature_flags),
             roots: folder_roots,
             workspaces: Arc::new(workspaces),
@@ -222,13 +206,13 @@ impl WorldState {
     pub fn update_configuration(
         &mut self,
         lru_capacity: Option<usize>,
-        config: Config,
+        options: Options,
         feature_flags: FeatureFlags,
     ) {
         self.feature_flags = Arc::new(feature_flags);
         self.analysis_host.update_lru_capacity(lru_capacity);
-        self.check_watcher = create_watcher(&self.workspaces, &config);
-        self.config = config;
+        self.check_watcher = create_watcher(&self.workspaces, &options);
+        self.options = options;
     }
 
     /// Returns a vec of libraries
@@ -284,7 +268,7 @@ impl WorldState {
 
     pub fn snapshot(&self) -> WorldSnapshot {
         WorldSnapshot {
-            config: self.config.clone(),
+            options: self.options.clone(),
             feature_flags: Arc::clone(&self.feature_flags),
             workspaces: Arc::clone(&self.workspaces),
             analysis: self.analysis_host.analysis(),
diff --git a/editors/code/package-lock.json b/editors/code/package-lock.json
index 955a050666..b7220d8e20 100644
--- a/editors/code/package-lock.json
+++ b/editors/code/package-lock.json
@@ -84,9 +84,9 @@
             "dev": true
         },
         "@types/node": {
-            "version": "12.12.34",
-            "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.34.tgz",
-            "integrity": "sha512-BneGN0J9ke24lBRn44hVHNeDlrXRYF+VRp0HbSUNnEZahXGAysHZIqnf/hER6aabdBgzM4YOV4jrR8gj4Zfi0g==",
+            "version": "12.12.30",
+            "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.30.tgz",
+            "integrity": "sha512-sz9MF/zk6qVr3pAnM0BSQvYIBK44tS75QC5N+VbWSE4DjCV/pJ+UzCW/F+vVnl7TkOPcuwQureKNtSSwjBTaMg==",
             "dev": true
         },
         "@types/node-fetch": {
@@ -115,56 +115,45 @@
             "dev": true
         },
         "@typescript-eslint/eslint-plugin": {
-            "version": "2.26.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.26.0.tgz",
-            "integrity": "sha512-4yUnLv40bzfzsXcTAtZyTjbiGUXMrcIJcIMioI22tSOyAxpdXiZ4r7YQUU8Jj6XXrLz9d5aMHPQf5JFR7h27Nw==",
+            "version": "2.24.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.24.0.tgz",
+            "integrity": "sha512-wJRBeaMeT7RLQ27UQkDFOu25MqFOBus8PtOa9KaT5ZuxC1kAsd7JEHqWt4YXuY9eancX0GK9C68i5OROnlIzBA==",
             "dev": true,
             "requires": {
-                "@typescript-eslint/experimental-utils": "2.26.0",
+                "@typescript-eslint/experimental-utils": "2.24.0",
+                "eslint-utils": "^1.4.3",
                 "functional-red-black-tree": "^1.0.1",
                 "regexpp": "^3.0.0",
                 "tsutils": "^3.17.1"
             }
         },
         "@typescript-eslint/experimental-utils": {
-            "version": "2.26.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.26.0.tgz",
-            "integrity": "sha512-RELVoH5EYd+JlGprEyojUv9HeKcZqF7nZUGSblyAw1FwOGNnmQIU8kxJ69fttQvEwCsX5D6ECJT8GTozxrDKVQ==",
+            "version": "2.24.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.24.0.tgz",
+            "integrity": "sha512-DXrwuXTdVh3ycNCMYmWhUzn/gfqu9N0VzNnahjiDJvcyhfBy4gb59ncVZVxdp5XzBC77dCncu0daQgOkbvPwBw==",
             "dev": true,
             "requires": {
                 "@types/json-schema": "^7.0.3",
-                "@typescript-eslint/typescript-estree": "2.26.0",
-                "eslint-scope": "^5.0.0",
-                "eslint-utils": "^2.0.0"
-            },
-            "dependencies": {
-                "eslint-utils": {
-                    "version": "2.0.0",
-                    "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz",
-                    "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==",
-                    "dev": true,
-                    "requires": {
-                        "eslint-visitor-keys": "^1.1.0"
-                    }
-                }
+                "@typescript-eslint/typescript-estree": "2.24.0",
+                "eslint-scope": "^5.0.0"
             }
         },
         "@typescript-eslint/parser": {
-            "version": "2.26.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.26.0.tgz",
-            "integrity": "sha512-+Xj5fucDtdKEVGSh9353wcnseMRkPpEAOY96EEenN7kJVrLqy/EVwtIh3mxcUz8lsFXW1mT5nN5vvEam/a5HiQ==",
+            "version": "2.24.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.24.0.tgz",
+            "integrity": "sha512-H2Y7uacwSSg8IbVxdYExSI3T7uM1DzmOn2COGtCahCC3g8YtM1xYAPi2MAHyfPs61VKxP/J/UiSctcRgw4G8aw==",
             "dev": true,
             "requires": {
                 "@types/eslint-visitor-keys": "^1.0.0",
-                "@typescript-eslint/experimental-utils": "2.26.0",
-                "@typescript-eslint/typescript-estree": "2.26.0",
+                "@typescript-eslint/experimental-utils": "2.24.0",
+                "@typescript-eslint/typescript-estree": "2.24.0",
                 "eslint-visitor-keys": "^1.1.0"
             }
         },
         "@typescript-eslint/typescript-estree": {
-            "version": "2.26.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.26.0.tgz",
-            "integrity": "sha512-3x4SyZCLB4zsKsjuhxDLeVJN6W29VwBnYpCsZ7vIdPel9ZqLfIZJgJXO47MNUkurGpQuIBALdPQKtsSnWpE1Yg==",
+            "version": "2.24.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.24.0.tgz",
+            "integrity": "sha512-RJ0yMe5owMSix55qX7Mi9V6z2FDuuDpN6eR5fzRJrp+8in9UF41IGNQHbg5aMK4/PjVaEQksLvz0IA8n+Mr/FA==",
             "dev": true,
             "requires": {
                 "debug": "^4.1.1",
@@ -1399,9 +1388,9 @@
             }
         },
         "rollup": {
-            "version": "2.3.1",
-            "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.3.1.tgz",
-            "integrity": "sha512-BRjzOauORe+R0U0I6SkMTSG22nYmtztR/TaBl0SvbXgc3VAxBDrZoB6HROiK0S5px1pUBnLnjBkbzmVuwC9Q1Q==",
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.1.0.tgz",
+            "integrity": "sha512-gfE1455AEazVVTJoeQtcOq/U6GSxwoj4XPSWVsuWmgIxj7sBQNLDOSA82PbdMe+cP8ql8fR1jogPFe8Wg8g4SQ==",
             "dev": true,
             "requires": {
                 "fsevents": "~2.1.2"
diff --git a/editors/code/package.json b/editors/code/package.json
index ba31c4e63d..37e0832208 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -39,13 +39,13 @@
     "devDependencies": {
         "@rollup/plugin-commonjs": "^11.0.2",
         "@rollup/plugin-node-resolve": "^7.1.1",
-        "@types/node": "^12.12.34",
+        "@types/node": "^12.12.30",
         "@types/node-fetch": "^2.5.5",
         "@types/vscode": "^1.43.0",
-        "@typescript-eslint/eslint-plugin": "^2.26.0",
-        "@typescript-eslint/parser": "^2.26.0",
+        "@typescript-eslint/eslint-plugin": "^2.24.0",
+        "@typescript-eslint/parser": "^2.24.0",
         "eslint": "^6.8.0",
-        "rollup": "^2.3.1",
+        "rollup": "^2.1.0",
         "tslib": "^1.11.1",
         "typescript": "^3.8.3",
         "typescript-formatter": "^7.2.2",
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts
index f909f8db26..d72ecc58fc 100644
--- a/editors/code/src/client.ts
+++ b/editors/code/src/client.ts
@@ -30,14 +30,15 @@ export function configToServerOptions(config: Config) {
     };
 }
 
-export async function createClient(config: Config, serverPath: string, cwd: string): Promise<lc.LanguageClient> {
+export async function createClient(config: Config, serverPath: string): Promise<lc.LanguageClient> {
     // '.' Is the fallback if no folder is open
     // TODO?: Workspace folders support Uri's (eg: file://test.txt).
     // It might be a good idea to test if the uri points to a file.
+    const workspaceFolderPath = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath ?? '.';
 
     const run: lc.Executable = {
         command: serverPath,
-        options: { cwd },
+        options: { cwd: workspaceFolderPath },
     };
     const serverOptions: lc.ServerOptions = {
         run,
diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts
index 86b5f36295..d2f49cd23d 100644
--- a/editors/code/src/ctx.ts
+++ b/editors/code/src/ctx.ts
@@ -15,13 +15,8 @@ export class Ctx {
 
     }
 
-    static async create(
-        config: Config,
-        extCtx: vscode.ExtensionContext,
-        serverPath: string,
-        cwd: string,
-    ): Promise<Ctx> {
-        const client = await createClient(config, serverPath, cwd);
+    static async create(config: Config, extCtx: vscode.ExtensionContext, serverPath: string): Promise<Ctx> {
+        const client = await createClient(config, serverPath);
         const res = new Ctx(config, extCtx, client, serverPath);
         res.pushCleanup(client.start());
         await client.onReady();
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts
index 7ba16120c3..a46dbde33c 100644
--- a/editors/code/src/main.ts
+++ b/editors/code/src/main.ts
@@ -13,7 +13,6 @@ import { log, assert } from './util';
 import { PersistentState } from './persistent_state';
 import { fetchRelease, download } from './net';
 import { spawnSync } from 'child_process';
-import { activateTaskProvider } from './tasks';
 
 let ctx: Ctx | undefined;
 
@@ -42,18 +41,11 @@ export async function activate(context: vscode.ExtensionContext) {
     const state = new PersistentState(context.globalState);
     const serverPath = await bootstrap(config, state);
 
-    const workspaceFolder = vscode.workspace.workspaceFolders?.[0];
-    if (workspaceFolder === undefined) {
-        const err = "Cannot activate rust-analyzer when no folder is opened";
-        void vscode.window.showErrorMessage(err);
-        throw new Error(err);
-    }
-
     // Note: we try to start the server before we activate type hints so that it
     // registers its `onDidChangeDocument` handler before us.
     //
     // This a horribly, horribly wrong way to deal with this problem.
-    ctx = await Ctx.create(config, context, serverPath, workspaceFolder.uri.fsPath);
+    ctx = await Ctx.create(config, context, serverPath);
 
     // Commands which invokes manually via command palette, shortcut, etc.
 
@@ -93,8 +85,6 @@ export async function activate(context: vscode.ExtensionContext) {
     ctx.registerCommand('applySourceChange', commands.applySourceChange);
     ctx.registerCommand('selectAndApplySourceChange', commands.selectAndApplySourceChange);
 
-    ctx.pushCleanup(activateTaskProvider(workspaceFolder));
-
     activateStatusDisplay(ctx);
 
     if (!ctx.config.highlightingSemanticTokens) {
diff --git a/editors/code/src/tasks.ts b/editors/code/src/tasks.ts
deleted file mode 100644
index fa1c4a951d..0000000000
--- a/editors/code/src/tasks.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import * as vscode from 'vscode';
-
-// This ends up as the `type` key in tasks.json. RLS also uses `cargo` and
-// our configuration should be compatible with it so use the same key.
-const TASK_TYPE = 'cargo';
-
-export function activateTaskProvider(target: vscode.WorkspaceFolder): vscode.Disposable {
-    const provider: vscode.TaskProvider = {
-        // Detect Rust tasks. Currently we do not do any actual detection
-        // of tasks (e.g. aliases in .cargo/config) and just return a fixed
-        // set of tasks that always exist. These tasks cannot be removed in
-        // tasks.json - only tweaked.
-        provideTasks: () => getStandardCargoTasks(target),
-
-        // We don't need to implement this.
-        resolveTask: () => undefined,
-    };
-
-    return vscode.tasks.registerTaskProvider(TASK_TYPE, provider);
-}
-
-function getStandardCargoTasks(target: vscode.WorkspaceFolder): vscode.Task[] {
-    return [
-        { command: 'build', group: vscode.TaskGroup.Build },
-        { command: 'check', group: vscode.TaskGroup.Build },
-        { command: 'test', group: vscode.TaskGroup.Test },
-        { command: 'clean', group: vscode.TaskGroup.Clean },
-        { command: 'run', group: undefined },
-    ]
-        .map(({ command, group }) => {
-            const vscodeTask = new vscode.Task(
-                // The contents of this object end up in the tasks.json entries.
-                {
-                    type: TASK_TYPE,
-                    command,
-                },
-                // The scope of the task - workspace or specific folder (global
-                // is not supported).
-                target,
-                // The task name, and task source. These are shown in the UI as
-                // `${source}: ${name}`, e.g. `rust: cargo build`.
-                `cargo ${command}`,
-                'rust',
-                // What to do when this command is executed.
-                new vscode.ShellExecution('cargo', [command]),
-                // Problem matchers.
-                ['$rustc'],
-            );
-            vscodeTask.group = group;
-            return vscodeTask;
-        });
-}


Test patch:
diff --git a/crates/ra_flycheck/src/conv.rs b/crates/ra_cargo_watch/src/conv.rs
similarity index 100%
rename from crates/ra_flycheck/src/conv.rs
rename to crates/ra_cargo_watch/src/conv.rs
diff --git a/crates/ra_flycheck/src/conv/snapshots/ra_flycheck__conv__test__snap_clippy_pass_by_ref.snap b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_clippy_pass_by_ref.snap
similarity index 98%
rename from crates/ra_flycheck/src/conv/snapshots/ra_flycheck__conv__test__snap_clippy_pass_by_ref.snap
rename to crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_clippy_pass_by_ref.snap
index 4c9db0385b..a59fa84faa 100644
--- a/crates/ra_flycheck/src/conv/snapshots/ra_flycheck__conv__test__snap_clippy_pass_by_ref.snap
+++ b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_clippy_pass_by_ref.snap
@@ -1,5 +1,5 @@
 ---
-source: crates/ra_flycheck/src/conv/test.rs
+source: crates/ra_cargo_watch/src/conv/test.rs
 expression: diag
 ---
 [
diff --git a/crates/ra_flycheck/src/conv/snapshots/ra_flycheck__conv__test__snap_handles_macro_location.snap b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_handles_macro_location.snap
similarity index 96%
rename from crates/ra_flycheck/src/conv/snapshots/ra_flycheck__conv__test__snap_handles_macro_location.snap
rename to crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_handles_macro_location.snap
index 7cde4d8670..61ae0c9aee 100644
--- a/crates/ra_flycheck/src/conv/snapshots/ra_flycheck__conv__test__snap_handles_macro_location.snap
+++ b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_handles_macro_location.snap
@@ -1,5 +1,5 @@
 ---
-source: crates/ra_flycheck/src/conv/test.rs
+source: crates/ra_cargo_watch/src/conv/test.rs
 expression: diag
 ---
 [
diff --git a/crates/ra_flycheck/src/conv/snapshots/ra_flycheck__conv__test__snap_macro_compiler_error.snap b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_macro_compiler_error.snap
similarity index 97%
rename from crates/ra_flycheck/src/conv/snapshots/ra_flycheck__conv__test__snap_macro_compiler_error.snap
rename to crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_macro_compiler_error.snap
index 1cc37e087f..641da1a588 100644
--- a/crates/ra_flycheck/src/conv/snapshots/ra_flycheck__conv__test__snap_macro_compiler_error.snap
+++ b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_macro_compiler_error.snap
@@ -1,5 +1,5 @@
 ---
-source: crates/ra_flycheck/src/conv/test.rs
+source: crates/ra_cargo_watch/src/conv/test.rs
 expression: diag
 ---
 [
diff --git a/crates/ra_flycheck/src/conv/snapshots/ra_flycheck__conv__test__snap_multi_line_fix.snap b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_multi_line_fix.snap
similarity index 98%
rename from crates/ra_flycheck/src/conv/snapshots/ra_flycheck__conv__test__snap_multi_line_fix.snap
rename to crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_multi_line_fix.snap
index 615ed83787..0557a2e79e 100644
--- a/crates/ra_flycheck/src/conv/snapshots/ra_flycheck__conv__test__snap_multi_line_fix.snap
+++ b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_multi_line_fix.snap
@@ -1,5 +1,5 @@
 ---
-source: crates/ra_flycheck/src/conv/test.rs
+source: crates/ra_cargo_watch/src/conv/test.rs
 expression: diag
 ---
 [
diff --git a/crates/ra_flycheck/src/conv/snapshots/ra_flycheck__conv__test__snap_rustc_incompatible_type_for_trait.snap b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_incompatible_type_for_trait.snap
similarity index 96%
rename from crates/ra_flycheck/src/conv/snapshots/ra_flycheck__conv__test__snap_rustc_incompatible_type_for_trait.snap
rename to crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_incompatible_type_for_trait.snap
index 0df0fce188..754bc33a46 100644
--- a/crates/ra_flycheck/src/conv/snapshots/ra_flycheck__conv__test__snap_rustc_incompatible_type_for_trait.snap
+++ b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_incompatible_type_for_trait.snap
@@ -1,5 +1,5 @@
 ---
-source: crates/ra_flycheck/src/conv/test.rs
+source: crates/ra_cargo_watch/src/conv/test.rs
 expression: diag
 ---
 [
diff --git a/crates/ra_flycheck/src/conv/snapshots/ra_flycheck__conv__test__snap_rustc_mismatched_type.snap b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_mismatched_type.snap
similarity index 96%
rename from crates/ra_flycheck/src/conv/snapshots/ra_flycheck__conv__test__snap_rustc_mismatched_type.snap
rename to crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_mismatched_type.snap
index 28ebcb3b30..78b7f7cc83 100644
--- a/crates/ra_flycheck/src/conv/snapshots/ra_flycheck__conv__test__snap_rustc_mismatched_type.snap
+++ b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_mismatched_type.snap
@@ -1,5 +1,5 @@
 ---
-source: crates/ra_flycheck/src/conv/test.rs
+source: crates/ra_cargo_watch/src/conv/test.rs
 expression: diag
 ---
 [
diff --git a/crates/ra_flycheck/src/conv/snapshots/ra_flycheck__conv__test__snap_rustc_unused_variable.snap b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_unused_variable.snap
similarity index 98%
rename from crates/ra_flycheck/src/conv/snapshots/ra_flycheck__conv__test__snap_rustc_unused_variable.snap
rename to crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_unused_variable.snap
index 5e08732817..5989ed2026 100644
--- a/crates/ra_flycheck/src/conv/snapshots/ra_flycheck__conv__test__snap_rustc_unused_variable.snap
+++ b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_unused_variable.snap
@@ -1,5 +1,5 @@
 ---
-source: crates/ra_flycheck/src/conv/test.rs
+source: crates/ra_cargo_watch/src/conv/test.rs
 expression: diag
 ---
 [
diff --git a/crates/ra_flycheck/src/conv/snapshots/ra_flycheck__conv__test__snap_rustc_wrong_number_of_parameters.snap b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_wrong_number_of_parameters.snap
similarity index 97%
rename from crates/ra_flycheck/src/conv/snapshots/ra_flycheck__conv__test__snap_rustc_wrong_number_of_parameters.snap
rename to crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_wrong_number_of_parameters.snap
index e500d3cd6c..e34b546dc1 100644
--- a/crates/ra_flycheck/src/conv/snapshots/ra_flycheck__conv__test__snap_rustc_wrong_number_of_parameters.snap
+++ b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_wrong_number_of_parameters.snap
@@ -1,5 +1,5 @@
 ---
-source: crates/ra_flycheck/src/conv/test.rs
+source: crates/ra_cargo_watch/src/conv/test.rs
 expression: diag
 ---
 [
diff --git a/crates/ra_ide/src/completion/test_utils.rs b/crates/ra_ide/src/completion/test_utils.rs
index eb90b5279c..136857315c 100644
--- a/crates/ra_ide/src/completion/test_utils.rs
+++ b/crates/ra_ide/src/completion/test_utils.rs
@@ -1,19 +1,19 @@
 //! Runs completion for testing purposes.
 
 use crate::{
-    completion::{completion_item::CompletionKind, CompletionConfig},
+    completion::{completion_item::CompletionKind, CompletionOptions},
     mock_analysis::{analysis_and_position, single_file_with_position},
     CompletionItem,
 };
 
 pub(crate) fn do_completion(code: &str, kind: CompletionKind) -> Vec<CompletionItem> {
-    do_completion_with_options(code, kind, &CompletionConfig::default())
+    do_completion_with_options(code, kind, &CompletionOptions::default())
 }
 
 pub(crate) fn do_completion_with_options(
     code: &str,
     kind: CompletionKind,
-    options: &CompletionConfig,
+    options: &CompletionOptions,
 ) -> Vec<CompletionItem> {
     let (analysis, position) = if code.contains("//-") {
         analysis_and_position(code)
diff --git a/crates/ra_syntax/test_data/parser/ok/0065_comment_newline.rs b/crates/ra_syntax/test_data/parser/ok/0065_comment_newline.rs
deleted file mode 100644
index 1fafe216b6..0000000000
--- a/crates/ra_syntax/test_data/parser/ok/0065_comment_newline.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-/// Example
-
-fn test() {}
diff --git a/crates/ra_syntax/test_data/parser/ok/0065_comment_newline.txt b/crates/ra_syntax/test_data/parser/ok/0065_comment_newline.txt
deleted file mode 100644
index 91d0c37365..0000000000
--- a/crates/ra_syntax/test_data/parser/ok/0065_comment_newline.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-SOURCE_FILE@[0; 26)
-  FN_DEF@[0; 25)
-    COMMENT@[0; 11) "/// Example"
-    WHITESPACE@[11; 13) "\n\n"
-    FN_KW@[13; 15) "fn"
-    WHITESPACE@[15; 16) " "
-    NAME@[16; 20)
-      IDENT@[16; 20) "test"
-    PARAM_LIST@[20; 22)
-      L_PAREN@[20; 21) "("
-      R_PAREN@[21; 22) ")"
-    WHITESPACE@[22; 23) " "
-    BLOCK_EXPR@[23; 25)
-      BLOCK@[23; 25)
-        L_CURLY@[23; 24) "{"
-        R_CURLY@[24; 25) "}"
-  WHITESPACE@[25; 26) "\n"
diff --git a/crates/rust-analyzer/tests/heavy_tests/support.rs b/crates/rust-analyzer/tests/heavy_tests/support.rs
index fc3c65ad9e..67f3c9332e 100644
--- a/crates/rust-analyzer/tests/heavy_tests/support.rs
+++ b/crates/rust-analyzer/tests/heavy_tests/support.rs
@@ -188,7 +188,6 @@ impl Server {
         self.client.sender.send(r.into()).unwrap();
         while let Some(msg) = self.recv() {
             match msg {
-                Message::Request(req) if req.method == "window/workDoneProgress/create" => (),
                 Message::Request(req) => panic!("unexpected request: {:?}", req),
                 Message::Notification(_) => (),
                 Message::Response(res) => {