Repository: rust-analyzer/rust-analyzer
Pull request #2844 (2020-01-14 17:47:44)

Use dummy value for line! and column! macro
Use dummy value `0` for line! and column! macro. 


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 29e70d8fcd..12a8896a3e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -45,7 +45,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "backtrace"
-version = "0.3.41"
+version = "0.3.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1113,7 +1113,7 @@ dependencies = [
 name = "ra_prof"
 version = "0.1.0"
 dependencies = [
- "backtrace 0.3.41 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "jemalloc-ctl 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "jemallocator 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1780,7 +1780,7 @@ dependencies = [
 "checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
 "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
 "checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
-"checksum backtrace 0.3.41 (registry+https://github.com/rust-lang/crates.io-index)" = "a4ed64ae6d9ebfd9893193c4b2532b1292ec97bd8271c9d7d0fa90cd78a34cba"
+"checksum backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)" = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea"
 "checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491"
 "checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
 "checksum bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e84c238982c4b1e1ee668d136c510c67a13465279c0cb367ea6baf6310620a80"
diff --git a/bors.toml b/bors.toml
index bf5553df46..0bc71860f2 100644
--- a/bors.toml
+++ b/bors.toml
@@ -1,6 +1,6 @@
 status = [
     "Rust (ubuntu-latest)",
-    # "Rust (windows-latest)",
+    "Rust (windows-latest)",
     "Rust (macos-latest)",
     "TypeScript"
 ]
diff --git a/crates/ra_assists/src/assists/add_custom_impl.rs b/crates/ra_assists/src/assists/add_custom_impl.rs
index 52e8c693d3..037306fd67 100644
--- a/crates/ra_assists/src/assists/add_custom_impl.rs
+++ b/crates/ra_assists/src/assists/add_custom_impl.rs
@@ -10,7 +10,7 @@ use ra_syntax::{
     TextRange, TextUnit,
 };
 
-const DERIVE_TRAIT: &str = "derive";
+const DERIVE_TRAIT: &'static str = "derive";
 
 // Assist: add_custom_impl
 //
@@ -49,10 +49,7 @@ pub(crate) fn add_custom_impl(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist
     let annotated_name = annotated.syntax().text().to_string();
     let start_offset = annotated.syntax().parent()?.text_range().end();
 
-    let label =
-        format!("Add Custom impl '{}' for '{}'", trait_token.text().as_str(), annotated_name);
-
-    ctx.add_assist(AssistId("add_custom_impl"), label, |edit| {
+    ctx.add_assist(AssistId("add_custom_impl"), "add custom impl", |edit| {
         edit.target(attr.syntax().text_range());
 
         let new_attr_input = input
diff --git a/crates/ra_cargo_watch/src/lib.rs b/crates/ra_cargo_watch/src/lib.rs
index 20fa5a924e..cb0856aa43 100644
--- a/crates/ra_cargo_watch/src/lib.rs
+++ b/crates/ra_cargo_watch/src/lib.rs
@@ -184,13 +184,8 @@ impl CheckWatcherState {
         workspace_root: PathBuf,
         shared: Arc<RwLock<CheckWatcherSharedState>>,
     ) -> CheckWatcherState {
-        CheckWatcherState {
-            options,
-            workspace_root,
-            watcher: WatchThread::dummy(),
-            last_update_req: None,
-            shared,
-        }
+        let watcher = WatchThread::new(&options, &workspace_root);
+        CheckWatcherState { options, workspace_root, watcher, last_update_req: None, shared }
     }
 
     fn run(&mut self, task_send: &Sender<CheckTask>, cmd_recv: &Receiver<CheckCommand>) {
@@ -318,10 +313,6 @@ enum CheckEvent {
 }
 
 impl WatchThread {
-    fn dummy() -> WatchThread {
-        WatchThread { handle: None, message_recv: never() }
-    }
-
     fn new(options: &CheckOptions, workspace_root: &PathBuf) -> WatchThread {
         let mut args: Vec<String> = vec![
             options.command.clone(),
diff --git a/crates/ra_cli/src/analysis_stats.rs b/crates/ra_cli/src/analysis_stats.rs
index fd0027691b..ac65415a5e 100644
--- a/crates/ra_cli/src/analysis_stats.rs
+++ b/crates/ra_cli/src/analysis_stats.rs
@@ -183,6 +183,7 @@ pub fn run(
     println!("Total: {:?}, {}", analysis_time.elapsed(), ra_prof::memory_usage());
 
     if memory_usage {
+        drop(db);
         for (name, bytes) in host.per_query_memory_usage() {
             println!("{:>8} {}", bytes, name)
         }
diff --git a/crates/ra_cli/src/main.rs b/crates/ra_cli/src/main.rs
index 806612c2ce..3808590abe 100644
--- a/crates/ra_cli/src/main.rs
+++ b/crates/ra_cli/src/main.rs
@@ -22,7 +22,7 @@ pub enum Verbosity {
 }
 
 impl Verbosity {
-    fn is_verbose(self) -> bool {
+    fn is_verbose(&self) -> bool {
         match self {
             Verbosity::Verbose => true,
             _ => false,
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 3b479356f8..a177cebca1 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -21,8 +21,8 @@ use hir_expand::{
     MacroDefId,
 };
 use hir_ty::{
-    autoderef, display::HirFormatter, expr::ExprValidator, method_resolution, ApplicationTy,
-    Canonical, InEnvironment, TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk,
+    autoderef, display::HirFormatter, expr::ExprValidator, ApplicationTy, Canonical, InEnvironment,
+    TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk,
 };
 use ra_db::{CrateId, Edition, FileId};
 use ra_prof::profile;
@@ -120,8 +120,7 @@ impl_froms!(
     BuiltinType
 );
 
-pub use hir_def::{attr::Attrs, visibility::Visibility, AssocItemId};
-use rustc_hash::FxHashSet;
+pub use hir_def::{attr::Attrs, visibility::Visibility};
 
 impl Module {
     pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module {
@@ -879,28 +878,6 @@ impl Type {
         }
     }
 
-    /// Checks that particular type `ty` implements `std::future::Future`.
-    /// This function is used in `.await` syntax completion.
-    pub fn impls_future(&self, db: &impl HirDatabase) -> bool {
-        let krate = self.krate;
-
-        let std_future_trait =
-            db.lang_item(krate, "future_trait".into()).and_then(|it| it.as_trait());
-        let std_future_trait = match std_future_trait {
-            Some(it) => it,
-            None => return false,
-        };
-
-        let canonical_ty = Canonical { value: self.ty.value.clone(), num_vars: 0 };
-        method_resolution::implements_trait(
-            &canonical_ty,
-            db,
-            self.ty.environment.clone(),
-            krate,
-            std_future_trait,
-        )
-    }
-
     // FIXME: this method is broken, as it doesn't take closures into account.
     pub fn as_callable(&self) -> Option<CallableDef> {
         Some(self.ty.value.as_callable()?.0)
@@ -1009,65 +986,6 @@ impl Type {
         None
     }
 
-    pub fn iterate_method_candidates<T>(
-        &self,
-        db: &impl HirDatabase,
-        krate: Crate,
-        traits_in_scope: &FxHashSet<TraitId>,
-        name: Option<&Name>,
-        mut callback: impl FnMut(&Ty, Function) -> Option<T>,
-    ) -> Option<T> {
-        // There should be no inference vars in types passed here
-        // FIXME check that?
-        // FIXME replace Unknown by bound vars here
-        let canonical = Canonical { value: self.ty.value.clone(), num_vars: 0 };
-
-        let env = self.ty.environment.clone();
-        let krate = krate.id;
-
-        method_resolution::iterate_method_candidates(
-            &canonical,
-            db,
-            env,
-            krate,
-            traits_in_scope,
-            name,
-            method_resolution::LookupMode::MethodCall,
-            |ty, it| match it {
-                AssocItemId::FunctionId(f) => callback(ty, f.into()),
-                _ => None,
-            },
-        )
-    }
-
-    pub fn iterate_path_candidates<T>(
-        &self,
-        db: &impl HirDatabase,
-        krate: Crate,
-        traits_in_scope: &FxHashSet<TraitId>,
-        name: Option<&Name>,
-        mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>,
-    ) -> Option<T> {
-        // There should be no inference vars in types passed here
-        // FIXME check that?
-        // FIXME replace Unknown by bound vars here
-        let canonical = Canonical { value: self.ty.value.clone(), num_vars: 0 };
-
-        let env = self.ty.environment.clone();
-        let krate = krate.id;
-
-        method_resolution::iterate_method_candidates(
-            &canonical,
-            db,
-            env,
-            krate,
-            traits_in_scope,
-            name,
-            method_resolution::LookupMode::Path,
-            |ty, it| callback(ty, it.into()),
-        )
-    }
-
     pub fn as_adt(&self) -> Option<Adt> {
         let (adt, _subst) = self.ty.value.as_adt()?;
         Some(adt.into())
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index a1cf89010f..3d13978d45 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -27,7 +27,7 @@ macro_rules! impl_froms {
 }
 
 pub mod db;
-pub mod source_analyzer;
+pub mod source_binder;
 
 pub mod diagnostics;
 
@@ -46,7 +46,7 @@ pub use crate::{
     },
     from_source::FromSource,
     has_source::HasSource,
-    source_analyzer::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer},
+    source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer},
 };
 
 pub use hir_def::{
diff --git a/crates/ra_hir/src/source_analyzer.rs b/crates/ra_hir/src/source_binder.rs
similarity index 87%
rename from crates/ra_hir/src/source_analyzer.rs
rename to crates/ra_hir/src/source_binder.rs
index 76e0bff347..a2a9d968cb 100644
--- a/crates/ra_hir/src/source_analyzer.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -15,13 +15,17 @@ use hir_def::{
     },
     expr::{ExprId, PatId},
     nameres::ModuleSource,
+    path::path,
     resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs},
-    DefWithBodyId, TraitId,
+    AssocItemId, DefWithBodyId,
 };
 use hir_expand::{
     hygiene::Hygiene, name::AsName, AstId, HirFileId, InFile, MacroCallId, MacroCallKind,
 };
-use hir_ty::{InEnvironment, InferenceResult, TraitEnvironment};
+use hir_ty::{
+    method_resolution::{self, implements_trait},
+    Canonical, InEnvironment, InferenceResult, TraitEnvironment, Ty,
+};
 use ra_prof::profile;
 use ra_syntax::{
     ast::{self, AstNode},
@@ -29,13 +33,71 @@ use ra_syntax::{
     SyntaxKind::*,
     SyntaxNode, SyntaxNodePtr, SyntaxToken, TextRange, TextUnit,
 };
-use rustc_hash::FxHashSet;
 
 use crate::{
-    db::HirDatabase, Adt, Const, DefWithBody, Enum, EnumVariant, FromSource, Function, ImplBlock,
-    Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Type, TypeAlias, TypeParam,
+    db::HirDatabase, Adt, AssocItem, Const, DefWithBody, Enum, EnumVariant, FromSource, Function,
+    ImplBlock, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Type, TypeAlias,
+    TypeParam,
 };
 
+fn try_get_resolver_for_node(db: &impl HirDatabase, node: InFile<&SyntaxNode>) -> Option<Resolver> {
+    match_ast! {
+        match (node.value) {
+            ast::Module(it) => {
+                let src = node.with_value(it);
+                Some(crate::Module::from_declaration(db, src)?.id.resolver(db))
+            },
+             ast::SourceFile(it) => {
+                let src = node.with_value(ModuleSource::SourceFile(it));
+                Some(crate::Module::from_definition(db, src)?.id.resolver(db))
+            },
+            ast::StructDef(it) => {
+                let src = node.with_value(it);
+                Some(Struct::from_source(db, src)?.id.resolver(db))
+            },
+            ast::EnumDef(it) => {
+                let src = node.with_value(it);
+                Some(Enum::from_source(db, src)?.id.resolver(db))
+            },
+            ast::ImplBlock(it) => {
+                let src = node.with_value(it);
+                Some(ImplBlock::from_source(db, src)?.id.resolver(db))
+            },
+            ast::TraitDef(it) => {
+                let src = node.with_value(it);
+                Some(Trait::from_source(db, src)?.id.resolver(db))
+            },
+            _ => match node.value.kind() {
+                FN_DEF | CONST_DEF | STATIC_DEF => {
+                    let def = def_with_body_from_child_node(db, node)?;
+                    let def = DefWithBodyId::from(def);
+                    Some(def.resolver(db))
+                }
+                // FIXME add missing cases
+                _ => None
+            }
+        }
+    }
+}
+
+fn def_with_body_from_child_node(
+    db: &impl HirDatabase,
+    child: InFile<&SyntaxNode>,
+) -> Option<DefWithBody> {
+    let _p = profile("def_with_body_from_child_node");
+    child.cloned().ancestors_with_macros(db).find_map(|node| {
+        let n = &node.value;
+        match_ast! {
+            match n {
+                ast::FnDef(def)  => { return Function::from_source(db, node.with_value(def)).map(DefWithBody::from); },
+                ast::ConstDef(def) => { return Const::from_source(db, node.with_value(def)).map(DefWithBody::from); },
+                ast::StaticDef(def) => { return Static::from_source(db, node.with_value(def)).map(DefWithBody::from); },
+                _ => { None },
+            }
+        }
+    })
+}
+
 /// `SourceAnalyzer` is a convenience wrapper which exposes HIR API in terms of
 /// original source files. It should not be used inside the HIR itself.
 #[derive(Debug)]
@@ -347,9 +409,68 @@ impl SourceAnalyzer {
             .collect()
     }
 
-    /// Note: `FxHashSet<TraitId>` should be treated as an opaque type, passed into `Type
-    pub fn traits_in_scope(&self, db: &impl HirDatabase) -> FxHashSet<TraitId> {
-        self.resolver.traits_in_scope(db)
+    pub fn iterate_method_candidates<T>(
+        &self,
+        db: &impl HirDatabase,
+        ty: &Type,
+        name: Option<&Name>,
+        mut callback: impl FnMut(&Ty, Function) -> Option<T>,
+    ) -> Option<T> {
+        // There should be no inference vars in types passed here
+        // FIXME check that?
+        // FIXME replace Unknown by bound vars here
+        let canonical = Canonical { value: ty.ty.value.clone(), num_vars: 0 };
+        method_resolution::iterate_method_candidates(
+            &canonical,
+            db,
+            &self.resolver,
+            name,
+            method_resolution::LookupMode::MethodCall,
+            |ty, it| match it {
+                AssocItemId::FunctionId(f) => callback(ty, f.into()),
+                _ => None,
+            },
+        )
+    }
+
+    pub fn iterate_path_candidates<T>(
+        &self,
+        db: &impl HirDatabase,
+        ty: &Type,
+        name: Option<&Name>,
+        mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>,
+    ) -> Option<T> {
+        // There should be no inference vars in types passed here
+        // FIXME check that?
+        // FIXME replace Unknown by bound vars here
+        let canonical = Canonical { value: ty.ty.value.clone(), num_vars: 0 };
+        method_resolution::iterate_method_candidates(
+            &canonical,
+            db,
+            &self.resolver,
+            name,
+            method_resolution::LookupMode::Path,
+            |ty, it| callback(ty, it.into()),
+        )
+    }
+
+    /// Checks that particular type `ty` implements `std::future::Future`.
+    /// This function is used in `.await` syntax completion.
+    pub fn impls_future(&self, db: &impl HirDatabase, ty: Type) -> bool {
+        let std_future_path = path![std::future::Future];
+
+        let std_future_trait = match self.resolver.resolve_known_trait(db, &std_future_path) {
+            Some(it) => it.into(),
+            _ => return false,
+        };
+
+        let krate = match self.resolver.krate() {
+            Some(krate) => krate,
+            _ => return false,
+        };
+
+        let canonical_ty = Canonical { value: ty.ty.value, num_vars: 0 };
+        implements_trait(&canonical_ty, db, &self.resolver, krate.into(), std_future_trait)
     }
 
     pub fn expand(
@@ -366,64 +487,6 @@ impl SourceAnalyzer {
     }
 }
 
-fn try_get_resolver_for_node(db: &impl HirDatabase, node: InFile<&SyntaxNode>) -> Option<Resolver> {
-    match_ast! {
-        match (node.value) {
-            ast::Module(it) => {
-                let src = node.with_value(it);
-                Some(crate::Module::from_declaration(db, src)?.id.resolver(db))
-            },
-             ast::SourceFile(it) => {
-                let src = node.with_value(ModuleSource::SourceFile(it));
-                Some(crate::Module::from_definition(db, src)?.id.resolver(db))
-            },
-            ast::StructDef(it) => {
-                let src = node.with_value(it);
-                Some(Struct::from_source(db, src)?.id.resolver(db))
-            },
-            ast::EnumDef(it) => {
-                let src = node.with_value(it);
-                Some(Enum::from_source(db, src)?.id.resolver(db))
-            },
-            ast::ImplBlock(it) => {
-                let src = node.with_value(it);
-                Some(ImplBlock::from_source(db, src)?.id.resolver(db))
-            },
-            ast::TraitDef(it) => {
-                let src = node.with_value(it);
-                Some(Trait::from_source(db, src)?.id.resolver(db))
-            },
-            _ => match node.value.kind() {
-                FN_DEF | CONST_DEF | STATIC_DEF => {
-                    let def = def_with_body_from_child_node(db, node)?;
-                    let def = DefWithBodyId::from(def);
-                    Some(def.resolver(db))
-                }
-                // FIXME add missing cases
-                _ => None
-            }
-        }
-    }
-}
-
-fn def_with_body_from_child_node(
-    db: &impl HirDatabase,
-    child: InFile<&SyntaxNode>,
-) -> Option<DefWithBody> {
-    let _p = profile("def_with_body_from_child_node");
-    child.cloned().ancestors_with_macros(db).find_map(|node| {
-        let n = &node.value;
-        match_ast! {
-            match n {
-                ast::FnDef(def)  => { return Function::from_source(db, node.with_value(def)).map(DefWithBody::from); },
-                ast::ConstDef(def) => { return Const::from_source(db, node.with_value(def)).map(DefWithBody::from); },
-                ast::StaticDef(def) => { return Static::from_source(db, node.with_value(def)).map(DefWithBody::from); },
-                _ => { None },
-            }
-        }
-    })
-}
-
 fn scope_for(
     scopes: &ExprScopes,
     source_map: &BodySourceMap,
diff --git a/crates/ra_hir_expand/src/builtin_macro.rs b/crates/ra_hir_expand/src/builtin_macro.rs
index e9e2756709..f3f959ac68 100644
--- a/crates/ra_hir_expand/src/builtin_macro.rs
+++ b/crates/ra_hir_expand/src/builtin_macro.rs
@@ -1,8 +1,8 @@
 //! Builtin macro
 use crate::db::AstDatabase;
 use crate::{
-    ast::{self, AstNode},
-    name, AstId, CrateId, HirFileId, MacroCallId, MacroDefId, MacroDefKind, TextUnit,
+    ast::{self},
+    name, AstId, CrateId, MacroCallId, MacroDefId, MacroDefKind, TextUnit,
 };
 
 use crate::quote;
@@ -61,48 +61,13 @@ register_builtin! {
     (format_args_nl, FormatArgsNl) => format_args_expand
 }
 
-fn to_line_number(db: &dyn AstDatabase, file: HirFileId, pos: TextUnit) -> usize {
-    let file_id = file.original_file(db);
-
-    // FIXME: if the file is coming from macro, we return a dummy value for now.
-    if file.call_node(db).map(|it| it.file_id != file_id.into()).unwrap_or(true) {
-        return 0;
-    }
-
-    let text = db.file_text(file_id);
-    let mut line_num = 1;
-
-    let pos = pos.to_usize();
-    if pos > text.len() {
-        // FIXME: `pos` at the moment could be an offset inside the "wrong" file
-        // in this case, when we know it's wrong, we return a dummy value
-        return 0;
-    }
-    // Count line end
-    for (i, c) in text.chars().enumerate() {
-        if i == pos {
-            break;
-        }
-        if c == '\n' {
-            line_num += 1;
-        }
-    }
-    line_num
-}
-
 fn line_expand(
-    db: &dyn AstDatabase,
-    id: MacroCallId,
+    _db: &dyn AstDatabase,
+    _id: MacroCallId,
     _tt: &tt::Subtree,
 ) -> Result<tt::Subtree, mbe::ExpandError> {
-    let loc = db.lookup_intern_macro(id);
-
-    let arg = loc.kind.arg(db).ok_or_else(|| mbe::ExpandError::UnexpectedToken)?;
-    let arg_start = arg.text_range().start();
-
-    let file = id.as_file();
-    let line_num = to_line_number(db, file, arg_start);
-
+    // dummy implementation for type-checking purposes
+    let line_num = 0;
     let expanded = quote! {
         #line_num
     };
@@ -154,48 +119,13 @@ fn option_env_expand(
     Ok(expanded)
 }
 
-fn to_col_number(db: &dyn AstDatabase, file: HirFileId, pos: TextUnit) -> usize {
-    let file_id = file.original_file(db);
-    // FIXME: if the file is coming from macro, we return a dummy value for now.
-    if file.call_node(db).map(|it| it.file_id != file_id.into()).unwrap_or(true) {
-        return 0;
-    }
-    let text = db.file_text(file_id);
-
-    let pos = pos.to_usize();
-    if pos > text.len() {
-        // FIXME: `pos` at the moment could be an offset inside the "wrong" file
-        // in this case we return a dummy value so that we don't `panic!`
-        return 0;
-    }
-
-    let mut col_num = 1;
-    for c in text[..pos].chars().rev() {
-        if c == '\n' {
-            break;
-        }
-        col_num += 1;
-    }
-    col_num
-}
-
 fn column_expand(
-    db: &dyn AstDatabase,
-    id: MacroCallId,
+    _db: &dyn AstDatabase,
+    _id: MacroCallId,
     _tt: &tt::Subtree,
 ) -> Result<tt::Subtree, mbe::ExpandError> {
-    let loc = db.lookup_intern_macro(id);
-    let macro_call = match loc.kind {
-        crate::MacroCallKind::FnLike(ast_id) => ast_id.to_node(db),
-        _ => panic!("column macro called as attr"),
-    };
-
-    let _arg = macro_call.token_tree().ok_or_else(|| mbe::ExpandError::UnexpectedToken)?;
-    let col_start = macro_call.syntax().text_range().start();
-
-    let file = id.as_file();
-    let col_num = to_col_number(db, file, col_start);
-
+    // dummy implementation for type-checking purposes
+    let col_num = 0;
     let expanded = quote! {
         #col_num
     };
@@ -284,7 +214,7 @@ fn format_args_expand(
 #[cfg(test)]
 mod tests {
     use super::*;
-    use crate::{name::AsName, test_db::TestDB, MacroCallKind, MacroCallLoc};
+    use crate::{name::AsName, test_db::TestDB, AstNode, MacroCallKind, MacroCallLoc};
     use ra_db::{fixture::WithFixture, SourceDatabase};
     use ra_syntax::ast::NameOwner;
 
@@ -330,7 +260,7 @@ mod tests {
             "#,
         );
 
-        assert_eq!(expanded, "13");
+        assert_eq!(expanded, "0");
     }
 
     #[test]
@@ -343,7 +273,7 @@ mod tests {
             "#,
         );
 
-        assert_eq!(expanded, "4");
+        assert_eq!(expanded, "0");
     }
 
     #[test]
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs
index d6a17e469d..3af05394c6 100644
--- a/crates/ra_hir_ty/src/infer/expr.rs
+++ b/crates/ra_hir_ty/src/infer/expr.rs
@@ -569,19 +569,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
     ) -> Ty {
         let receiver_ty = self.infer_expr(receiver, &Expectation::none());
         let canonicalized_receiver = self.canonicalizer().canonicalize_ty(receiver_ty.clone());
-
-        let traits_in_scope = self.resolver.traits_in_scope(self.db);
-
-        let resolved = self.resolver.krate().and_then(|krate| {
-            method_resolution::lookup_method(
-                &canonicalized_receiver.value,
-                self.db,
-                self.trait_env.clone(),
-                krate,
-                &traits_in_scope,
-                method_name,
-            )
-        });
+        let resolved = method_resolution::lookup_method(
+            &canonicalized_receiver.value,
+            self.db,
+            method_name,
+            &self.resolver,
+        );
         let (derefed_receiver_ty, method_ty, def_generics) = match resolved {
             Some((ty, func)) => {
                 let ty = canonicalized_receiver.decanonicalize_ty(ty);
diff --git a/crates/ra_hir_ty/src/infer/path.rs b/crates/ra_hir_ty/src/infer/path.rs
index 2c1d4831d7..ffd3583675 100644
--- a/crates/ra_hir_ty/src/infer/path.rs
+++ b/crates/ra_hir_ty/src/infer/path.rs
@@ -11,7 +11,7 @@ use hir_expand::name::Name;
 
 use crate::{db::HirDatabase, method_resolution, Substs, Ty, TypeWalk, ValueTyDefId};
 
-use super::{ExprOrPatId, InferenceContext, TraitEnvironment, TraitRef};
+use super::{ExprOrPatId, InferenceContext, TraitRef};
 
 impl<'a, D: HirDatabase> InferenceContext<'a, D> {
     pub(super) fn infer_path(
@@ -193,16 +193,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
         }
 
         let canonical_ty = self.canonicalizer().canonicalize_ty(ty.clone());
-        let env = TraitEnvironment::lower(self.db, &self.resolver);
-        let krate = self.resolver.krate()?;
-        let traits_in_scope = self.resolver.traits_in_scope(self.db);
 
         method_resolution::iterate_method_candidates(
             &canonical_ty.value,
             self.db,
-            env,
-            krate,
-            &traits_in_scope,
+            &self.resolver.clone(),
             Some(name),
             method_resolution::LookupMode::Path,
             move |_ty, item| {
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs
index 5bacbbd7c7..888dc31166 100644
--- a/crates/ra_hir_ty/src/method_resolution.rs
+++ b/crates/ra_hir_ty/src/method_resolution.rs
@@ -6,13 +6,13 @@ use std::sync::Arc;
 
 use arrayvec::ArrayVec;
 use hir_def::{
-    lang_item::LangItemTarget, type_ref::Mutability, AssocContainerId, AssocItemId, FunctionId,
-    HasModule, ImplId, Lookup, TraitId,
+    lang_item::LangItemTarget, resolver::Resolver, type_ref::Mutability, AssocContainerId,
+    AssocItemId, FunctionId, HasModule, ImplId, Lookup, TraitId,
 };
 use hir_expand::name::Name;
 use ra_db::CrateId;
 use ra_prof::profile;
-use rustc_hash::{FxHashMap, FxHashSet};
+use rustc_hash::FxHashMap;
 
 use super::Substs;
 use crate::{
@@ -144,24 +144,14 @@ impl Ty {
 pub(crate) fn lookup_method(
     ty: &Canonical<Ty>,
     db: &impl HirDatabase,
-    env: Arc<TraitEnvironment>,
-    krate: CrateId,
-    traits_in_scope: &FxHashSet<TraitId>,
     name: &Name,
+    resolver: &Resolver,
 ) -> Option<(Ty, FunctionId)> {
-    iterate_method_candidates(
-        ty,
-        db,
-        env,
-        krate,
-        &traits_in_scope,
-        Some(name),
-        LookupMode::MethodCall,
-        |ty, f| match f {
-            AssocItemId::FunctionId(f) => Some((ty.clone(), f)),
-            _ => None,
-        },
-    )
+    iterate_method_candidates(ty, db, resolver, Some(name), LookupMode::MethodCall, |ty, f| match f
+    {
+        AssocItemId::FunctionId(f) => Some((ty.clone(), f)),
+        _ => None,
+    })
 }
 
 /// Whether we're looking up a dotted method call (like `v.len()`) or a path
@@ -182,9 +172,7 @@ pub enum LookupMode {
 pub fn iterate_method_candidates<T>(
     ty: &Canonical<Ty>,
     db: &impl HirDatabase,
-    env: Arc<TraitEnvironment>,
-    krate: CrateId,
-    traits_in_scope: &FxHashSet<TraitId>,
+    resolver: &Resolver,
     name: Option<&Name>,
     mode: LookupMode,
     mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
@@ -199,7 +187,9 @@ pub fn iterate_method_candidates<T>(
             // Also note that when we've got a receiver like &S, even if the method we
             // find in the end takes &self, we still do the autoderef step (just as
             // rustc does an autoderef and then autoref again).
-            let ty = InEnvironment { value: ty.clone(), environment: env.clone() };
+            let environment = TraitEnvironment::lower(db, resolver);
+            let ty = InEnvironment { value: ty.clone(), environment };
+            let krate = resolver.krate()?;
 
             // We have to be careful about the order we're looking at candidates
             // in here. Consider the case where we're resolving `x.clone()`
@@ -219,9 +209,7 @@ pub fn iterate_method_candidates<T>(
                 if let Some(result) = iterate_method_candidates_with_autoref(
                     &deref_chain[i..],
                     db,
-                    env.clone(),
-                    krate,
-                    traits_in_scope,
+                    resolver,
                     name,
                     &mut callback,
                 ) {
@@ -232,15 +220,7 @@ pub fn iterate_method_candidates<T>(
         }
         LookupMode::Path => {
             // No autoderef for path lookups
-            iterate_method_candidates_for_self_ty(
-                &ty,
-                db,
-                env,
-                krate,
-                traits_in_scope,
-                name,
-                &mut callback,
-            )
+            iterate_method_candidates_for_self_ty(&ty, db, resolver, name, &mut callback)
         }
     }
 }
@@ -248,9 +228,7 @@ pub fn iterate_method_candidates<T>(
 fn iterate_method_candidates_with_autoref<T>(
     deref_chain: &[Canonical<Ty>],
     db: &impl HirDatabase,
-    env: Arc<TraitEnvironment>,
-    krate: CrateId,
-    traits_in_scope: &FxHashSet<TraitId>,
+    resolver: &Resolver,
     name: Option<&Name>,
     mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
 ) -> Option<T> {
@@ -258,9 +236,7 @@ fn iterate_method_candidates_with_autoref<T>(
         &deref_chain[0],
         &deref_chain[1..],
         db,
-        env.clone(),
-        krate,
-        &traits_in_scope,
+        resolver,
         name,
         &mut callback,
     ) {
@@ -274,9 +250,7 @@ fn iterate_method_candidates_with_autoref<T>(
         &refed,
         deref_chain,
         db,
-        env.clone(),
-        krate,
-        &traits_in_scope,
+        resolver,
         name,
         &mut callback,
     ) {
@@ -290,9 +264,7 @@ fn iterate_method_candidates_with_autoref<T>(
         &ref_muted,
         deref_chain,
         db,
-        env.clone(),
-        krate,
-        &traits_in_scope,
+        resolver,
         name,
         &mut callback,
     ) {
@@ -305,15 +277,14 @@ fn iterate_method_candidates_by_receiver<T>(
     receiver_ty: &Canonical<Ty>,
     rest_of_deref_chain: &[Canonical<Ty>],
     db: &impl HirDatabase,
-    env: Arc<TraitEnvironment>,
-    krate: CrateId,
-    traits_in_scope: &FxHashSet<TraitId>,
+    resolver: &Resolver,
     name: Option<&Name>,
     mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
 ) -> Option<T> {
     // We're looking for methods with *receiver* type receiver_ty. These could
     // be found in any of the derefs of receiver_ty, so we have to go through
     // that.
+    let krate = resolver.krate()?;
     for self_ty in std::iter::once(receiver_ty).chain(rest_of_deref_chain) {
         if let Some(result) =
             iterate_inherent_methods(self_ty, db, name, Some(receiver_ty), krate, &mut callback)
@@ -325,9 +296,7 @@ fn iterate_method_candidates_by_receiver<T>(
         if let Some(result) = iterate_trait_method_candidates(
             self_ty,
             db,
-            env.clone(),
-            krate,
-            &traits_in_scope,
+            resolver,
             name,
             Some(receiver_ty),
             &mut callback,
@@ -341,25 +310,17 @@ fn iterate_method_candidates_by_receiver<T>(
 fn iterate_method_candidates_for_self_ty<T>(
     self_ty: &Canonical<Ty>,
     db: &impl HirDatabase,
-    env: Arc<TraitEnvironment>,
-    krate: CrateId,
-    traits_in_scope: &FxHashSet<TraitId>,
+    resolver: &Resolver,
     name: Option<&Name>,
     mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
 ) -> Option<T> {
+    let krate = resolver.krate()?;
     if let Some(result) = iterate_inherent_methods(self_ty, db, name, None, krate, &mut callback) {
         return Some(result);
     }
-    if let Some(result) = iterate_trait_method_candidates(
-        self_ty,
-        db,
-        env,
-        krate,
-        traits_in_scope,
-        name,
-        None,
-        &mut callback,
-    ) {
+    if let Some(result) =
+        iterate_trait_method_candidates(self_ty, db, resolver, name, None, &mut callback)
+    {
         return Some(result);
     }
     None
@@ -368,13 +329,14 @@ fn iterate_method_candidates_for_self_ty<T>(
 fn iterate_trait_method_candidates<T>(
     self_ty: &Canonical<Ty>,
     db: &impl HirDatabase,
-    env: Arc<TraitEnvironment>,
-    krate: CrateId,
-    traits_in_scope: &FxHashSet<TraitId>,
+    resolver: &Resolver,
     name: Option<&Name>,
     receiver_ty: Option<&Canonical<Ty>>,
     mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
 ) -> Option<T> {
+    let krate = resolver.krate()?;
+    // FIXME: maybe put the trait_env behind a query (need to figure out good input parameters for that)
+    let env = TraitEnvironment::lower(db, resolver);
     // if ty is `impl Trait` or `dyn Trait`, the trait doesn't need to be in scope
     let inherent_trait = self_ty.value.inherent_trait().into_iter();
     // if we have `T: Trait` in the param env, the trait doesn't need to be in scope
@@ -382,7 +344,8 @@ fn iterate_trait_method_candidates<T>(
         .trait_predicates_for_self_ty(&self_ty.value)
         .map(|tr| tr.trait_)
         .flat_map(|t| all_super_traits(db, t));
-    let traits = inherent_trait.chain(traits_from_env).chain(traits_in_scope.iter().copied());
+    let traits =
+        inherent_trait.chain(traits_from_env).chain(resolver.traits_in_scope(db).into_iter());
     'traits: for t in traits {
         let data = db.trait_data(t);
 
@@ -502,7 +465,7 @@ fn transform_receiver_ty(
 pub fn implements_trait(
     ty: &Canonical<Ty>,
     db: &impl HirDatabase,
-    env: Arc<TraitEnvironment>,
+    resolver: &Resolver,
     krate: CrateId,
     trait_: TraitId,
 ) -> bool {
@@ -511,6 +474,7 @@ pub fn implements_trait(
         // anyway, but currently Chalk doesn't implement `dyn/impl Trait` yet
         return true;
     }
+    let env = TraitEnvironment::lower(db, resolver);
     let goal = generic_implements_goal(db, env, trait_, ty.clone());
     let solution = db.trait_solve(krate.into(), goal);
 
diff --git a/crates/ra_hir_ty/src/traits.rs b/crates/ra_hir_ty/src/traits.rs
index 4aabd66dc6..c4dc857bc7 100644
--- a/crates/ra_hir_ty/src/traits.rs
+++ b/crates/ra_hir_ty/src/traits.rs
@@ -1,12 +1,10 @@
 //! Trait solving using Chalk.
-use std::{
-    panic,
-    sync::{Arc, Mutex},
-};
+use std::sync::{Arc, Mutex};
 
 use chalk_ir::cast::Cast;
 use hir_def::{expr::ExprId, DefWithBodyId, ImplId, TraitId, TypeAliasId};
-use ra_db::{impl_intern_key, salsa, Canceled, CrateId};
+use log::debug;
+use ra_db::{impl_intern_key, salsa, CrateId};
 use ra_prof::profile;
 use rustc_hash::FxHashSet;
 
@@ -41,7 +39,7 @@ impl TraitSolver {
         goal: &chalk_ir::UCanonical<chalk_ir::InEnvironment<chalk_ir::Goal<TypeFamily>>>,
     ) -> Option<chalk_solve::Solution<TypeFamily>> {
         let context = ChalkContext { db, krate: self.krate };
-        log::debug!("solve goal: {:?}", goal);
+        debug!("solve goal: {:?}", goal);
         let mut solver = match self.inner.lock() {
             Ok(it) => it,
             // Our cancellation works via unwinding, but, as chalk is not
@@ -49,28 +47,8 @@ impl TraitSolver {
             // Ideally, we should also make chalk panic-safe.
             Err(_) => ra_db::Canceled::throw(),
         };
-
-        let solution = panic::catch_unwind({
-            let solver = panic::AssertUnwindSafe(&mut solver);
-            let context = panic::AssertUnwindSafe(&context);
-            move || solver.0.solve(context.0, goal)
-        });
-
-        let solution = match solution {
-            Ok(it) => it,
-            Err(err) => {
-                if err.downcast_ref::<Canceled>().is_some() {
-                    panic::resume_unwind(err)
-                } else {
-                    log::error!("chalk panicked :-(");
-                    // Reset the solver, as it is not panic-safe.
-                    *solver = create_chalk_solver();
-                    None
-                }
-            }
-        };
-
-        log::debug!("solve({:?}) => {:?}", goal, solution);
+        let solution = solver.solve(&context, goal);
+        debug!("solve({:?}) => {:?}", goal, solution);
         solution
     }
 }
@@ -92,13 +70,9 @@ pub(crate) fn trait_solver_query(
 ) -> TraitSolver {
     db.salsa_runtime().report_untracked_read();
     // krate parameter is just so we cache a unique solver per crate
-    log::debug!("Creating new solver for crate {:?}", krate);
-    TraitSolver { krate, inner: Arc::new(Mutex::new(create_chalk_solver())) }
-}
-
-fn create_chalk_solver() -> chalk_solve::Solver<TypeFamily> {
     let solver_choice = chalk_solve::SolverChoice::SLG { max_size: CHALK_SOLVER_MAX_SIZE };
-    solver_choice.into_solver()
+    debug!("Creating new solver for crate {:?}", krate);
+    TraitSolver { krate, inner: Arc::new(Mutex::new(solver_choice.into_solver())) }
 }
 
 /// Collects impls for the given trait in the whole dependency tree of `krate`.
@@ -207,7 +181,7 @@ pub(crate) fn trait_solve_query(
     goal: Canonical<InEnvironment<Obligation>>,
 ) -> Option<Solution> {
     let _p = profile("trait_solve_query");
-    log::debug!("trait_solve_query({})", goal.value.value.display(db));
+    debug!("trait_solve_query({})", goal.value.value.display(db));
 
     if let Obligation::Projection(pred) = &goal.value.value {
         if let Ty::Bound(_) = &pred.projection_ty.parameters[0] {
diff --git a/crates/ra_ide/src/call_hierarchy.rs b/crates/ra_ide/src/call_hierarchy.rs
index aa5d60c7b5..1cb712e32d 100644
--- a/crates/ra_ide/src/call_hierarchy.rs
+++ b/crates/ra_ide/src/call_hierarchy.rs
@@ -121,7 +121,7 @@ pub(crate) fn outgoing_calls(db: &RootDatabase, position: FilePosition) -> Optio
                     Some(macro_def.to_nav(db))
                 }
             } {
-                Some((func_target, name_ref.value.text_range()))
+                Some((func_target.clone(), name_ref.value.text_range()))
             } else {
                 None
             }
diff --git a/crates/ra_ide/src/call_info.rs b/crates/ra_ide/src/call_info.rs
index 72a68522e5..a7023529b6 100644
--- a/crates/ra_ide/src/call_info.rs
+++ b/crates/ra_ide/src/call_info.rs
@@ -1,10 +1,10 @@
 //! FIXME: write short doc here
+
 use hir::db::AstDatabase;
 use ra_syntax::{
     ast::{self, ArgListOwner},
     match_ast, AstNode, SyntaxNode,
 };
-
 use test_utils::tested_by;
 
 use crate::{
@@ -51,39 +51,36 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal
     // If we have a calling expression let's find which argument we are on
     let num_params = call_info.parameters().len();
 
-    match num_params {
-        0 => (),
-        1 => {
-            if !has_self {
-                call_info.active_parameter = Some(0);
-            }
+    if num_params == 1 {
+        if !has_self {
+            call_info.active_parameter = Some(0);
         }
-        _ => {
-            if let Some(arg_list) = calling_node.arg_list() {
-                // Number of arguments specified at the call site
-                let num_args_at_callsite = arg_list.args().count();
-
-                let arg_list_range = arg_list.syntax().text_range();
-                if !arg_list_range.contains_inclusive(position.offset) {
-                    tested_by!(call_info_bad_offset);
-                    return None;
-                }
-
-                let mut param = std::cmp::min(
-                    num_args_at_callsite,
-                    arg_list
-                        .args()
-                        .take_while(|arg| arg.syntax().text_range().end() < position.offset)
-                        .count(),
-                );
-
-                // If we are in a method account for `self`
-                if has_self {
-                    param += 1;
-                }
+    } else if num_params > 1 {
+        // Count how many parameters into the call we are.
+        if let Some(arg_list) = calling_node.arg_list() {
+            // Number of arguments specified at the call site
+            let num_args_at_callsite = arg_list.args().count();
+
+            let arg_list_range = arg_list.syntax().text_range();
+            if !arg_list_range.contains_inclusive(position.offset) {
+                tested_by!(call_info_bad_offset);
+                return None;
+            }
 
-                call_info.active_parameter = Some(param);
+            let mut param = std::cmp::min(
+                num_args_at_callsite,
+                arg_list
+                    .args()
+                    .take_while(|arg| arg.syntax().text_range().end() < position.offset)
+                    .count(),
+            );
+
+            // If we are in a method account for `self`
+            if has_self {
+                param += 1;
             }
+
+            call_info.active_parameter = Some(param);
         }
     }
 
diff --git a/crates/ra_ide/src/completion/complete_dot.rs b/crates/ra_ide/src/completion/complete_dot.rs
index 2ca78c927f..210a685e40 100644
--- a/crates/ra_ide/src/completion/complete_dot.rs
+++ b/crates/ra_ide/src/completion/complete_dot.rs
@@ -27,7 +27,7 @@ pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) {
     complete_methods(acc, ctx, &receiver_ty);
 
     // Suggest .await syntax for types that implement Future trait
-    if receiver_ty.impls_future(ctx.db) {
+    if ctx.analyzer.impls_future(ctx.db, receiver_ty) {
         CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), "await")
             .detail("expr.await")
             .insert_text("await")
@@ -53,16 +53,13 @@ fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: &Ty
 }
 
 fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: &Type) {
-    if let Some(krate) = ctx.module.map(|it| it.krate()) {
-        let mut seen_methods = FxHashSet::default();
-        let traits_in_scope = ctx.analyzer.traits_in_scope(ctx.db);
-        receiver.iterate_method_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, func| {
-            if func.has_self_param(ctx.db) && seen_methods.insert(func.name(ctx.db)) {
-                acc.add_function(ctx, func);
-            }
-            None::<()>
-        });
-    }
+    let mut seen_methods = FxHashSet::default();
+    ctx.analyzer.iterate_method_candidates(ctx.db, receiver, None, |_ty, func| {
+        if func.has_self_param(ctx.db) && seen_methods.insert(func.name(ctx.db)) {
+            acc.add_function(ctx, func);
+        }
+        None::<()>
+    });
 }
 
 #[cfg(test)]
@@ -528,7 +525,6 @@ mod tests {
 
             //- /std/lib.rs
             pub mod future {
-                #[lang = "future_trait"]
                 pub trait Future {}
             }
             "###, CompletionKind::Keyword),
diff --git a/crates/ra_ide/src/completion/complete_path.rs b/crates/ra_ide/src/completion/complete_path.rs
index af24e9f48d..cc1f7c8305 100644
--- a/crates/ra_ide/src/completion/complete_path.rs
+++ b/crates/ra_ide/src/completion/complete_path.rs
@@ -26,7 +26,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
                     }
                     if let ScopeDef::Unknown = def {
                         if let Some(name_ref) = ctx.name_ref_syntax.as_ref() {
-                            if name_ref.syntax().text() == name.to_string().as_str() {
+                            if &name_ref.syntax().text() == name.to_string().as_str() {
                                 // for `use self::foo<|>`, don't suggest `foo` as a completion
                                 tested_by!(dont_complete_current_use);
                                 continue;
@@ -49,24 +49,22 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
                 hir::ModuleDef::TypeAlias(a) => a.ty(ctx.db),
                 _ => unreachable!(),
             };
+            ctx.analyzer.iterate_path_candidates(ctx.db, &ty, None, |_ty, item| {
+                match item {
+                    hir::AssocItem::Function(func) => {
+                        if !func.has_self_param(ctx.db) {
+                            acc.add_function(ctx, func);
+                        }
+                    }
+                    hir::AssocItem::Const(ct) => acc.add_const(ctx, ct),
+                    hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty),
+                }
+                None::<()>
+            });
             // Iterate assoc types separately
             // FIXME: complete T::AssocType
             let krate = ctx.module.map(|m| m.krate());
             if let Some(krate) = krate {
-                let traits_in_scope = ctx.analyzer.traits_in_scope(ctx.db);
-                ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| {
-                    match item {
-                        hir::AssocItem::Function(func) => {
-                            if !func.has_self_param(ctx.db) {
-                                acc.add_function(ctx, func);
-                            }
-                        }
-                        hir::AssocItem::Const(ct) => acc.add_const(ctx, ct),
-                        hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty),
-                    }
-                    None::<()>
-                });
-
                 ty.iterate_impl_items(ctx.db, krate, |item| {
                     match item {
                         hir::AssocItem::Function(_) | hir::AssocItem::Const(_) => {}
diff --git a/crates/ra_ide/src/extend_selection.rs b/crates/ra_ide/src/extend_selection.rs
index 930e0c4c24..70b6fde82f 100644
--- a/crates/ra_ide/src/extend_selection.rs
+++ b/crates/ra_ide/src/extend_selection.rs
@@ -339,7 +339,7 @@ mod tests {
         let (cursor, before) = extract_offset(before);
         let (analysis, file_id) = single_file(&before);
         let range = TextRange::offset_len(cursor, 0.into());
-        let mut frange = FileRange { file_id, range };
+        let mut frange = FileRange { file_id: file_id, range };
 
         for &after in afters {
             frange.range = analysis.extend_selection(frange).unwrap();
diff --git a/crates/ra_ide/src/references.rs b/crates/ra_ide/src/references.rs
index 2c753dade2..4e52e0e7bf 100644
--- a/crates/ra_ide/src/references.rs
+++ b/crates/ra_ide/src/references.rs
@@ -166,7 +166,7 @@ pub(crate) fn find_all_refs(
     Some(RangeInfo::new(range, ReferenceSearchResult { declaration, references }))
 }
 
-fn find_name(
+fn find_name<'a>(
     db: &RootDatabase,
     syntax: &SyntaxNode,
     position: FilePosition,
@@ -253,10 +253,13 @@ fn decl_access(
     let stmt = find_node_at_offset::<ast::LetStmt>(syntax, range.start())?;
     if let Some(_) = stmt.initializer() {
         let pat = stmt.pat()?;
-        if let ast::Pat::BindPat(it) = pat {
-            if it.name()?.text().as_str() == name {
-                return Some(ReferenceAccess::Write);
+        match pat {
+            ast::Pat::BindPat(it) => {
+                if it.name()?.text().as_str() == name {
+                    return Some(ReferenceAccess::Write);
+                }
             }
+            _ => {}
         }
     }
 
@@ -283,7 +286,7 @@ fn reference_access(kind: &NameKind, name_ref: &ast::NameRef) -> Option<Referenc
                             }
                         }
                     }
-                    Some(ReferenceAccess::Read)
+                    return Some(ReferenceAccess::Read);
                 },
                 _ => {None}
             }
diff --git a/crates/ra_ide/src/references/search_scope.rs b/crates/ra_ide/src/references/search_scope.rs
index f8211a7469..241dd358f9 100644
--- a/crates/ra_ide/src/references/search_scope.rs
+++ b/crates/ra_ide/src/references/search_scope.rs
@@ -82,7 +82,8 @@ impl NameDefinition {
             return SearchScope::new(res);
         }
 
-        let vis = self.visibility.as_ref().map(|v| v.syntax().to_string()).unwrap_or_default();
+        let vis =
+            self.visibility.as_ref().map(|v| v.syntax().to_string()).unwrap_or("".to_string());
 
         if vis.as_str() == "pub(super)" {
             if let Some(parent_module) = self.container.parent(db) {
diff --git a/crates/ra_lsp_server/src/main.rs b/crates/ra_lsp_server/src/main.rs
index 3879eeff2d..cdd925c9f3 100644
--- a/crates/ra_lsp_server/src/main.rs
+++ b/crates/ra_lsp_server/src/main.rs
@@ -47,10 +47,6 @@ fn run_server() -> Result<()> {
     let initialize_params = connection.initialize(server_capabilities)?;
     let initialize_params: lsp_types::InitializeParams = serde_json::from_value(initialize_params)?;
 
-    if let Some(client_info) = initialize_params.client_info {
-        log::info!("Client '{}' {}", client_info.name, client_info.version.unwrap_or_default());
-    }
-
     let cwd = std::env::current_dir()?;
     let root = initialize_params.root_uri.and_then(|it| it.to_file_path().ok()).unwrap_or(cwd);
 
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs
index 84012b99da..7a49cad866 100644
--- a/crates/ra_lsp_server/src/main_loop.rs
+++ b/crates/ra_lsp_server/src/main_loop.rs
@@ -417,7 +417,6 @@ fn loop_turn(
             let msg = format!("workspace loaded, {} rust packages", n_packages);
             show_message(req::MessageType::Info, msg, &connection.sender);
         }
-        world_state.check_watcher.update();
     }
 
     if state_changed {
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs
index d5a8bbe4db..a592f0a126 100644
--- a/crates/ra_lsp_server/src/main_loop/handlers.rs
+++ b/crates/ra_lsp_server/src/main_loop/handlers.rs
@@ -710,7 +710,6 @@ pub fn handle_code_action(
             title: command.title.clone(),
             kind: match assist.id {
                 AssistId("introduce_variable") => Some("refactor.extract.variable".to_string()),
-                AssistId("add_custom_impl") => Some("refactor.rewrite.add_custom_impl".to_string()),
                 _ => None,
             },
             diagnostics: None,
diff --git a/crates/ra_syntax/src/ast/expr_extensions.rs b/crates/ra_syntax/src/ast/expr_extensions.rs
index 6da4b1309a..3dfecfe762 100644
--- a/crates/ra_syntax/src/ast/expr_extensions.rs
+++ b/crates/ra_syntax/src/ast/expr_extensions.rs
@@ -127,8 +127,8 @@ pub enum BinOp {
 }
 
 impl BinOp {
-    pub fn is_assignment(self) -> bool {
-        match self {
+    pub fn is_assignment(&self) -> bool {
+        match *self {
             BinOp::Assignment
             | BinOp::AddAssign
             | BinOp::DivAssign
diff --git a/editors/code/package-lock.json b/editors/code/package-lock.json
index 746dd4bc37..3059323aa8 100644
--- a/editors/code/package-lock.json
+++ b/editors/code/package-lock.json
@@ -889,32 +889,32 @@
             }
         },
         "vscode-jsonrpc": {
-            "version": "5.0.0-next.7",
-            "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-5.0.0-next.7.tgz",
-            "integrity": "sha512-DZuEyxaWuA0srFh9kKu2fudVG6d5CJhte3OW2ILM8lZqpHjI+/D2byrowFd0YmEbyQB2nh0yqg0sa1mhxOtivA=="
+            "version": "5.0.0-next.5",
+            "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-5.0.0-next.5.tgz",
+            "integrity": "sha512-k9akfglxWgr0dtLNscq2uBq48XJwnhf4EaDxn05KQowRwR0DkNML0zeYqFRLtXZe6x5vpL5ppyu4o6GqL+23YQ=="
         },
         "vscode-languageclient": {
-            "version": "6.0.0-next.10",
-            "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-6.0.0-next.10.tgz",
-            "integrity": "sha512-xJ9KNJnHfGIMz7ewuXijtUTje1Tc2fpuyYS/DHZI/MBwYRLp7L38KnivvYJmUICdPnrQTSvPSWKbjlwWhMlKwQ==",
+            "version": "6.0.0-next.9",
+            "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-6.0.0-next.9.tgz",
+            "integrity": "sha512-NEpeeFM9FKrrRqlBHXGfwpkhtnjruDz3zfFBP+Cymr10qigAEtE/JsODJsIG/ErGqjh3/JXxu8SUOVTGu5oK+w==",
             "requires": {
                 "semver": "^6.3.0",
-                "vscode-languageserver-protocol": "^3.15.0-next.15"
+                "vscode-languageserver-protocol": "^3.15.0-next.14"
             }
         },
         "vscode-languageserver-protocol": {
-            "version": "3.15.0-next.15",
-            "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.0-next.15.tgz",
-            "integrity": "sha512-c1f47pxAtUE+gYTGLoySVA+nBUbPtz8NMOLOB69RiTBQobSJBO1XXKB8TXz8BSxpG5T8qRXeEm2vXrM/eepYKg==",
+            "version": "3.15.0-next.14",
+            "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.0-next.14.tgz",
+            "integrity": "sha512-xUwwno6Q6RFd2Z2EWV9D3dQlsKPnHyiZMNWq+EC7JJdp2WH1gRlD+KPX4UGRCnJK0WI5omqHV313IESPwRY5xA==",
             "requires": {
-                "vscode-jsonrpc": "^5.0.0-next.7",
-                "vscode-languageserver-types": "^3.15.0-next.10"
+                "vscode-jsonrpc": "^5.0.0-next.5",
+                "vscode-languageserver-types": "^3.15.0-next.9"
             }
         },
         "vscode-languageserver-types": {
-            "version": "3.15.0-next.10",
-            "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.10.tgz",
-            "integrity": "sha512-s9Psd+0sQVkH4o1U7hwTNJRuXQQgFvGVZIim7Wb44tcq54rZou3kJKCtdFEm0aHUuYxIrMPYrzuh1jlqCbRegw=="
+            "version": "3.15.0-next.9",
+            "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.9.tgz",
+            "integrity": "sha512-Rl/8qJ6932nrHCdPn+9y0x08uLVQaSLRG+U4JzhyKpWU4eJbVaDRoAcz1Llj7CErJGbPr6kdBvShPy5fRfR+Uw=="
         },
         "wrappy": {
             "version": "1.0.2",
diff --git a/editors/code/package.json b/editors/code/package.json
index fe2948861e..7c22d21d35 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -25,7 +25,7 @@
     "dependencies": {
         "jsonc-parser": "^2.1.0",
         "seedrandom": "^3.0.5",
-        "vscode-languageclient": "^6.0.0-next.10"
+        "vscode-languageclient": "^6.0.0-next.9"
     },
     "devDependencies": {
         "@rollup/plugin-commonjs": "^11.0.0",


Test patch:
diff --git a/crates/ra_hir_ty/src/tests/macros.rs b/crates/ra_hir_ty/src/tests/macros.rs
index 9d09d93a7c..652420ea8b 100644
--- a/crates/ra_hir_ty/src/tests/macros.rs
+++ b/crates/ra_hir_ty/src/tests/macros.rs
@@ -374,7 +374,7 @@ fn main() {
 }
 "#),
         @r###"
-    ![0; 1) '6': i32
+    ![0; 1) '0': i32
     [64; 88) '{     ...!(); }': ()
     [74; 75) 'x': i32
     "###
@@ -412,7 +412,7 @@ fn main() {
 }
 "#),
         @r###"
-    ![0; 2) '13': i32
+    ![0; 1) '0': i32
     [66; 92) '{     ...!(); }': ()
     [76; 77) 'x': i32
     "###