Repository: rust-analyzer/rust-analyzer
Pull request #2642 (2019-12-22 03:12:08)

Use name instead of ident in parser for macro 2.0 syntax


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 55afcda7bf..c29ce324e8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -761,7 +761,7 @@ dependencies = [
  "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
- "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -948,7 +948,6 @@ dependencies = [
  "ra_hir_def 0.1.0",
  "ra_hir_expand 0.1.0",
  "ra_hir_ty 0.1.0",
- "ra_prof 0.1.0",
  "ra_syntax 0.1.0",
  "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1077,7 +1076,7 @@ dependencies = [
  "ra_syntax 0.1.0",
  "ra_tt 0.1.0",
  "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "test_utils 0.1.0",
 ]
 
@@ -1122,7 +1121,7 @@ dependencies = [
  "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "ra_parser 0.1.0",
  "ra_text_edit 0.1.0",
- "rowan 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rowan 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_lexer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1388,7 +1387,7 @@ dependencies = [
 
 [[package]]
 name = "rowan"
-version = "0.8.2"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1443,7 +1442,7 @@ dependencies = [
  "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "salsa-macros 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1540,7 +1539,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "smallvec"
-version = "1.1.0"
+version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1643,7 +1642,7 @@ name = "unicode-normalization"
 version = "0.1.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1893,7 +1892,7 @@ dependencies = [
 "checksum relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bedde000f40f2921ce439ea165c9c53fd629bfa115140c72e22aceacb4a21954"
 "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
 "checksum ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ece421e0c4129b90e4a35b6f625e472e96c552136f5093a2f4fa2bbb75a62d5"
-"checksum rowan 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3eb10a10a48f0f809a217bcf074b85a03dcf79831bae80e7f1a043d0897463e2"
+"checksum rowan 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "769d42f547015b761f70c3086ccb3f7bff355124d52e9bf96d17de41774ede4b"
 "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
 "checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8"
 "checksum rustc_lexer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c86aae0c77166108c01305ee1a36a1e77289d7dc6ca0a3cd91ff4992de2d16a5"
@@ -1911,7 +1910,7 @@ dependencies = [
 "checksum serde_repr 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "cd02c7587ec314570041b2754829f84d873ced14a96d1fd1823531e11db40573"
 "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35"
 "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
-"checksum smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44e59e0c9fa00817912ae6e4e6e3c4fe04455e75699d06eedc7d85917ed8e8f4"
+"checksum smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86"
 "checksum smol_str 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "34836c9a295c62c2ce3514471117c5cb269891e8421b2aafdd910050576c4d8b"
 "checksum superslice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f"
 "checksum syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238"
diff --git a/crates/ra_hir/Cargo.toml b/crates/ra_hir/Cargo.toml
index 7dc31ad3cb..6ca9cc2e7d 100644
--- a/crates/ra_hir/Cargo.toml
+++ b/crates/ra_hir/Cargo.toml
@@ -14,7 +14,6 @@ either = "1.5"
 
 ra_syntax = { path = "../ra_syntax" }
 ra_db = { path = "../ra_db" }
-ra_prof = { path = "../ra_prof" }
 hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" }
 hir_def = { path = "../ra_hir_def", package = "ra_hir_def" }
 hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" }
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 4cd28eb4e3..fca3a29509 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -12,8 +12,8 @@ use hir_def::{
     resolver::HasResolver,
     type_ref::{Mutability, TypeRef},
     AdtId, ConstId, DefWithBodyId, EnumId, FunctionId, HasModule, ImplId, LocalEnumVariantId,
-    LocalModuleId, LocalStructFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId,
-    TypeParamId, UnionId,
+    LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, StaticId, StructId,
+    TraitId, TypeAliasId, TypeParamId, UnionId,
 };
 use hir_expand::{
     diagnostics::DiagnosticSink,
@@ -180,11 +180,13 @@ impl Module {
     }
 
     /// Returns a `ModuleScope`: a set of items, visible in this module.
-    pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef)> {
+    pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef, Option<Import>)> {
         db.crate_def_map(self.id.krate)[self.id.local_id]
             .scope
             .entries()
-            .map(|(name, res)| (name.clone(), res.def.into()))
+            .map(|(name, res)| {
+                (name.clone(), res.def.into(), res.import.map(|id| Import { parent: self, id }))
+            })
             .collect()
     }
 
@@ -227,6 +229,11 @@ impl Module {
     }
 }
 
+pub struct Import {
+    pub(crate) parent: Module,
+    pub(crate) id: LocalImportId,
+}
+
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub struct StructField {
     pub(crate) parent: VariantDef,
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index f5ffd64fa7..bfae3660b4 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -4,8 +4,8 @@ pub use hir_def::db::{
     BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, CrateDefMapQuery, CrateLangItemsQuery,
     DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery, ExprScopesQuery,
     FunctionDataQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage,
-    LangItemQuery, ModuleLangItemsQuery, RawItemsQuery, StaticDataQuery, StructDataQuery,
-    TraitDataQuery, TypeAliasDataQuery,
+    LangItemQuery, ModuleLangItemsQuery, RawItemsQuery, RawItemsWithSourceMapQuery,
+    StaticDataQuery, StructDataQuery, TraitDataQuery, TypeAliasDataQuery,
 };
 pub use hir_expand::db::{
     AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery,
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs
index 6314be8d4c..42ca55fe72 100644
--- a/crates/ra_hir/src/from_source.rs
+++ b/crates/ra_hir/src/from_source.rs
@@ -7,8 +7,6 @@ use hir_def::{
     StaticId, StructId, TraitId, TypeAliasId, UnionId, VariantId,
 };
 use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind};
-use ra_db::FileId;
-use ra_prof::profile;
 use ra_syntax::{
     ast::{self, AstNode, NameOwner},
     match_ast, SyntaxNode,
@@ -171,7 +169,6 @@ impl TypeParam {
 
 impl Module {
     pub fn from_declaration(db: &impl DefDatabase, src: InFile<ast::Module>) -> Option<Self> {
-        let _p = profile("Module::from_declaration");
         let parent_declaration = src.value.syntax().ancestors().skip(1).find_map(ast::Module::cast);
 
         let parent_module = match parent_declaration {
@@ -194,7 +191,6 @@ impl Module {
     }
 
     pub fn from_definition(db: &impl DefDatabase, src: InFile<ModuleSource>) -> Option<Self> {
-        let _p = profile("Module::from_definition");
         match src.value {
             ModuleSource::Module(ref module) => {
                 assert!(!module.has_semi());
@@ -207,14 +203,10 @@ impl Module {
         };
 
         let original_file = src.file_id.original_file(db);
-        Module::from_file(db, original_file)
-    }
 
-    fn from_file(db: &impl DefDatabase, file: FileId) -> Option<Self> {
-        let _p = profile("Module::from_file");
-        let (krate, local_id) = db.relevant_crates(file).iter().find_map(|&crate_id| {
+        let (krate, local_id) = db.relevant_crates(original_file).iter().find_map(|&crate_id| {
             let crate_def_map = db.crate_def_map(crate_id);
-            let local_id = crate_def_map.modules_for_file(file).next()?;
+            let local_id = crate_def_map.modules_for_file(original_file).next()?;
             Some((crate_id, local_id))
         })?;
         Some(Module { id: ModuleId { krate, local_id } })
@@ -222,7 +214,6 @@ impl Module {
 }
 
 fn analyze_container(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> DynMap {
-    let _p = profile("analyze_container");
     return child_by_source(db, src).unwrap_or_default();
 
     fn child_by_source(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> Option<DynMap> {
diff --git a/crates/ra_hir/src/has_source.rs b/crates/ra_hir/src/has_source.rs
index 5541266e2b..72afecf26c 100644
--- a/crates/ra_hir/src/has_source.rs
+++ b/crates/ra_hir/src/has_source.rs
@@ -9,8 +9,8 @@ use hir_def::{
 use ra_syntax::ast;
 
 use crate::{
-    db::DefDatabase, Const, Enum, EnumVariant, FieldSource, Function, ImplBlock, MacroDef, Module,
-    Static, Struct, StructField, Trait, TypeAlias, TypeParam, Union,
+    db::DefDatabase, Const, Enum, EnumVariant, FieldSource, Function, ImplBlock, Import, MacroDef,
+    Module, Static, Struct, StructField, Trait, TypeAlias, TypeParam, Union,
 };
 
 pub use hir_expand::InFile;
@@ -117,6 +117,18 @@ impl HasSource for ImplBlock {
         self.id.lookup(db).source(db)
     }
 }
+impl HasSource for Import {
+    type Ast = Either<ast::UseTree, ast::ExternCrateItem>;
+
+    /// Returns the syntax of the last path segment corresponding to this import
+    fn source(self, db: &impl DefDatabase) -> InFile<Self::Ast> {
+        let src = self.parent.definition_source(db);
+        let (_, source_map) = db.raw_items_with_source_map(src.file_id);
+        let root = db.parse_or_expand(src.file_id).unwrap();
+        let ptr = source_map.get(self.id);
+        src.with_value(ptr.map_left(|it| it.to_node(&root)).map_right(|it| it.to_node(&root)))
+    }
+}
 
 impl HasSource for TypeParam {
     type Ast = Either<ast::TraitDef, ast::TypeParam>;
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 0008a8858f..7f9aef7707 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -40,8 +40,8 @@ mod from_source;
 pub use crate::{
     code_model::{
         Adt, AssocItem, AttrDef, Const, Crate, CrateDependency, DefWithBody, Docs, Enum,
-        EnumVariant, FieldSource, Function, GenericDef, HasAttrs, ImplBlock, Local, MacroDef,
-        Module, ModuleDef, ScopeDef, Static, Struct, StructField, Trait, Type, TypeAlias,
+        EnumVariant, FieldSource, Function, GenericDef, HasAttrs, ImplBlock, Import, Local,
+        MacroDef, Module, ModuleDef, ScopeDef, Static, Struct, StructField, Trait, Type, TypeAlias,
         TypeParam, Union, VariantDef,
     },
     from_source::FromSource,
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 85b378483c..b60a6b87e4 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -26,7 +26,6 @@ use hir_ty::{
     method_resolution::{self, implements_trait},
     Canonical, InEnvironment, InferenceResult, TraitEnvironment, Ty,
 };
-use ra_prof::profile;
 use ra_syntax::{
     ast::{self, AstNode},
     match_ast, AstPtr,
@@ -84,7 +83,6 @@ 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! {
@@ -171,7 +169,6 @@ impl SourceAnalyzer {
         node: InFile<&SyntaxNode>,
         offset: Option<TextUnit>,
     ) -> SourceAnalyzer {
-        let _p = profile("SourceAnalyzer::new");
         let def_with_body = def_with_body_from_child_node(db, node);
         if let Some(def) = def_with_body {
             let (_body, source_map) = db.body_with_source_map(def.into());
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs
index d9ea693e34..ec3d57d1a9 100644
--- a/crates/ra_hir_def/src/adt.rs
+++ b/crates/ra_hir_def/src/adt.rs
@@ -8,7 +8,6 @@ use hir_expand::{
     InFile,
 };
 use ra_arena::{map::ArenaMap, Arena};
-use ra_prof::profile;
 use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
 
 use crate::{
@@ -73,7 +72,6 @@ impl StructData {
 
 impl EnumData {
     pub(crate) fn enum_data_query(db: &impl DefDatabase, e: EnumId) -> Arc<EnumData> {
-        let _p = profile("enum_data_query");
         let src = e.lookup(db).source(db);
         let name = src.value.name().map_or_else(Name::missing, |n| n.as_name());
         let mut trace = Trace::new_for_arena();
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs
index 148ff007ed..445d215b7b 100644
--- a/crates/ra_hir_def/src/body.rs
+++ b/crates/ra_hir_def/src/body.rs
@@ -11,7 +11,6 @@ use hir_expand::{
     ast_id_map::AstIdMap, hygiene::Hygiene, AstId, HirFileId, InFile, MacroCallKind, MacroDefId,
 };
 use ra_arena::{map::ArenaMap, Arena};
-use ra_prof::profile;
 use ra_syntax::{ast, AstNode, AstPtr};
 use rustc_hash::FxHashMap;
 
@@ -169,7 +168,6 @@ impl Body {
         db: &impl DefDatabase,
         def: DefWithBodyId,
     ) -> (Arc<Body>, Arc<BodySourceMap>) {
-        let _p = profile("body_with_source_map_query");
         let mut params = None;
 
         let (file_id, module, body) = match def {
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs
index c55fd41110..98bff6cb78 100644
--- a/crates/ra_hir_def/src/db.rs
+++ b/crates/ra_hir_def/src/db.rs
@@ -13,7 +13,10 @@ use crate::{
     docs::Documentation,
     generics::GenericParams,
     lang_item::{LangItemTarget, LangItems},
-    nameres::{raw::RawItems, CrateDefMap},
+    nameres::{
+        raw::{ImportSourceMap, RawItems},
+        CrateDefMap,
+    },
     AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc,
     GenericDefId, ImplId, ImplLoc, ModuleId, StaticId, StaticLoc, StructId, StructLoc, TraitId,
     TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc,
@@ -43,6 +46,12 @@ pub trait InternDatabase: SourceDatabase {
 
 #[salsa::query_group(DefDatabaseStorage)]
 pub trait DefDatabase: InternDatabase + AstDatabase {
+    #[salsa::invoke(RawItems::raw_items_with_source_map_query)]
+    fn raw_items_with_source_map(
+        &self,
+        file_id: HirFileId,
+    ) -> (Arc<RawItems>, Arc<ImportSourceMap>);
+
     #[salsa::invoke(RawItems::raw_items_query)]
     fn raw_items(&self, file_id: HirFileId) -> Arc<RawItems>;
 
diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs
index 9e082c5f74..6b9be8325d 100644
--- a/crates/ra_hir_def/src/item_scope.rs
+++ b/crates/ra_hir_def/src/item_scope.rs
@@ -5,7 +5,7 @@ use hir_expand::name::Name;
 use once_cell::sync::Lazy;
 use rustc_hash::FxHashMap;
 
-use crate::{per_ns::PerNs, BuiltinType, ImplId, MacroDefId, ModuleDefId, TraitId};
+use crate::{per_ns::PerNs, BuiltinType, ImplId, LocalImportId, MacroDefId, ModuleDefId, TraitId};
 
 #[derive(Debug, Default, PartialEq, Eq)]
 pub struct ItemScope {
@@ -30,7 +30,7 @@ static BUILTIN_SCOPE: Lazy<FxHashMap<Name, Resolution>> = Lazy::new(|| {
     BuiltinType::ALL
         .iter()
         .map(|(name, ty)| {
-            (name.clone(), Resolution { def: PerNs::types(ty.clone().into()), import: false })
+            (name.clone(), Resolution { def: PerNs::types(ty.clone().into()), import: None })
         })
         .collect()
 });
@@ -54,7 +54,7 @@ impl ItemScope {
 
     pub fn declarations(&self) -> impl Iterator<Item = ModuleDefId> + '_ {
         self.entries()
-            .filter_map(|(_name, res)| if !res.import { Some(res.def) } else { None })
+            .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None })
             .flat_map(|per_ns| {
                 per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter())
             })
@@ -112,27 +112,36 @@ impl ItemScope {
         self.legacy_macros.insert(name, mac);
     }
 
-    pub(crate) fn push_res(&mut self, name: Name, res: &Resolution, import: bool) -> bool {
+    pub(crate) fn push_res(
+        &mut self,
+        name: Name,
+        res: &Resolution,
+        import: Option<LocalImportId>,
+    ) -> bool {
         let mut changed = false;
         let existing = self.items.entry(name.clone()).or_default();
 
         if existing.def.types.is_none() && res.def.types.is_some() {
             existing.def.types = res.def.types;
-            existing.import = import || res.import;
+            existing.import = import.or(res.import);
             changed = true;
         }
         if existing.def.values.is_none() && res.def.values.is_some() {
             existing.def.values = res.def.values;
-            existing.import = import || res.import;
+            existing.import = import.or(res.import);
             changed = true;
         }
         if existing.def.macros.is_none() && res.def.macros.is_some() {
             existing.def.macros = res.def.macros;
-            existing.import = import || res.import;
+            existing.import = import.or(res.import);
             changed = true;
         }
 
-        if existing.def.is_none() && res.def.is_none() && !existing.import && res.import {
+        if existing.def.is_none()
+            && res.def.is_none()
+            && existing.import.is_none()
+            && res.import.is_some()
+        {
             existing.import = res.import;
         }
         changed
@@ -151,5 +160,6 @@ impl ItemScope {
 pub struct Resolution {
     /// None for unresolved
     pub def: PerNs,
-    pub(crate) import: bool,
+    /// ident by which this is imported into local scope.
+    pub import: Option<LocalImportId>,
 }
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index f6c7f38d17..acd4f4af17 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -51,6 +51,10 @@ use ra_syntax::{ast, AstNode};
 use crate::body::Expander;
 use crate::builtin_type::BuiltinType;
 
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub struct LocalImportId(RawId);
+impl_arena_id!(LocalImportId);
+
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub struct ModuleId {
     pub krate: CrateId,
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index 2b194f4881..45199fa114 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -26,7 +26,8 @@ use crate::{
     path::{ModPath, PathKind},
     per_ns::PerNs,
     AdtId, AstId, ConstLoc, ContainerId, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern,
-    LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc,
+    LocalImportId, LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, TraitLoc,
+    TypeAliasLoc, UnionLoc,
 };
 
 pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap {
@@ -92,7 +93,7 @@ impl PartialResolvedImport {
 #[derive(Clone, Debug, Eq, PartialEq)]
 struct ImportDirective {
     module_id: LocalModuleId,
-    import_id: raw::Import,
+    import_id: LocalImportId,
     import: raw::ImportData,
     status: PartialResolvedImport,
 }
@@ -109,7 +110,7 @@ struct MacroDirective {
 struct DefCollector<'a, DB> {
     db: &'a DB,
     def_map: CrateDefMap,
-    glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, raw::Import)>>,
+    glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, LocalImportId)>>,
     unresolved_imports: Vec<ImportDirective>,
     resolved_imports: Vec<ImportDirective>,
     unexpanded_macros: Vec<MacroDirective>,
@@ -218,7 +219,7 @@ where
             self.update(
                 self.def_map.root,
                 None,
-                &[(name, Resolution { def: PerNs::macros(macro_), import: false })],
+                &[(name, Resolution { def: PerNs::macros(macro_), import: None })],
             );
         }
     }
@@ -403,7 +404,7 @@ where
                             let variant = EnumVariantId { parent: e, local_id };
                             let res = Resolution {
                                 def: PerNs::both(variant.into(), variant.into()),
-                                import: true,
+                                import: Some(import_id),
                             };
                             (name, res)
                         })
@@ -430,7 +431,7 @@ where
                         }
                     }
 
-                    let resolution = Resolution { def, import: true };
+                    let resolution = Resolution { def, import: Some(import_id) };
                     self.update(module_id, Some(import_id), &[(name, resolution)]);
                 }
                 None => tested_by!(bogus_paths),
@@ -441,7 +442,7 @@ where
     fn update(
         &mut self,
         module_id: LocalModuleId,
-        import: Option<raw::Import>,
+        import: Option<LocalImportId>,
         resolutions: &[(Name, Resolution)],
     ) {
         self.update_recursive(module_id, import, resolutions, 0)
@@ -450,7 +451,7 @@ where
     fn update_recursive(
         &mut self,
         module_id: LocalModuleId,
-        import: Option<raw::Import>,
+        import: Option<LocalImportId>,
         resolutions: &[(Name, Resolution)],
         depth: usize,
     ) {
@@ -461,7 +462,7 @@ where
         let scope = &mut self.def_map.modules[module_id].scope;
         let mut changed = false;
         for (name, res) in resolutions {
-            changed |= scope.push_res(name.clone(), res, import.is_some());
+            changed |= scope.push_res(name.clone(), res, import);
         }
 
         if !changed {
@@ -718,7 +719,7 @@ where
             def: PerNs::types(
                 ModuleId { krate: self.def_collector.def_map.krate, local_id: res }.into(),
             ),
-            import: false,
+            import: None,
         };
         self.def_collector.update(self.module_id, None, &[(name, resolution)]);
         res
@@ -790,7 +791,7 @@ where
                 PerNs::types(def.into())
             }
         };
-        let resolution = Resolution { def, import: false };
+        let resolution = Resolution { def, import: None };
         self.def_collector.update(self.module_id, None, &[(name, resolution)])
     }
 
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs
index 73dc087459..ecb4d7c03d 100644
--- a/crates/ra_hir_def/src/nameres/raw.rs
+++ b/crates/ra_hir_def/src/nameres/raw.rs
@@ -7,21 +7,24 @@
 
 use std::{ops::Index, sync::Arc};
 
+use either::Either;
 use hir_expand::{
     ast_id_map::AstIdMap,
     db::AstDatabase,
     hygiene::Hygiene,
     name::{AsName, Name},
 };
-use ra_arena::{impl_arena_id, Arena, RawId};
-use ra_prof::profile;
+use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId};
 use ra_syntax::{
     ast::{self, AttrsOwner, NameOwner},
-    AstNode,
+    AstNode, AstPtr,
 };
 use test_utils::tested_by;
 
-use crate::{attr::Attrs, db::DefDatabase, path::ModPath, FileAstId, HirFileId, InFile};
+use crate::{
+    attr::Attrs, db::DefDatabase, path::ModPath, trace::Trace, FileAstId, HirFileId, InFile,
+    LocalImportId,
+};
 
 /// `RawItems` is a set of top-level items in a file (except for impls).
 ///
@@ -30,7 +33,7 @@ use crate::{attr::Attrs, db::DefDatabase, path::ModPath, FileAstId, HirFileId, I
 #[derive(Debug, Default, PartialEq, Eq)]
 pub struct RawItems {
     modules: Arena<Module, ModuleData>,
-    imports: Arena<Import, ImportData>,
+    imports: Arena<LocalImportId, ImportData>,
     defs: Arena<Def, DefData>,
     macros: Arena<Macro, MacroData>,
     impls: Arena<Impl, ImplData>,
@@ -38,15 +41,35 @@ pub struct RawItems {
     items: Vec<RawItem>,
 }
 
+#[derive(Debug, Default, PartialEq, Eq)]
+pub struct ImportSourceMap {
+    map: ArenaMap<LocalImportId, ImportSourcePtr>,
+}
+
+type ImportSourcePtr = Either<AstPtr<ast::UseTree>, AstPtr<ast::ExternCrateItem>>;
+
+impl ImportSourceMap {
+    pub fn get(&self, import: LocalImportId) -> ImportSourcePtr {
+        self.map[import].clone()
+    }
+}
+
 impl RawItems {
     pub(crate) fn raw_items_query(
         db: &(impl DefDatabase + AstDatabase),
         file_id: HirFileId,
     ) -> Arc<RawItems> {
-        let _p = profile("raw_items_query");
+        db.raw_items_with_source_map(file_id).0
+    }
+
+    pub(crate) fn raw_items_with_source_map_query(
+        db: &(impl DefDatabase + AstDatabase),
+        file_id: HirFileId,
+    ) -> (Arc<RawItems>, Arc<ImportSourceMap>) {
         let mut collector = RawItemsCollector {
             raw_items: RawItems::default(),
             source_ast_id_map: db.ast_id_map(file_id),
+            imports: Trace::new(),
             file_id,
             hygiene: Hygiene::new(db, file_id),
         };
@@ -57,8 +80,11 @@ impl RawItems {
                 collector.process_module(None, item_list);
             }
         }
-        let raw_items = collector.raw_items;
-        Arc::new(raw_items)
+        let mut raw_items = collector.raw_items;
+        let (arena, map) = collector.imports.into_arena_and_map();
+        raw_items.imports = arena;
+        let source_map = ImportSourceMap { map };
+        (Arc::new(raw_items), Arc::new(source_map))
     }
 
     pub(super) fn items(&self) -> &[RawItem] {
@@ -73,9 +99,9 @@ impl Index<Module> for RawItems {
     }
 }
 
-impl Index<Import> for RawItems {
+impl Index<LocalImportId> for RawItems {
     type Output = ImportData;
-    fn index(&self, idx: Import) -> &ImportData {
+    fn index(&self, idx: LocalImportId) -> &ImportData {
         &self.imports[idx]
     }
 }
@@ -110,7 +136,7 @@ pub(super) struct RawItem {
 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
 pub(super) enum RawItemKind {
     Module(Module),
-    Import(Import),
+    Import(LocalImportId),
     Def(Def),
     Macro(Macro),
     Impl(Impl),
@@ -126,10 +152,6 @@ pub(super) enum ModuleData {
     Definition { name: Name, ast_id: FileAstId<ast::Module>, items: Vec<RawItem> },
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub(crate) struct Import(RawId);
-impl_arena_id!(Import);
-
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct ImportData {
     pub(super) path: ModPath,
@@ -201,6 +223,7 @@ pub(super) struct ImplData {
 
 struct RawItemsCollector {
     raw_items: RawItems,
+    imports: Trace<LocalImportId, ImportData, ImportSourcePtr>,
     source_ast_id_map: Arc<AstIdMap>,
     file_id: HirFileId,
     hygiene: Hygiene,
@@ -307,7 +330,7 @@ impl RawItemsCollector {
         ModPath::expand_use_item(
             InFile { value: use_item, file_id: self.file_id },
             &self.hygiene,
-            |path, _use_tree, is_glob, alias| {
+            |path, use_tree, is_glob, alias| {
                 let import_data = ImportData {
                     path,
                     alias,
@@ -316,11 +339,11 @@ impl RawItemsCollector {
                     is_extern_crate: false,
                     is_macro_use: false,
                 };
-                buf.push(import_data);
+                buf.push((import_data, Either::Left(AstPtr::new(use_tree))));
             },
         );
-        for import_data in buf {
-            self.push_import(current_module, attrs.clone(), import_data);
+        for (import_data, ptr) in buf {
+            self.push_import(current_module, attrs.clone(), import_data, ptr);
         }
     }
 
@@ -343,7 +366,12 @@ impl RawItemsCollector {
                 is_extern_crate: true,
                 is_macro_use,
             };
-            self.push_import(current_module, attrs, import_data);
+            self.push_import(
+                current_module,
+                attrs,
+                import_data,
+                Either::Right(AstPtr::new(&extern_crate)),
+            );
         }
     }
 
@@ -374,8 +402,14 @@ impl RawItemsCollector {
         self.push_item(current_module, attrs, RawItemKind::Impl(imp))
     }
 
-    fn push_import(&mut self, current_module: Option<Module>, attrs: Attrs, data: ImportData) {
-        let import = self.raw_items.imports.alloc(data);
+    fn push_import(
+        &mut self,
+        current_module: Option<Module>,
+        attrs: Attrs,
+        data: ImportData,
+        source: ImportSourcePtr,
+    ) {
+        let import = self.imports.alloc(|| source, || data);
         self.push_item(current_module, attrs, RawItemKind::Import(import))
     }
 
diff --git a/crates/ra_hir_def/src/trace.rs b/crates/ra_hir_def/src/trace.rs
index 9769e88df5..2bcd707bcd 100644
--- a/crates/ra_hir_def/src/trace.rs
+++ b/crates/ra_hir_def/src/trace.rs
@@ -18,6 +18,10 @@ pub(crate) struct Trace<ID: ArenaId, T, V> {
 }
 
 impl<ID: ra_arena::ArenaId + Copy, T, V> Trace<ID, T, V> {
+    pub(crate) fn new() -> Trace<ID, T, V> {
+        Trace { arena: Some(Arena::default()), map: Some(ArenaMap::default()), len: 0 }
+    }
+
     pub(crate) fn new_for_arena() -> Trace<ID, T, V> {
         Trace { arena: Some(Arena::default()), map: None, len: 0 }
     }
@@ -48,4 +52,8 @@ impl<ID: ra_arena::ArenaId + Copy, T, V> Trace<ID, T, V> {
     pub(crate) fn into_map(mut self) -> ArenaMap<ID, V> {
         self.map.take().unwrap()
     }
+
+    pub(crate) fn into_arena_and_map(mut self) -> (Arena<ID, T>, ArenaMap<ID, V>) {
+        (self.arena.take().unwrap(), self.map.take().unwrap())
+    }
 }
diff --git a/crates/ra_hir_expand/src/builtin_macro.rs b/crates/ra_hir_expand/src/builtin_macro.rs
index 2c119269c1..857f8a4441 100644
--- a/crates/ra_hir_expand/src/builtin_macro.rs
+++ b/crates/ra_hir_expand/src/builtin_macro.rs
@@ -26,13 +26,6 @@ macro_rules! register_builtin {
                 };
                 expander(db, id, tt)
             }
-
-            fn by_name(ident: &name::Name) -> Option<BuiltinFnLikeExpander> {
-                match ident {
-                    $( id if id == &name::name![$name] => Some(BuiltinFnLikeExpander::$kind), )*
-                    _ => return None,
-                }
-            }
         }
 
         pub fn find_builtin_macro(
@@ -40,7 +33,10 @@ macro_rules! register_builtin {
             krate: CrateId,
             ast_id: AstId<ast::MacroCall>,
         ) -> Option<MacroDefId> {
-            let kind = BuiltinFnLikeExpander::by_name(ident)?;
+            let kind = match ident {
+                 $( id if id == &name::name![$name] => BuiltinFnLikeExpander::$kind, )*
+                 _ => return None,
+            };
 
             Some(MacroDefId { krate: Some(krate), ast_id: Some(ast_id), kind: MacroDefKind::BuiltIn(kind) })
         }
@@ -54,8 +50,6 @@ register_builtin! {
     (line, Line) => line_expand,
     (stringify, Stringify) => stringify_expand,
     (format_args, FormatArgs) => format_args_expand,
-    (env, Env) => env_expand,
-    (option_env, OptionEnv) => option_env_expand,
     // format_args_nl only differs in that it adds a newline in the end,
     // so we use the same stub expansion for now
     (format_args_nl, FormatArgsNl) => format_args_expand
@@ -127,28 +121,6 @@ fn stringify_expand(
     Ok(expanded)
 }
 
-fn env_expand(
-    _db: &dyn AstDatabase,
-    _id: MacroCallId,
-    _tt: &tt::Subtree,
-) -> Result<tt::Subtree, mbe::ExpandError> {
-    // dummy implementation for type-checking purposes
-    let expanded = quote! { "" };
-
-    Ok(expanded)
-}
-
-fn option_env_expand(
-    _db: &dyn AstDatabase,
-    _id: MacroCallId,
-    _tt: &tt::Subtree,
-) -> Result<tt::Subtree, mbe::ExpandError> {
-    // dummy implementation for type-checking purposes
-    let expanded = quote! { std::option::Option::None::<&str> };
-
-    Ok(expanded)
-}
-
 fn to_col_number(db: &dyn AstDatabase, file: HirFileId, pos: TextUnit) -> usize {
     // FIXME: Use expansion info
     let file_id = file.original_file(db);
@@ -276,11 +248,10 @@ fn format_args_expand(
 #[cfg(test)]
 mod tests {
     use super::*;
-    use crate::{name::AsName, test_db::TestDB, MacroCallKind, MacroCallLoc};
+    use crate::{test_db::TestDB, MacroCallKind, MacroCallLoc};
     use ra_db::{fixture::WithFixture, SourceDatabase};
-    use ra_syntax::ast::NameOwner;
 
-    fn expand_builtin_macro(s: &str) -> String {
+    fn expand_builtin_macro(s: &str, expander: BuiltinFnLikeExpander) -> String {
         let (db, file_id) = TestDB::with_single_file(&s);
         let parsed = db.parse(file_id);
         let macro_calls: Vec<_> =
@@ -288,9 +259,6 @@ mod tests {
 
         let ast_id_map = db.ast_id_map(file_id.into());
 
-        let expander =
-            BuiltinFnLikeExpander::by_name(&macro_calls[0].name().unwrap().as_name()).unwrap();
-
         // the first one should be a macro_rules
         let def = MacroDefId {
             krate: Some(CrateId(0)),
@@ -316,23 +284,25 @@ mod tests {
     fn test_column_expand() {
         let expanded = expand_builtin_macro(
             r#"
-            #[rustc_builtin_macro]
-            macro_rules! column {() => {}}
-            column!()
-            "#,
+        #[rustc_builtin_macro]
+        macro_rules! column {() => {}}
+        column!()
+"#,
+            BuiltinFnLikeExpander::Column,
         );
 
-        assert_eq!(expanded, "13");
+        assert_eq!(expanded, "9");
     }
 
     #[test]
     fn test_line_expand() {
         let expanded = expand_builtin_macro(
             r#"
-            #[rustc_builtin_macro]
-            macro_rules! line {() => {}}
-            line!()
-            "#,
+        #[rustc_builtin_macro]
+        macro_rules! line {() => {}}
+        line!()
+"#,
+            BuiltinFnLikeExpander::Line,
         );
 
         assert_eq!(expanded, "4");
@@ -342,49 +312,25 @@ mod tests {
     fn test_stringify_expand() {
         let expanded = expand_builtin_macro(
             r#"
-            #[rustc_builtin_macro]
-            macro_rules! stringify {() => {}}
-            stringify!(a b c)
-            "#,
+        #[rustc_builtin_macro]
+        macro_rules! stringify {() => {}}
+        stringify!(a b c)
+"#,
+            BuiltinFnLikeExpander::Stringify,
         );
 
         assert_eq!(expanded, "\"a b c\"");
     }
 
-    #[test]
-    fn test_env_expand() {
-        let expanded = expand_builtin_macro(
-            r#"
-            #[rustc_builtin_macro]
-            macro_rules! env {() => {}}
-            env!("TEST_ENV_VAR")
-            "#,
-        );
-
-        assert_eq!(expanded, "\"\"");
-    }
-
-    #[test]
-    fn test_option_env_expand() {
-        let expanded = expand_builtin_macro(
-            r#"
-            #[rustc_builtin_macro]
-            macro_rules! option_env {() => {}}
-            option_env!("TEST_ENV_VAR")
-            "#,
-        );
-
-        assert_eq!(expanded, "std::option::Option::None:: <&str>");
-    }
-
     #[test]
     fn test_file_expand() {
         let expanded = expand_builtin_macro(
             r#"
-            #[rustc_builtin_macro]
-            macro_rules! file {() => {}}
-            file!()
-            "#,
+        #[rustc_builtin_macro]
+        macro_rules! file {() => {}}
+        file!()
+"#,
+            BuiltinFnLikeExpander::File,
         );
 
         assert_eq!(expanded, "\"\"");
@@ -394,13 +340,14 @@ mod tests {
     fn test_compile_error_expand() {
         let expanded = expand_builtin_macro(
             r#"
-            #[rustc_builtin_macro]
-            macro_rules! compile_error {
-                ($msg:expr) => ({ /* compiler built-in */ });
-                ($msg:expr,) => ({ /* compiler built-in */ })
-            }
-            compile_error!("error!");
-            "#,
+        #[rustc_builtin_macro]
+        macro_rules! compile_error {
+            ($msg:expr) => ({ /* compiler built-in */ });
+            ($msg:expr,) => ({ /* compiler built-in */ })
+        }
+        compile_error!("error!");
+"#,
+            BuiltinFnLikeExpander::CompileError,
         );
 
         assert_eq!(expanded, r#"loop{"error!"}"#);
@@ -410,13 +357,14 @@ mod tests {
     fn test_format_args_expand() {
         let expanded = expand_builtin_macro(
             r#"
-            #[rustc_builtin_macro]
-            macro_rules! format_args {
-                ($fmt:expr) => ({ /* compiler built-in */ });
-                ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
-            }
-            format_args!("{} {:?}", arg1(a, b, c), arg2);
-            "#,
+        #[rustc_builtin_macro]
+        macro_rules! format_args {
+            ($fmt:expr) => ({ /* compiler built-in */ });
+            ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
+        }
+        format_args!("{} {:?}", arg1(a, b, c), arg2);
+"#,
+            BuiltinFnLikeExpander::FormatArgs,
         );
 
         assert_eq!(
diff --git a/crates/ra_hir_expand/src/name.rs b/crates/ra_hir_expand/src/name.rs
index e62693b685..fd02ffa4e1 100644
--- a/crates/ra_hir_expand/src/name.rs
+++ b/crates/ra_hir_expand/src/name.rs
@@ -170,8 +170,6 @@ pub mod known {
         stringify,
         format_args,
         format_args_nl,
-        env,
-        option_env,
         // Builtin derives
         Copy,
         Clone,
diff --git a/crates/ra_hir_expand/src/quote.rs b/crates/ra_hir_expand/src/quote.rs
index 4de219ce46..49155fe626 100644
--- a/crates/ra_hir_expand/src/quote.rs
+++ b/crates/ra_hir_expand/src/quote.rs
@@ -102,8 +102,6 @@ macro_rules! __quote {
     ( : ) => {$crate::__quote!(@PUNCT ':')};
     ( :: ) => {$crate::__quote!(@PUNCT ':', ':')};
     ( . ) => {$crate::__quote!(@PUNCT '.')};
-    ( < ) => {$crate::__quote!(@PUNCT '<')};
-    ( > ) => {$crate::__quote!(@PUNCT '>')};
 
     ( $first:tt $($tail:tt)+ ) => {
         {
diff --git a/crates/ra_ide/src/change.rs b/crates/ra_ide/src/change.rs
index 387a9cafb6..4a76d1dd83 100644
--- a/crates/ra_ide/src/change.rs
+++ b/crates/ra_ide/src/change.rs
@@ -270,6 +270,7 @@ impl RootDatabase {
 
         self.query(hir::db::AstIdMapQuery).sweep(sweep);
 
+        self.query(hir::db::RawItemsWithSourceMapQuery).sweep(sweep);
         self.query(hir::db::BodyWithSourceMapQuery).sweep(sweep);
 
         self.query(hir::db::ExprScopesQuery).sweep(sweep);
@@ -308,6 +309,7 @@ impl RootDatabase {
             hir::db::StructDataQuery
             hir::db::EnumDataQuery
             hir::db::TraitDataQuery
+            hir::db::RawItemsWithSourceMapQuery
             hir::db::RawItemsQuery
             hir::db::CrateDefMapQuery
             hir::db::GenericParamsQuery
diff --git a/crates/ra_ide/src/completion/complete_path.rs b/crates/ra_ide/src/completion/complete_path.rs
index cc1f7c8305..28f94e0a77 100644
--- a/crates/ra_ide/src/completion/complete_path.rs
+++ b/crates/ra_ide/src/completion/complete_path.rs
@@ -1,6 +1,7 @@
 //! FIXME: write short doc here
 
-use hir::{Adt, PathResolution, ScopeDef};
+use either::Either;
+use hir::{Adt, HasSource, PathResolution};
 use ra_syntax::AstNode;
 use test_utils::tested_by;
 
@@ -18,15 +19,17 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
     match def {
         hir::ModuleDef::Module(module) => {
             let module_scope = module.scope(ctx.db);
-            for (name, def) in module_scope {
-                if ctx.use_item_syntax.is_some() {
-                    if let hir::ScopeDef::ModuleDef(hir::ModuleDef::BuiltinType(..)) = def {
+            for (name, def, import) in module_scope {
+                if let hir::ScopeDef::ModuleDef(hir::ModuleDef::BuiltinType(..)) = def {
+                    if ctx.use_item_syntax.is_some() {
                         tested_by!(dont_complete_primitive_in_use);
                         continue;
                     }
-                    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 Some(module) == ctx.module {
+                    if let Some(import) = import {
+                        if let Either::Left(use_tree) = import.source(ctx.db).value {
+                            if use_tree.syntax().text_range().contains_inclusive(ctx.offset) {
                                 // for `use self::foo<|>`, don't suggest `foo` as a completion
                                 tested_by!(dont_complete_current_use);
                                 continue;
@@ -34,7 +37,6 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
                         }
                     }
                 }
-
                 acc.add_resolution(ctx, name.to_string(), &def);
             }
         }
diff --git a/crates/ra_ide/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs
index 48d69f7e54..4894ea2f6b 100644
--- a/crates/ra_ide/src/completion/completion_context.rs
+++ b/crates/ra_ide/src/completion/completion_context.rs
@@ -19,7 +19,6 @@ pub(crate) struct CompletionContext<'a> {
     pub(super) offset: TextUnit,
     pub(super) token: SyntaxToken,
     pub(super) module: Option<hir::Module>,
-    pub(super) name_ref_syntax: Option<ast::NameRef>,
     pub(super) function_syntax: Option<ast::FnDef>,
     pub(super) use_item_syntax: Option<ast::UseItem>,
     pub(super) record_lit_syntax: Option<ast::RecordLit>,
@@ -70,7 +69,6 @@ impl<'a> CompletionContext<'a> {
             token,
             offset: position.offset,
             module,
-            name_ref_syntax: None,
             function_syntax: None,
             use_item_syntax: None,
             record_lit_syntax: None,
@@ -144,8 +142,6 @@ impl<'a> CompletionContext<'a> {
     }
 
     fn classify_name_ref(&mut self, original_file: SourceFile, name_ref: ast::NameRef) {
-        self.name_ref_syntax =
-            find_node_at_offset(original_file.syntax(), name_ref.syntax().text_range().start());
         let name_range = name_ref.syntax().text_range();
         if name_ref.syntax().parent().and_then(ast::RecordField::cast).is_some() {
             self.record_lit_syntax = find_node_at_offset(original_file.syntax(), self.offset);
diff --git a/crates/ra_ide/src/inlay_hints.rs b/crates/ra_ide/src/inlay_hints.rs
index c5e4069773..3154df4572 100644
--- a/crates/ra_ide/src/inlay_hints.rs
+++ b/crates/ra_ide/src/inlay_hints.rs
@@ -1,15 +1,12 @@
 //! FIXME: write short doc here
 
+use crate::{db::RootDatabase, FileId};
 use hir::{HirDisplay, SourceAnalyzer};
-use once_cell::unsync::Lazy;
-use ra_prof::profile;
 use ra_syntax::{
     ast::{self, AstNode, TypeAscriptionOwner},
     match_ast, SmolStr, SourceFile, SyntaxKind, SyntaxNode, TextRange,
 };
 
-use crate::{db::RootDatabase, FileId};
-
 #[derive(Debug, PartialEq, Eq)]
 pub enum InlayKind {
     TypeHint,
@@ -30,7 +27,7 @@ pub(crate) fn inlay_hints(
 ) -> Vec<InlayHint> {
     file.syntax()
         .descendants()
-        .flat_map(|node| get_inlay_hints(db, file_id, &node, max_inlay_hint_length))
+        .map(|node| get_inlay_hints(db, file_id, &node, max_inlay_hint_length).unwrap_or_default())
         .flatten()
         .collect()
 }
@@ -41,9 +38,7 @@ fn get_inlay_hints(
     node: &SyntaxNode,
     max_inlay_hint_length: Option<usize>,
 ) -> Option<Vec<InlayHint>> {
-    let _p = profile("get_inlay_hints");
-    let analyzer =
-        Lazy::new(|| SourceAnalyzer::new(db, hir::InFile::new(file_id.into(), node), None));
+    let analyzer = SourceAnalyzer::new(db, hir::InFile::new(file_id.into(), node), None);
     match_ast! {
         match node {
             ast::LetStmt(it) => {
diff --git a/crates/ra_lsp_server/src/caps.rs b/crates/ra_lsp_server/src/caps.rs
index eeca67ee19..d812ff7ca2 100644
--- a/crates/ra_lsp_server/src/caps.rs
+++ b/crates/ra_lsp_server/src/caps.rs
@@ -1,4 +1,4 @@
-//! Advertizes the capabilities of the LSP Server.
+//! FIXME: write short doc here
 
 use lsp_types::{
     CodeActionProviderCapability, CodeLensOptions, CompletionOptions,
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs
index e93d4ea33d..5561f6270b 100644
--- a/crates/ra_lsp_server/src/conv.rs
+++ b/crates/ra_lsp_server/src/conv.rs
@@ -1,4 +1,4 @@
-//! Convenience module responsible for translating between rust-analyzer's types and LSP types.
+//! FIXME: write short doc here
 
 use lsp_types::{
     self, CreateFile, DiagnosticSeverity, DocumentChangeOperation, DocumentChanges, Documentation,
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs
index 81fd08c910..9e207415e6 100644
--- a/crates/ra_lsp_server/src/main_loop.rs
+++ b/crates/ra_lsp_server/src/main_loop.rs
@@ -1,5 +1,4 @@
-//! The main loop of `ra_lsp_server` responsible for dispatching LSP requests/replies and
-//! notifications back to the client.
+//! FIXME: write short doc here
 
 mod handlers;
 mod subscriptions;
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs
index 39eb3df3e5..5e3b1a73f0 100644
--- a/crates/ra_lsp_server/src/main_loop/handlers.rs
+++ b/crates/ra_lsp_server/src/main_loop/handlers.rs
@@ -1,5 +1,4 @@
-//! This module is responsible for implementing handlers for Lanuage Server Protocol.
-//! The majority of requests are fulfilled by calling into the `ra_ide` crate.
+//! FIXME: write short doc here
 
 use std::{fmt::Write as _, io::Write as _};
 
diff --git a/crates/ra_lsp_server/src/main_loop/pending_requests.rs b/crates/ra_lsp_server/src/main_loop/pending_requests.rs
index 2d22134641..e7ea7aa5b8 100644
--- a/crates/ra_lsp_server/src/main_loop/pending_requests.rs
+++ b/crates/ra_lsp_server/src/main_loop/pending_requests.rs
@@ -1,4 +1,4 @@
-//! Datastructures that keep track of inflight requests.
+//! FIXME: write short doc here
 
 use std::time::{Duration, Instant};
 
diff --git a/crates/ra_lsp_server/src/main_loop/subscriptions.rs b/crates/ra_lsp_server/src/main_loop/subscriptions.rs
index b0bae90f5c..609b2adcc9 100644
--- a/crates/ra_lsp_server/src/main_loop/subscriptions.rs
+++ b/crates/ra_lsp_server/src/main_loop/subscriptions.rs
@@ -1,4 +1,4 @@
-//! Keeps track of file subscriptions.
+//! FIXME: write short doc here
 
 use ra_ide::FileId;
 use rustc_hash::FxHashSet;
diff --git a/crates/ra_lsp_server/src/markdown.rs b/crates/ra_lsp_server/src/markdown.rs
index 76bef45ccc..f51fc4ade3 100644
--- a/crates/ra_lsp_server/src/markdown.rs
+++ b/crates/ra_lsp_server/src/markdown.rs
@@ -1,4 +1,4 @@
-//! Transforms markdown
+//! FIXME: write short doc here
 
 pub(crate) fn format_docs(src: &str) -> String {
     let mut processed_lines = Vec::new();
diff --git a/crates/ra_lsp_server/src/req.rs b/crates/ra_lsp_server/src/req.rs
index b34e6f9b89..2a22b655ce 100644
--- a/crates/ra_lsp_server/src/req.rs
+++ b/crates/ra_lsp_server/src/req.rs
@@ -1,4 +1,4 @@
-//! Defines `rust-analyzer` specific custom messages.
+//! FIXME: write short doc here
 
 use lsp_types::{Location, Position, Range, TextDocumentIdentifier, Url};
 use rustc_hash::FxHashMap;
diff --git a/crates/ra_lsp_server/src/world.rs b/crates/ra_lsp_server/src/world.rs
index 5e53b02785..f89b23089e 100644
--- a/crates/ra_lsp_server/src/world.rs
+++ b/crates/ra_lsp_server/src/world.rs
@@ -1,7 +1,4 @@
-//! The context or environment in which the language server functions.
-//! In our server implementation this is know as the `WorldState`.
-//!
-//! Each tick provides an immutable snapshot of the state as `WorldSnapshot`.
+//! FIXME: write short doc here
 
 use std::{
     path::{Path, PathBuf},
diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs
index 3c717e5f9e..6e23d9b72d 100644
--- a/crates/ra_parser/src/grammar/items.rs
+++ b/crates/ra_parser/src/grammar/items.rs
@@ -389,7 +389,7 @@ pub(crate) fn mod_item_list(p: &mut Parser) {
 // macro m($i:ident) {}
 fn macro_def(p: &mut Parser, m: Marker) {
     p.expect(T![macro]);
-    p.expect(IDENT);
+    name_r(p, ITEM_RECOVERY_SET);
     if p.at(T!['{']) {
         token_tree(p);
     } else if !p.at(T!['(']) {


Test patch:
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0147_macro_def.txt b/crates/ra_syntax/test_data/parser/inline/ok/0147_macro_def.txt
index af1122bfa4..3556099bd0 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0147_macro_def.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0147_macro_def.txt
@@ -2,7 +2,8 @@ SOURCE_FILE@[0; 50)
   MACRO_DEF@[0; 28)
     MACRO_KW@[0; 5) "macro"
     WHITESPACE@[5; 6) " "
-    IDENT@[6; 7) "m"
+    NAME@[6; 7)
+      IDENT@[6; 7) "m"
     WHITESPACE@[7; 8) " "
     TOKEN_TREE@[8; 28)
       L_CURLY@[8; 9) "{"
@@ -27,7 +28,8 @@ SOURCE_FILE@[0; 50)
   MACRO_DEF@[29; 49)
     MACRO_KW@[29; 34) "macro"
     WHITESPACE@[34; 35) " "
-    IDENT@[35; 36) "m"
+    NAME@[35; 36)
+      IDENT@[35; 36) "m"
     TOKEN_TREE@[36; 49)
       TOKEN_TREE@[36; 46)
         L_PAREN@[36; 37) "("
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0148_pub_macro_def.txt b/crates/ra_syntax/test_data/parser/inline/ok/0148_pub_macro_def.txt
index 985f61f89e..cfd79d9c26 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0148_pub_macro_def.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0148_pub_macro_def.txt
@@ -5,7 +5,8 @@ SOURCE_FILE@[0; 24)
     WHITESPACE@[3; 4) " "
     MACRO_KW@[4; 9) "macro"
     WHITESPACE@[9; 10) " "
-    IDENT@[10; 11) "m"
+    NAME@[10; 11)
+      IDENT@[10; 11) "m"
     TOKEN_TREE@[11; 23)
       TOKEN_TREE@[11; 20)
         L_PAREN@[11; 12) "("
diff --git a/crates/ra_syntax/test_data/parser/ok/0062_macro_2.0.txt b/crates/ra_syntax/test_data/parser/ok/0062_macro_2.0.txt
index 158af85f55..2be523fc35 100644
--- a/crates/ra_syntax/test_data/parser/ok/0062_macro_2.0.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0062_macro_2.0.txt
@@ -2,7 +2,8 @@ SOURCE_FILE@[0; 349)
   MACRO_DEF@[0; 93)
     MACRO_KW@[0; 5) "macro"
     WHITESPACE@[5; 6) " "
-    IDENT@[6; 21) "parse_use_trees"
+    NAME@[6; 21)
+      IDENT@[6; 21) "parse_use_trees"
     TOKEN_TREE@[21; 93)
       TOKEN_TREE@[21; 41)
         L_PAREN@[21; 22) "("
@@ -75,7 +76,8 @@ SOURCE_FILE@[0; 349)
         MACRO_DEF@[134; 346)
           MACRO_KW@[134; 139) "macro"
           WHITESPACE@[139; 140) " "
-          IDENT@[140; 150) "test_merge"
+          NAME@[140; 150)
+            IDENT@[140; 150) "test_merge"
           TOKEN_TREE@[150; 346)
             TOKEN_TREE@[150; 203)
               L_PAREN@[150; 151) "("