aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock7
-rw-r--r--crates/ra_hir/src/code_model.rs23
-rw-r--r--crates/ra_hir/src/from_source.rs173
-rw-r--r--crates/ra_hir/src/has_source.rs12
-rw-r--r--crates/ra_hir_def/src/adt.rs16
-rw-r--r--crates/ra_hir_def/src/attr.rs13
-rw-r--r--crates/ra_hir_def/src/child_by_source.rs27
-rw-r--r--crates/ra_hir_def/src/data.rs8
-rw-r--r--crates/ra_hir_def/src/db.rs18
-rw-r--r--crates/ra_hir_def/src/docs.rs10
-rw-r--r--crates/ra_hir_def/src/generics.rs12
-rw-r--r--crates/ra_hir_def/src/keys.rs13
-rw-r--r--crates/ra_hir_def/src/lib.rs199
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs39
-rw-r--r--crates/ra_hir_def/src/path.rs110
-rw-r--r--crates/ra_hir_def/src/path/lower_use.rs115
-rw-r--r--crates/ra_hir_def/src/resolver.rs11
-rw-r--r--crates/ra_hir_def/src/src.rs50
-rw-r--r--crates/ra_hir_expand/src/builtin_macro.rs5
-rw-r--r--crates/ra_hir_ty/src/lower.rs9
-rw-r--r--crates/ra_hir_ty/src/method_resolution.rs6
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs8
-rw-r--r--crates/ra_lsp_server/Cargo.toml2
-rw-r--r--crates/ra_lsp_server/src/caps.rs9
-rw-r--r--crates/ra_lsp_server/src/main_loop.rs3
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs5
-rw-r--r--crates/ra_lsp_server/tests/heavy_tests/main.rs21
-rw-r--r--crates/ra_syntax/Cargo.toml7
-rw-r--r--editors/code/src/commands/analyzer_status.ts2
-rw-r--r--editors/code/src/commands/expand_macro.ts2
-rw-r--r--editors/code/src/commands/runnables.ts16
-rw-r--r--editors/code/src/test/utils/diagnotics/SuggestedFix.test.ts3
-rw-r--r--editors/code/src/test/utils/diagnotics/SuggestedFixCollection.test.ts6
-rw-r--r--editors/code/src/test/utils/diagnotics/rust.test.ts6
-rw-r--r--editors/code/tsconfig.json9
-rw-r--r--editors/code/tslint.json4
36 files changed, 535 insertions, 444 deletions
diff --git a/Cargo.lock b/Cargo.lock
index caa52fb69..af874945c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -620,7 +620,7 @@ dependencies = [
620 620
621[[package]] 621[[package]]
622name = "lsp-types" 622name = "lsp-types"
623version = "0.61.0" 623version = "0.63.1"
624source = "registry+https://github.com/rust-lang/crates.io-index" 624source = "registry+https://github.com/rust-lang/crates.io-index"
625dependencies = [ 625dependencies = [
626 "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 626 "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1048,7 +1048,7 @@ dependencies = [
1048 "jod-thread 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1048 "jod-thread 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1049 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 1049 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
1050 "lsp-server 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 1050 "lsp-server 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
1051 "lsp-types 0.61.0 (registry+https://github.com/rust-lang/crates.io-index)", 1051 "lsp-types 0.63.1 (registry+https://github.com/rust-lang/crates.io-index)",
1052 "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", 1052 "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
1053 "ra_ide 0.1.0", 1053 "ra_ide 0.1.0",
1054 "ra_prof 0.1.0", 1054 "ra_prof 0.1.0",
@@ -1123,6 +1123,7 @@ dependencies = [
1123 "rowan 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 1123 "rowan 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
1124 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1124 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
1125 "rustc_lexer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1125 "rustc_lexer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1126 "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
1126 "smol_str 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", 1127 "smol_str 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
1127 "test_utils 0.1.0", 1128 "test_utils 0.1.0",
1128 "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", 1129 "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1839,7 +1840,7 @@ dependencies = [
1839"checksum lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e57b3997725d2b60dbec1297f6c2e2957cc383db1cebd6be812163f969c7d586" 1840"checksum lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e57b3997725d2b60dbec1297f6c2e2957cc383db1cebd6be812163f969c7d586"
1840"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" 1841"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
1841"checksum lsp-server 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ba36405bd742139ab79c246ca5adb7fde2fe1a0f495e2c8e2f607b607dedb12" 1842"checksum lsp-server 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ba36405bd742139ab79c246ca5adb7fde2fe1a0f495e2c8e2f607b607dedb12"
1842"checksum lsp-types 0.61.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa3268fbe8beb2795c2fb327bf44f4f3d24f5fe9ebc18d7e2980afd444d72bcf" 1843"checksum lsp-types 0.63.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70090cea3cd5db0aa923575e03874b33da90c4d0fe1eaf63fa51b8925a78ef03"
1843"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" 1844"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
1844"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" 1845"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
1845"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" 1846"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9"
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index c013ff99b..c705d1630 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -11,7 +11,7 @@ use hir_def::{
11 per_ns::PerNs, 11 per_ns::PerNs,
12 resolver::HasResolver, 12 resolver::HasResolver,
13 type_ref::{Mutability, TypeRef}, 13 type_ref::{Mutability, TypeRef},
14 AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, HasModule, ImplId, 14 AdtId, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, HasModule, ImplId,
15 LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, 15 LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId,
16 StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId, 16 StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId,
17}; 17};
@@ -269,7 +269,7 @@ pub struct Struct {
269 269
270impl Struct { 270impl Struct {
271 pub fn module(self, db: &impl DefDatabase) -> Module { 271 pub fn module(self, db: &impl DefDatabase) -> Module {
272 Module { id: self.id.module(db) } 272 Module { id: self.id.lookup(db).container }
273 } 273 }
274 274
275 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { 275 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
@@ -290,7 +290,7 @@ impl Struct {
290 } 290 }
291 291
292 pub fn ty(self, db: &impl HirDatabase) -> Type { 292 pub fn ty(self, db: &impl HirDatabase) -> Type {
293 Type::from_def(db, self.id.module(db).krate, self.id) 293 Type::from_def(db, self.id.lookup(db).container.krate, self.id)
294 } 294 }
295 295
296 fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { 296 fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
@@ -309,11 +309,11 @@ impl Union {
309 } 309 }
310 310
311 pub fn module(self, db: &impl DefDatabase) -> Module { 311 pub fn module(self, db: &impl DefDatabase) -> Module {
312 Module { id: self.id.module(db) } 312 Module { id: self.id.lookup(db).container }
313 } 313 }
314 314
315 pub fn ty(self, db: &impl HirDatabase) -> Type { 315 pub fn ty(self, db: &impl HirDatabase) -> Type {
316 Type::from_def(db, self.id.module(db).krate, self.id) 316 Type::from_def(db, self.id.lookup(db).container.krate, self.id)
317 } 317 }
318 318
319 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { 319 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
@@ -337,7 +337,7 @@ pub struct Enum {
337 337
338impl Enum { 338impl Enum {
339 pub fn module(self, db: &impl DefDatabase) -> Module { 339 pub fn module(self, db: &impl DefDatabase) -> Module {
340 Module { id: self.id.module(db) } 340 Module { id: self.id.lookup(db).container }
341 } 341 }
342 342
343 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { 343 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
@@ -357,7 +357,7 @@ impl Enum {
357 } 357 }
358 358
359 pub fn ty(self, db: &impl HirDatabase) -> Type { 359 pub fn ty(self, db: &impl HirDatabase) -> Type {
360 Type::from_def(db, self.id.module(db).krate, self.id) 360 Type::from_def(db, self.id.lookup(db).container.krate, self.id)
361 } 361 }
362} 362}
363 363
@@ -577,7 +577,7 @@ pub struct Trait {
577 577
578impl Trait { 578impl Trait {
579 pub fn module(self, db: &impl DefDatabase) -> Module { 579 pub fn module(self, db: &impl DefDatabase) -> Module {
580 Module { id: self.id.module(db) } 580 Module { id: self.id.lookup(db).container }
581 } 581 }
582 582
583 pub fn name(self, db: &impl DefDatabase) -> Name { 583 pub fn name(self, db: &impl DefDatabase) -> Name {
@@ -809,7 +809,10 @@ impl ImplBlock {
809 let resolver = self.id.resolver(db); 809 let resolver = self.id.resolver(db);
810 let environment = TraitEnvironment::lower(db, &resolver); 810 let environment = TraitEnvironment::lower(db, &resolver);
811 let ty = Ty::from_hir(db, &resolver, &impl_data.target_type); 811 let ty = Ty::from_hir(db, &resolver, &impl_data.target_type);
812 Type { krate: self.id.module(db).krate, ty: InEnvironment { value: ty, environment } } 812 Type {
813 krate: self.id.lookup(db).container.krate,
814 ty: InEnvironment { value: ty, environment },
815 }
813 } 816 }
814 817
815 pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> { 818 pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> {
@@ -821,7 +824,7 @@ impl ImplBlock {
821 } 824 }
822 825
823 pub fn module(&self, db: &impl DefDatabase) -> Module { 826 pub fn module(&self, db: &impl DefDatabase) -> Module {
824 self.id.module(db).into() 827 self.id.lookup(db).container.into()
825 } 828 }
826 829
827 pub fn krate(&self, db: &impl DefDatabase) -> Crate { 830 pub fn krate(&self, db: &impl DefDatabase) -> Crate {
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs
index 307f3d5bf..7abb4bd75 100644
--- a/crates/ra_hir/src/from_source.rs
+++ b/crates/ra_hir/src/from_source.rs
@@ -1,7 +1,8 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2use hir_def::{ 2use hir_def::{
3 child_by_source::ChildBySource, dyn_map::DynMap, keys, nameres::ModuleSource, AstItemDef, 3 child_by_source::ChildBySource, dyn_map::DynMap, keys, keys::Key, nameres::ModuleSource,
4 EnumVariantId, GenericDefId, LocationCtx, ModuleId, VariantId, 4 ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, ImplId, ModuleId, StaticId, StructId,
5 TraitId, TypeAliasId, UnionId, VariantId,
5}; 6};
6use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; 7use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind};
7use ra_syntax::{ 8use ra_syntax::{
@@ -20,74 +21,47 @@ pub trait FromSource: Sized {
20 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self>; 21 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self>;
21} 22}
22 23
23impl FromSource for Struct { 24pub trait FromSourceByContainer: Sized {
24 type Ast = ast::StructDef; 25 type Ast: AstNode + 'static;
25 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { 26 type Id: Copy + 'static;
26 let id = from_source(db, src)?; 27 const KEY: Key<Self::Ast, Self::Id>;
27 Some(Struct { id })
28 }
29}
30impl FromSource for Union {
31 type Ast = ast::UnionDef;
32 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> {
33 let id = from_source(db, src)?;
34 Some(Union { id })
35 }
36}
37impl FromSource for Enum {
38 type Ast = ast::EnumDef;
39 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> {
40 let id = from_source(db, src)?;
41 Some(Enum { id })
42 }
43}
44impl FromSource for Trait {
45 type Ast = ast::TraitDef;
46 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> {
47 let id = from_source(db, src)?;
48 Some(Trait { id })
49 }
50}
51impl FromSource for Function {
52 type Ast = ast::FnDef;
53 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> {
54 Container::find(db, src.as_ref().map(|it| it.syntax()))?.child_by_source(db)[keys::FUNCTION]
55 .get(&src)
56 .copied()
57 .map(Function::from)
58 }
59} 28}
60 29
61impl FromSource for Const { 30impl<T: FromSourceByContainer> FromSource for T
62 type Ast = ast::ConstDef; 31where
63 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { 32 T: From<<T as FromSourceByContainer>::Id>,
64 Container::find(db, src.as_ref().map(|it| it.syntax()))?.child_by_source(db)[keys::CONST] 33{
65 .get(&src) 34 type Ast = <T as FromSourceByContainer>::Ast;
66 .copied()
67 .map(Const::from)
68 }
69}
70impl FromSource for Static {
71 type Ast = ast::StaticDef;
72 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { 35 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> {
73 Container::find(db, src.as_ref().map(|it| it.syntax()))?.child_by_source(db)[keys::STATIC] 36 analyze_container(db, src.as_ref().map(|it| it.syntax()))[T::KEY]
74 .get(&src) 37 .get(&src)
75 .copied() 38 .copied()
76 .map(Static::from) 39 .map(Self::from)
77 } 40 }
78} 41}
79 42
80impl FromSource for TypeAlias { 43macro_rules! from_source_by_container_impls {
81 type Ast = ast::TypeAliasDef; 44 ($(($hir:ident, $id:ident, $ast:path, $key:path)),* ,) => {$(
82 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { 45 impl FromSourceByContainer for $hir {
83 Container::find(db, src.as_ref().map(|it| it.syntax()))?.child_by_source(db) 46 type Ast = $ast;
84 [keys::TYPE_ALIAS] 47 type Id = $id;
85 .get(&src) 48 const KEY: Key<Self::Ast, Self::Id> = $key;
86 .copied() 49 }
87 .map(TypeAlias::from) 50 )*}
88 }
89} 51}
90 52
53from_source_by_container_impls![
54 (Struct, StructId, ast::StructDef, keys::STRUCT),
55 (Union, UnionId, ast::UnionDef, keys::UNION),
56 (Enum, EnumId, ast::EnumDef, keys::ENUM),
57 (Trait, TraitId, ast::TraitDef, keys::TRAIT),
58 (Function, FunctionId, ast::FnDef, keys::FUNCTION),
59 (Static, StaticId, ast::StaticDef, keys::STATIC),
60 (Const, ConstId, ast::ConstDef, keys::CONST),
61 (TypeAlias, TypeAliasId, ast::TypeAliasDef, keys::TYPE_ALIAS),
62 (ImplBlock, ImplId, ast::ImplBlock, keys::IMPL),
63];
64
91impl FromSource for MacroDef { 65impl FromSource for MacroDef {
92 type Ast = ast::MacroCall; 66 type Ast = ast::MacroCall;
93 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { 67 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> {
@@ -104,14 +78,6 @@ impl FromSource for MacroDef {
104 } 78 }
105} 79}
106 80
107impl FromSource for ImplBlock {
108 type Ast = ast::ImplBlock;
109 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> {
110 let id = from_source(db, src)?;
111 Some(ImplBlock { id })
112 }
113}
114
115impl FromSource for EnumVariant { 81impl FromSource for EnumVariant {
116 type Ast = ast::EnumVariant; 82 type Ast = ast::EnumVariant;
117 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { 83 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> {
@@ -245,57 +211,30 @@ impl Module {
245 } 211 }
246} 212}
247 213
248fn from_source<N, DEF>(db: &(impl DefDatabase + AstDatabase), src: InFile<N>) -> Option<DEF> 214fn analyze_container(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> DynMap {
249where 215 _analyze_container(db, src).unwrap_or_default()
250 N: AstNode,
251 DEF: AstItemDef<N>,
252{
253 let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax()));
254 let module = Module::from_definition(db, InFile::new(src.file_id, module_src))?;
255 let ctx = LocationCtx::new(db, module.id, src.file_id);
256 let items = db.ast_id_map(src.file_id);
257 let item_id = items.ast_id(&src.value);
258 Some(DEF::from_ast_id(ctx, item_id))
259} 216}
260 217
261enum Container { 218fn _analyze_container(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> Option<DynMap> {
262 Trait(Trait), 219 // FIXME: this doesn't try to handle nested declarations
263 ImplBlock(ImplBlock), 220 for container in src.value.ancestors().skip(1) {
264 Module(Module), 221 let res = match_ast! {
265} 222 match container {
266 223 ast::TraitDef(it) => {
267impl Container { 224 let c = Trait::from_source(db, src.with_value(it))?;
268 fn find(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> Option<Container> { 225 c.id.child_by_source(db)
269 // FIXME: this doesn't try to handle nested declarations 226 },
270 for container in src.value.ancestors() { 227 ast::ImplBlock(it) => {
271 let res = match_ast! { 228 let c = ImplBlock::from_source(db, src.with_value(it))?;
272 match container { 229 c.id.child_by_source(db)
273 ast::TraitDef(it) => { 230 },
274 let c = Trait::from_source(db, src.with_value(it))?; 231 _ => { continue },
275 Container::Trait(c) 232 }
276 }, 233 };
277 ast::ImplBlock(it) => { 234 return Some(res);
278 let c = ImplBlock::from_source(db, src.with_value(it))?;
279 Container::ImplBlock(c)
280 },
281 _ => { continue },
282 }
283 };
284 return Some(res);
285 }
286
287 let module_source = ModuleSource::from_child_node(db, src);
288 let c = Module::from_definition(db, src.with_value(module_source))?;
289 Some(Container::Module(c))
290 } 235 }
291}
292 236
293impl ChildBySource for Container { 237 let module_source = ModuleSource::from_child_node(db, src);
294 fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { 238 let c = Module::from_definition(db, src.with_value(module_source))?;
295 match self { 239 Some(c.id.child_by_source(db))
296 Container::Trait(it) => it.id.child_by_source(db),
297 Container::ImplBlock(it) => it.id.child_by_source(db),
298 Container::Module(it) => it.id.child_by_source(db),
299 }
300 }
301} 240}
diff --git a/crates/ra_hir/src/has_source.rs b/crates/ra_hir/src/has_source.rs
index b09582f93..72afecf26 100644
--- a/crates/ra_hir/src/has_source.rs
+++ b/crates/ra_hir/src/has_source.rs
@@ -4,7 +4,7 @@ use either::Either;
4use hir_def::{ 4use hir_def::{
5 nameres::ModuleSource, 5 nameres::ModuleSource,
6 src::{HasChildSource, HasSource as _}, 6 src::{HasChildSource, HasSource as _},
7 AstItemDef, Lookup, VariantId, 7 Lookup, VariantId,
8}; 8};
9use ra_syntax::ast; 9use ra_syntax::ast;
10 10
@@ -51,19 +51,19 @@ impl HasSource for StructField {
51impl HasSource for Struct { 51impl HasSource for Struct {
52 type Ast = ast::StructDef; 52 type Ast = ast::StructDef;
53 fn source(self, db: &impl DefDatabase) -> InFile<ast::StructDef> { 53 fn source(self, db: &impl DefDatabase) -> InFile<ast::StructDef> {
54 self.id.source(db) 54 self.id.lookup(db).source(db)
55 } 55 }
56} 56}
57impl HasSource for Union { 57impl HasSource for Union {
58 type Ast = ast::UnionDef; 58 type Ast = ast::UnionDef;
59 fn source(self, db: &impl DefDatabase) -> InFile<ast::UnionDef> { 59 fn source(self, db: &impl DefDatabase) -> InFile<ast::UnionDef> {
60 self.id.source(db) 60 self.id.lookup(db).source(db)
61 } 61 }
62} 62}
63impl HasSource for Enum { 63impl HasSource for Enum {
64 type Ast = ast::EnumDef; 64 type Ast = ast::EnumDef;
65 fn source(self, db: &impl DefDatabase) -> InFile<ast::EnumDef> { 65 fn source(self, db: &impl DefDatabase) -> InFile<ast::EnumDef> {
66 self.id.source(db) 66 self.id.lookup(db).source(db)
67 } 67 }
68} 68}
69impl HasSource for EnumVariant { 69impl HasSource for EnumVariant {
@@ -93,7 +93,7 @@ impl HasSource for Static {
93impl HasSource for Trait { 93impl HasSource for Trait {
94 type Ast = ast::TraitDef; 94 type Ast = ast::TraitDef;
95 fn source(self, db: &impl DefDatabase) -> InFile<ast::TraitDef> { 95 fn source(self, db: &impl DefDatabase) -> InFile<ast::TraitDef> {
96 self.id.source(db) 96 self.id.lookup(db).source(db)
97 } 97 }
98} 98}
99impl HasSource for TypeAlias { 99impl HasSource for TypeAlias {
@@ -114,7 +114,7 @@ impl HasSource for MacroDef {
114impl HasSource for ImplBlock { 114impl HasSource for ImplBlock {
115 type Ast = ast::ImplBlock; 115 type Ast = ast::ImplBlock;
116 fn source(self, db: &impl DefDatabase) -> InFile<ast::ImplBlock> { 116 fn source(self, db: &impl DefDatabase) -> InFile<ast::ImplBlock> {
117 self.id.source(db) 117 self.id.lookup(db).source(db)
118 } 118 }
119} 119}
120impl HasSource for Import { 120impl HasSource for Import {
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs
index db3e63ef8..ec3d57d1a 100644
--- a/crates/ra_hir_def/src/adt.rs
+++ b/crates/ra_hir_def/src/adt.rs
@@ -11,8 +11,8 @@ use ra_arena::{map::ArenaMap, Arena};
11use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; 11use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
12 12
13use crate::{ 13use crate::{
14 db::DefDatabase, src::HasChildSource, trace::Trace, type_ref::TypeRef, AstItemDef, EnumId, 14 db::DefDatabase, src::HasChildSource, src::HasSource, trace::Trace, type_ref::TypeRef, EnumId,
15 LocalEnumVariantId, LocalStructFieldId, StructId, UnionId, VariantId, 15 LocalEnumVariantId, LocalStructFieldId, Lookup, StructId, UnionId, VariantId,
16}; 16};
17 17
18/// Note that we use `StructData` for unions as well! 18/// Note that we use `StructData` for unions as well!
@@ -50,14 +50,14 @@ pub struct StructFieldData {
50 50
51impl StructData { 51impl StructData {
52 pub(crate) fn struct_data_query(db: &impl DefDatabase, id: StructId) -> Arc<StructData> { 52 pub(crate) fn struct_data_query(db: &impl DefDatabase, id: StructId) -> Arc<StructData> {
53 let src = id.source(db); 53 let src = id.lookup(db).source(db);
54 let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); 54 let name = src.value.name().map_or_else(Name::missing, |n| n.as_name());
55 let variant_data = VariantData::new(src.value.kind()); 55 let variant_data = VariantData::new(src.value.kind());
56 let variant_data = Arc::new(variant_data); 56 let variant_data = Arc::new(variant_data);
57 Arc::new(StructData { name, variant_data }) 57 Arc::new(StructData { name, variant_data })
58 } 58 }
59 pub(crate) fn union_data_query(db: &impl DefDatabase, id: UnionId) -> Arc<StructData> { 59 pub(crate) fn union_data_query(db: &impl DefDatabase, id: UnionId) -> Arc<StructData> {
60 let src = id.source(db); 60 let src = id.lookup(db).source(db);
61 let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); 61 let name = src.value.name().map_or_else(Name::missing, |n| n.as_name());
62 let variant_data = VariantData::new( 62 let variant_data = VariantData::new(
63 src.value 63 src.value
@@ -72,7 +72,7 @@ impl StructData {
72 72
73impl EnumData { 73impl EnumData {
74 pub(crate) fn enum_data_query(db: &impl DefDatabase, e: EnumId) -> Arc<EnumData> { 74 pub(crate) fn enum_data_query(db: &impl DefDatabase, e: EnumId) -> Arc<EnumData> {
75 let src = e.source(db); 75 let src = e.lookup(db).source(db);
76 let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); 76 let name = src.value.name().map_or_else(Name::missing, |n| n.as_name());
77 let mut trace = Trace::new_for_arena(); 77 let mut trace = Trace::new_for_arena();
78 lower_enum(&mut trace, &src.value); 78 lower_enum(&mut trace, &src.value);
@@ -89,7 +89,7 @@ impl HasChildSource for EnumId {
89 type ChildId = LocalEnumVariantId; 89 type ChildId = LocalEnumVariantId;
90 type Value = ast::EnumVariant; 90 type Value = ast::EnumVariant;
91 fn child_source(&self, db: &impl DefDatabase) -> InFile<ArenaMap<Self::ChildId, Self::Value>> { 91 fn child_source(&self, db: &impl DefDatabase) -> InFile<ArenaMap<Self::ChildId, Self::Value>> {
92 let src = self.source(db); 92 let src = self.lookup(db).source(db);
93 let mut trace = Trace::new_for_map(); 93 let mut trace = Trace::new_for_map();
94 lower_enum(&mut trace, &src.value); 94 lower_enum(&mut trace, &src.value);
95 src.with_value(trace.into_map()) 95 src.with_value(trace.into_map())
@@ -153,8 +153,8 @@ impl HasChildSource for VariantId {
153 let src = it.parent.child_source(db); 153 let src = it.parent.child_source(db);
154 src.map(|map| map[it.local_id].kind()) 154 src.map(|map| map[it.local_id].kind())
155 } 155 }
156 VariantId::StructId(it) => it.source(db).map(|it| it.kind()), 156 VariantId::StructId(it) => it.lookup(db).source(db).map(|it| it.kind()),
157 VariantId::UnionId(it) => it.source(db).map(|it| { 157 VariantId::UnionId(it) => it.lookup(db).source(db).map(|it| {
158 it.record_field_def_list() 158 it.record_field_def_list()
159 .map(ast::StructKind::Record) 159 .map(ast::StructKind::Record)
160 .unwrap_or(ast::StructKind::Unit) 160 .unwrap_or(ast::StructKind::Unit)
diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs
index 2f8f02d82..5bf82e191 100644
--- a/crates/ra_hir_def/src/attr.rs
+++ b/crates/ra_hir_def/src/attr.rs
@@ -12,8 +12,7 @@ use ra_syntax::{
12use tt::Subtree; 12use tt::Subtree;
13 13
14use crate::{ 14use crate::{
15 db::DefDatabase, path::Path, src::HasChildSource, src::HasSource, AdtId, AstItemDef, AttrDefId, 15 db::DefDatabase, path::Path, src::HasChildSource, src::HasSource, AdtId, AttrDefId, Lookup,
16 Lookup,
17}; 16};
18 17
19#[derive(Default, Debug, Clone, PartialEq, Eq)] 18#[derive(Default, Debug, Clone, PartialEq, Eq)]
@@ -56,15 +55,15 @@ impl Attrs {
56 Attrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner)) 55 Attrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner))
57 } 56 }
58 AttrDefId::AdtId(it) => match it { 57 AttrDefId::AdtId(it) => match it {
59 AdtId::StructId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), 58 AdtId::StructId(it) => attrs_from_loc(it.lookup(db), db),
60 AdtId::EnumId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), 59 AdtId::EnumId(it) => attrs_from_loc(it.lookup(db), db),
61 AdtId::UnionId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), 60 AdtId::UnionId(it) => attrs_from_loc(it.lookup(db), db),
62 }, 61 },
63 AttrDefId::TraitId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), 62 AttrDefId::TraitId(it) => attrs_from_loc(it.lookup(db), db),
64 AttrDefId::MacroDefId(it) => { 63 AttrDefId::MacroDefId(it) => {
65 it.ast_id.map_or_else(Default::default, |ast_id| attrs_from_ast(ast_id, db)) 64 it.ast_id.map_or_else(Default::default, |ast_id| attrs_from_ast(ast_id, db))
66 } 65 }
67 AttrDefId::ImplId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), 66 AttrDefId::ImplId(it) => attrs_from_loc(it.lookup(db), db),
68 AttrDefId::ConstId(it) => attrs_from_loc(it.lookup(db), db), 67 AttrDefId::ConstId(it) => attrs_from_loc(it.lookup(db), db),
69 AttrDefId::StaticId(it) => attrs_from_loc(it.lookup(db), db), 68 AttrDefId::StaticId(it) => attrs_from_loc(it.lookup(db), db),
70 AttrDefId::FunctionId(it) => attrs_from_loc(it.lookup(db), db), 69 AttrDefId::FunctionId(it) => attrs_from_loc(it.lookup(db), db),
diff --git a/crates/ra_hir_def/src/child_by_source.rs b/crates/ra_hir_def/src/child_by_source.rs
index a3574a9db..3c9379b15 100644
--- a/crates/ra_hir_def/src/child_by_source.rs
+++ b/crates/ra_hir_def/src/child_by_source.rs
@@ -11,8 +11,8 @@ use crate::{
11 dyn_map::DynMap, 11 dyn_map::DynMap,
12 keys, 12 keys,
13 src::{HasChildSource, HasSource}, 13 src::{HasChildSource, HasSource},
14 AssocItemId, EnumId, EnumVariantId, ImplId, Lookup, ModuleDefId, ModuleId, StructFieldId, 14 AdtId, AssocItemId, EnumId, EnumVariantId, ImplId, Lookup, ModuleDefId, ModuleId,
15 TraitId, VariantId, 15 StructFieldId, TraitId, VariantId,
16}; 16};
17 17
18pub trait ChildBySource { 18pub trait ChildBySource {
@@ -94,10 +94,33 @@ impl ChildBySource for ModuleId {
94 let src = ty.lookup(db).source(db); 94 let src = ty.lookup(db).source(db);
95 res[keys::TYPE_ALIAS].insert(src, ty) 95 res[keys::TYPE_ALIAS].insert(src, ty)
96 } 96 }
97 ModuleDefId::TraitId(trait_) => {
98 let src = trait_.lookup(db).source(db);
99 res[keys::TRAIT].insert(src, trait_)
100 }
101 ModuleDefId::AdtId(adt) => match adt {
102 AdtId::StructId(strukt) => {
103 let src = strukt.lookup(db).source(db);
104 res[keys::STRUCT].insert(src, strukt)
105 }
106 AdtId::UnionId(union_) => {
107 let src = union_.lookup(db).source(db);
108 res[keys::UNION].insert(src, union_)
109 }
110 AdtId::EnumId(enum_) => {
111 let src = enum_.lookup(db).source(db);
112 res[keys::ENUM].insert(src, enum_)
113 }
114 },
97 _ => (), 115 _ => (),
98 } 116 }
99 } 117 }
100 118
119 for &impl_ in crate_def_map[self.local_id].impls.iter() {
120 let src = impl_.lookup(db).source(db);
121 res[keys::IMPL].insert(src, impl_)
122 }
123
101 res 124 res
102 } 125 }
103} 126}
diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs
index 095d7064a..b2dac183e 100644
--- a/crates/ra_hir_def/src/data.rs
+++ b/crates/ra_hir_def/src/data.rs
@@ -12,8 +12,8 @@ use crate::{
12 db::DefDatabase, 12 db::DefDatabase,
13 src::HasSource, 13 src::HasSource,
14 type_ref::{Mutability, TypeRef}, 14 type_ref::{Mutability, TypeRef},
15 AssocItemId, AstItemDef, ConstId, ConstLoc, ContainerId, FunctionId, FunctionLoc, ImplId, 15 AssocItemId, ConstId, ConstLoc, ContainerId, FunctionId, FunctionLoc, ImplId, Intern, Lookup,
16 Intern, Lookup, StaticId, TraitId, TypeAliasId, TypeAliasLoc, 16 StaticId, TraitId, TypeAliasId, TypeAliasLoc,
17}; 17};
18 18
19#[derive(Debug, Clone, PartialEq, Eq)] 19#[derive(Debug, Clone, PartialEq, Eq)]
@@ -94,7 +94,7 @@ pub struct TraitData {
94 94
95impl TraitData { 95impl TraitData {
96 pub(crate) fn trait_data_query(db: &impl DefDatabase, tr: TraitId) -> Arc<TraitData> { 96 pub(crate) fn trait_data_query(db: &impl DefDatabase, tr: TraitId) -> Arc<TraitData> {
97 let src = tr.source(db); 97 let src = tr.lookup(db).source(db);
98 let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); 98 let name = src.value.name().map_or_else(Name::missing, |n| n.as_name());
99 let auto = src.value.is_auto(); 99 let auto = src.value.is_auto();
100 let ast_id_map = db.ast_id_map(src.file_id); 100 let ast_id_map = db.ast_id_map(src.file_id);
@@ -167,7 +167,7 @@ pub struct ImplData {
167 167
168impl ImplData { 168impl ImplData {
169 pub(crate) fn impl_data_query(db: &impl DefDatabase, id: ImplId) -> Arc<ImplData> { 169 pub(crate) fn impl_data_query(db: &impl DefDatabase, id: ImplId) -> Arc<ImplData> {
170 let src = id.source(db); 170 let src = id.lookup(db).source(db);
171 let items = db.ast_id_map(src.file_id); 171 let items = db.ast_id_map(src.file_id);
172 172
173 let target_trait = src.value.target_trait().map(TypeRef::from_ast); 173 let target_trait = src.value.target_trait().map(TypeRef::from_ast);
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs
index ef5611ffc..98bff6cb7 100644
--- a/crates/ra_hir_def/src/db.rs
+++ b/crates/ra_hir_def/src/db.rs
@@ -3,7 +3,7 @@ use std::sync::Arc;
3 3
4use hir_expand::{db::AstDatabase, HirFileId}; 4use hir_expand::{db::AstDatabase, HirFileId};
5use ra_db::{salsa, CrateId, SourceDatabase}; 5use ra_db::{salsa, CrateId, SourceDatabase};
6use ra_syntax::{ast, SmolStr}; 6use ra_syntax::SmolStr;
7 7
8use crate::{ 8use crate::{
9 adt::{EnumData, StructData}, 9 adt::{EnumData, StructData},
@@ -17,9 +17,9 @@ use crate::{
17 raw::{ImportSourceMap, RawItems}, 17 raw::{ImportSourceMap, RawItems},
18 CrateDefMap, 18 CrateDefMap,
19 }, 19 },
20 AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, FunctionId, FunctionLoc, GenericDefId, 20 AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc,
21 ImplId, ItemLoc, ModuleId, StaticId, StaticLoc, StructId, TraitId, TypeAliasId, TypeAliasLoc, 21 GenericDefId, ImplId, ImplLoc, ModuleId, StaticId, StaticLoc, StructId, StructLoc, TraitId,
22 UnionId, 22 TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc,
23}; 23};
24 24
25#[salsa::query_group(InternDatabaseStorage)] 25#[salsa::query_group(InternDatabaseStorage)]
@@ -27,21 +27,21 @@ pub trait InternDatabase: SourceDatabase {
27 #[salsa::interned] 27 #[salsa::interned]
28 fn intern_function(&self, loc: FunctionLoc) -> FunctionId; 28 fn intern_function(&self, loc: FunctionLoc) -> FunctionId;
29 #[salsa::interned] 29 #[salsa::interned]
30 fn intern_struct(&self, loc: ItemLoc<ast::StructDef>) -> StructId; 30 fn intern_struct(&self, loc: StructLoc) -> StructId;
31 #[salsa::interned] 31 #[salsa::interned]
32 fn intern_union(&self, loc: ItemLoc<ast::UnionDef>) -> UnionId; 32 fn intern_union(&self, loc: UnionLoc) -> UnionId;
33 #[salsa::interned] 33 #[salsa::interned]
34 fn intern_enum(&self, loc: ItemLoc<ast::EnumDef>) -> EnumId; 34 fn intern_enum(&self, loc: EnumLoc) -> EnumId;
35 #[salsa::interned] 35 #[salsa::interned]
36 fn intern_const(&self, loc: ConstLoc) -> ConstId; 36 fn intern_const(&self, loc: ConstLoc) -> ConstId;
37 #[salsa::interned] 37 #[salsa::interned]
38 fn intern_static(&self, loc: StaticLoc) -> StaticId; 38 fn intern_static(&self, loc: StaticLoc) -> StaticId;
39 #[salsa::interned] 39 #[salsa::interned]
40 fn intern_trait(&self, loc: ItemLoc<ast::TraitDef>) -> TraitId; 40 fn intern_trait(&self, loc: TraitLoc) -> TraitId;
41 #[salsa::interned] 41 #[salsa::interned]
42 fn intern_type_alias(&self, loc: TypeAliasLoc) -> TypeAliasId; 42 fn intern_type_alias(&self, loc: TypeAliasLoc) -> TypeAliasId;
43 #[salsa::interned] 43 #[salsa::interned]
44 fn intern_impl(&self, loc: ItemLoc<ast::ImplBlock>) -> ImplId; 44 fn intern_impl(&self, loc: ImplLoc) -> ImplId;
45} 45}
46 46
47#[salsa::query_group(DefDatabaseStorage)] 47#[salsa::query_group(DefDatabaseStorage)]
diff --git a/crates/ra_hir_def/src/docs.rs b/crates/ra_hir_def/src/docs.rs
index 61727bd26..b29f142e3 100644
--- a/crates/ra_hir_def/src/docs.rs
+++ b/crates/ra_hir_def/src/docs.rs
@@ -11,7 +11,7 @@ use ra_syntax::ast;
11use crate::{ 11use crate::{
12 db::DefDatabase, 12 db::DefDatabase,
13 src::{HasChildSource, HasSource}, 13 src::{HasChildSource, HasSource},
14 AdtId, AstItemDef, AttrDefId, Lookup, 14 AdtId, AttrDefId, Lookup,
15}; 15};
16 16
17/// Holds documentation 17/// Holds documentation
@@ -51,15 +51,15 @@ impl Documentation {
51 } 51 }
52 } 52 }
53 AttrDefId::AdtId(it) => match it { 53 AttrDefId::AdtId(it) => match it {
54 AdtId::StructId(it) => docs_from_ast(&it.source(db).value), 54 AdtId::StructId(it) => docs_from_ast(&it.lookup(db).source(db).value),
55 AdtId::EnumId(it) => docs_from_ast(&it.source(db).value), 55 AdtId::EnumId(it) => docs_from_ast(&it.lookup(db).source(db).value),
56 AdtId::UnionId(it) => docs_from_ast(&it.source(db).value), 56 AdtId::UnionId(it) => docs_from_ast(&it.lookup(db).source(db).value),
57 }, 57 },
58 AttrDefId::EnumVariantId(it) => { 58 AttrDefId::EnumVariantId(it) => {
59 let src = it.parent.child_source(db); 59 let src = it.parent.child_source(db);
60 docs_from_ast(&src.value[it.local_id]) 60 docs_from_ast(&src.value[it.local_id])
61 } 61 }
62 AttrDefId::TraitId(it) => docs_from_ast(&it.source(db).value), 62 AttrDefId::TraitId(it) => docs_from_ast(&it.lookup(db).source(db).value),
63 AttrDefId::MacroDefId(it) => docs_from_ast(&it.ast_id?.to_node(db)), 63 AttrDefId::MacroDefId(it) => docs_from_ast(&it.ast_id?.to_node(db)),
64 AttrDefId::ConstId(it) => docs_from_ast(&it.lookup(db).source(db).value), 64 AttrDefId::ConstId(it) => docs_from_ast(&it.lookup(db).source(db).value),
65 AttrDefId::StaticId(it) => docs_from_ast(&it.lookup(db).source(db).value), 65 AttrDefId::StaticId(it) => docs_from_ast(&it.lookup(db).source(db).value),
diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs
index 976cf72d0..e502dd798 100644
--- a/crates/ra_hir_def/src/generics.rs
+++ b/crates/ra_hir_def/src/generics.rs
@@ -21,7 +21,7 @@ use crate::{
21 src::HasChildSource, 21 src::HasChildSource,
22 src::HasSource, 22 src::HasSource,
23 type_ref::{TypeBound, TypeRef}, 23 type_ref::{TypeBound, TypeRef},
24 AdtId, AstItemDef, GenericDefId, LocalTypeParamId, Lookup, TypeParamId, 24 AdtId, GenericDefId, LocalTypeParamId, Lookup, TypeParamId,
25}; 25};
26 26
27/// Data about a generic parameter (to a function, struct, impl, ...). 27/// Data about a generic parameter (to a function, struct, impl, ...).
@@ -71,22 +71,22 @@ impl GenericParams {
71 src.file_id 71 src.file_id
72 } 72 }
73 GenericDefId::AdtId(AdtId::StructId(it)) => { 73 GenericDefId::AdtId(AdtId::StructId(it)) => {
74 let src = it.source(db); 74 let src = it.lookup(db).source(db);
75 generics.fill(&mut sm, &src.value); 75 generics.fill(&mut sm, &src.value);
76 src.file_id 76 src.file_id
77 } 77 }
78 GenericDefId::AdtId(AdtId::UnionId(it)) => { 78 GenericDefId::AdtId(AdtId::UnionId(it)) => {
79 let src = it.source(db); 79 let src = it.lookup(db).source(db);
80 generics.fill(&mut sm, &src.value); 80 generics.fill(&mut sm, &src.value);
81 src.file_id 81 src.file_id
82 } 82 }
83 GenericDefId::AdtId(AdtId::EnumId(it)) => { 83 GenericDefId::AdtId(AdtId::EnumId(it)) => {
84 let src = it.source(db); 84 let src = it.lookup(db).source(db);
85 generics.fill(&mut sm, &src.value); 85 generics.fill(&mut sm, &src.value);
86 src.file_id 86 src.file_id
87 } 87 }
88 GenericDefId::TraitId(it) => { 88 GenericDefId::TraitId(it) => {
89 let src = it.source(db); 89 let src = it.lookup(db).source(db);
90 90
91 // traits get the Self type as an implicit first type parameter 91 // traits get the Self type as an implicit first type parameter
92 let self_param_id = 92 let self_param_id =
@@ -109,7 +109,7 @@ impl GenericParams {
109 // type-parameter, but rather is a type-alias for impl's target 109 // type-parameter, but rather is a type-alias for impl's target
110 // type, so this is handled by the resolver. 110 // type, so this is handled by the resolver.
111 GenericDefId::ImplId(it) => { 111 GenericDefId::ImplId(it) => {
112 let src = it.source(db); 112 let src = it.lookup(db).source(db);
113 generics.fill(&mut sm, &src.value); 113 generics.fill(&mut sm, &src.value);
114 src.file_id 114 src.file_id
115 } 115 }
diff --git a/crates/ra_hir_def/src/keys.rs b/crates/ra_hir_def/src/keys.rs
index be702a4f8..d844f7a62 100644
--- a/crates/ra_hir_def/src/keys.rs
+++ b/crates/ra_hir_def/src/keys.rs
@@ -8,16 +8,23 @@ use rustc_hash::FxHashMap;
8 8
9use crate::{ 9use crate::{
10 dyn_map::{DynMap, Policy}, 10 dyn_map::{DynMap, Policy},
11 ConstId, EnumVariantId, FunctionId, StaticId, StructFieldId, TypeAliasId, TypeParamId, 11 ConstId, EnumId, EnumVariantId, FunctionId, ImplId, StaticId, StructFieldId, StructId, TraitId,
12 TypeAliasId, TypeParamId, UnionId,
12}; 13};
13 14
14type Key<K, V> = crate::dyn_map::Key<InFile<K>, V, AstPtrPolicy<K, V>>; 15pub type Key<K, V> = crate::dyn_map::Key<InFile<K>, V, AstPtrPolicy<K, V>>;
15 16
16pub const FUNCTION: Key<ast::FnDef, FunctionId> = Key::new(); 17pub const FUNCTION: Key<ast::FnDef, FunctionId> = Key::new();
17pub const CONST: Key<ast::ConstDef, ConstId> = Key::new(); 18pub const CONST: Key<ast::ConstDef, ConstId> = Key::new();
18pub const STATIC: Key<ast::StaticDef, StaticId> = Key::new(); 19pub const STATIC: Key<ast::StaticDef, StaticId> = Key::new();
19pub const ENUM_VARIANT: Key<ast::EnumVariant, EnumVariantId> = Key::new();
20pub const TYPE_ALIAS: Key<ast::TypeAliasDef, TypeAliasId> = Key::new(); 20pub const TYPE_ALIAS: Key<ast::TypeAliasDef, TypeAliasId> = Key::new();
21pub const IMPL: Key<ast::ImplBlock, ImplId> = Key::new();
22pub const TRAIT: Key<ast::TraitDef, TraitId> = Key::new();
23pub const STRUCT: Key<ast::StructDef, StructId> = Key::new();
24pub const UNION: Key<ast::UnionDef, UnionId> = Key::new();
25pub const ENUM: Key<ast::EnumDef, EnumId> = Key::new();
26
27pub const ENUM_VARIANT: Key<ast::EnumVariant, EnumVariantId> = Key::new();
21pub const TUPLE_FIELD: Key<ast::TupleFieldDef, StructFieldId> = Key::new(); 28pub const TUPLE_FIELD: Key<ast::TupleFieldDef, StructFieldId> = Key::new();
22pub const RECORD_FIELD: Key<ast::RecordFieldDef, StructFieldId> = Key::new(); 29pub const RECORD_FIELD: Key<ast::RecordFieldDef, StructFieldId> = Key::new();
23pub const TYPE_PARAM: Key<ast::TypeParam, TypeParamId> = Key::new(); 30pub const TYPE_PARAM: Key<ast::TypeParam, TypeParamId> = Key::new();
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index 569da4f28..f085bbe87 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -40,14 +40,14 @@ mod test_db;
40#[cfg(test)] 40#[cfg(test)]
41mod marks; 41mod marks;
42 42
43use std::hash::{Hash, Hasher}; 43use std::hash::Hash;
44 44
45use hir_expand::{ast_id_map::FileAstId, db::AstDatabase, AstId, HirFileId, InFile, MacroDefId}; 45use hir_expand::{ast_id_map::FileAstId, AstId, HirFileId, InFile, MacroDefId};
46use ra_arena::{impl_arena_id, RawId}; 46use ra_arena::{impl_arena_id, RawId};
47use ra_db::{impl_intern_key, salsa, CrateId}; 47use ra_db::{impl_intern_key, salsa, CrateId};
48use ra_syntax::{ast, AstNode}; 48use ra_syntax::ast;
49 49
50use crate::{builtin_type::BuiltinType, db::InternDatabase}; 50use crate::builtin_type::BuiltinType;
51 51
52#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 52#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
53pub struct LocalImportId(RawId); 53pub struct LocalImportId(RawId);
@@ -65,63 +65,6 @@ pub struct ModuleId {
65pub struct LocalModuleId(RawId); 65pub struct LocalModuleId(RawId);
66impl_arena_id!(LocalModuleId); 66impl_arena_id!(LocalModuleId);
67 67
68#[derive(Debug)]
69pub struct ItemLoc<N: AstNode> {
70 pub(crate) module: ModuleId,
71 ast_id: AstId<N>,
72}
73
74impl<N: AstNode> PartialEq for ItemLoc<N> {
75 fn eq(&self, other: &Self) -> bool {
76 self.module == other.module && self.ast_id == other.ast_id
77 }
78}
79impl<N: AstNode> Eq for ItemLoc<N> {}
80impl<N: AstNode> Hash for ItemLoc<N> {
81 fn hash<H: Hasher>(&self, hasher: &mut H) {
82 self.module.hash(hasher);
83 self.ast_id.hash(hasher);
84 }
85}
86
87impl<N: AstNode> Clone for ItemLoc<N> {
88 fn clone(&self) -> ItemLoc<N> {
89 ItemLoc { module: self.module, ast_id: self.ast_id }
90 }
91}
92
93#[derive(Clone, Copy)]
94pub struct LocationCtx<DB> {
95 db: DB,
96 module: ModuleId,
97 file_id: HirFileId,
98}
99
100impl<'a, DB> LocationCtx<&'a DB> {
101 pub fn new(db: &'a DB, module: ModuleId, file_id: HirFileId) -> LocationCtx<&'a DB> {
102 LocationCtx { db, module, file_id }
103 }
104}
105
106pub trait AstItemDef<N: AstNode>: salsa::InternKey + Clone {
107 fn intern(db: &impl InternDatabase, loc: ItemLoc<N>) -> Self;
108 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<N>;
109
110 fn from_ast_id(ctx: LocationCtx<&impl InternDatabase>, ast_id: FileAstId<N>) -> Self {
111 let loc = ItemLoc { module: ctx.module, ast_id: AstId::new(ctx.file_id, ast_id) };
112 Self::intern(ctx.db, loc)
113 }
114 fn source(self, db: &(impl AstDatabase + InternDatabase)) -> InFile<N> {
115 let loc = self.lookup_intern(db);
116 let value = loc.ast_id.to_node(db);
117 InFile { file_id: loc.ast_id.file_id, value }
118 }
119 fn module(self, db: &impl InternDatabase) -> ModuleId {
120 let loc = self.lookup_intern(db);
121 loc.module
122 }
123}
124
125#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 68#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
126pub struct FunctionId(salsa::InternId); 69pub struct FunctionId(salsa::InternId);
127impl_intern_key!(FunctionId); 70impl_intern_key!(FunctionId);
@@ -149,36 +92,72 @@ impl Lookup for FunctionId {
149#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 92#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
150pub struct StructId(salsa::InternId); 93pub struct StructId(salsa::InternId);
151impl_intern_key!(StructId); 94impl_intern_key!(StructId);
152impl AstItemDef<ast::StructDef> for StructId { 95
153 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::StructDef>) -> Self { 96#[derive(Debug, Clone, PartialEq, Eq, Hash)]
154 db.intern_struct(loc) 97pub struct StructLoc {
98 pub container: ModuleId,
99 pub ast_id: AstId<ast::StructDef>,
100}
101
102impl Intern for StructLoc {
103 type ID = StructId;
104 fn intern(self, db: &impl db::DefDatabase) -> StructId {
105 db.intern_struct(self)
155 } 106 }
156 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::StructDef> { 107}
157 db.lookup_intern_struct(self) 108
109impl Lookup for StructId {
110 type Data = StructLoc;
111 fn lookup(&self, db: &impl db::DefDatabase) -> StructLoc {
112 db.lookup_intern_struct(*self)
158 } 113 }
159} 114}
160 115
161#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 116#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
162pub struct UnionId(salsa::InternId); 117pub struct UnionId(salsa::InternId);
163impl_intern_key!(UnionId); 118impl_intern_key!(UnionId);
164impl AstItemDef<ast::UnionDef> for UnionId { 119
165 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::UnionDef>) -> Self { 120#[derive(Debug, Clone, PartialEq, Eq, Hash)]
166 db.intern_union(loc) 121pub struct UnionLoc {
122 pub container: ModuleId,
123 pub ast_id: AstId<ast::UnionDef>,
124}
125
126impl Intern for UnionLoc {
127 type ID = UnionId;
128 fn intern(self, db: &impl db::DefDatabase) -> UnionId {
129 db.intern_union(self)
167 } 130 }
168 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::UnionDef> { 131}
169 db.lookup_intern_union(self) 132
133impl Lookup for UnionId {
134 type Data = UnionLoc;
135 fn lookup(&self, db: &impl db::DefDatabase) -> UnionLoc {
136 db.lookup_intern_union(*self)
170 } 137 }
171} 138}
172 139
173#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 140#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
174pub struct EnumId(salsa::InternId); 141pub struct EnumId(salsa::InternId);
175impl_intern_key!(EnumId); 142impl_intern_key!(EnumId);
176impl AstItemDef<ast::EnumDef> for EnumId { 143
177 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::EnumDef>) -> Self { 144#[derive(Debug, Clone, PartialEq, Eq, Hash)]
178 db.intern_enum(loc) 145pub struct EnumLoc {
146 pub container: ModuleId,
147 pub ast_id: AstId<ast::EnumDef>,
148}
149
150impl Intern for EnumLoc {
151 type ID = EnumId;
152 fn intern(self, db: &impl db::DefDatabase) -> EnumId {
153 db.intern_enum(self)
179 } 154 }
180 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::EnumDef> { 155}
181 db.lookup_intern_enum(self) 156
157impl Lookup for EnumId {
158 type Data = EnumLoc;
159 fn lookup(&self, db: &impl db::DefDatabase) -> EnumLoc {
160 db.lookup_intern_enum(*self)
182 } 161 }
183} 162}
184 163
@@ -253,12 +232,24 @@ impl Lookup for StaticId {
253#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 232#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
254pub struct TraitId(salsa::InternId); 233pub struct TraitId(salsa::InternId);
255impl_intern_key!(TraitId); 234impl_intern_key!(TraitId);
256impl AstItemDef<ast::TraitDef> for TraitId { 235
257 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::TraitDef>) -> Self { 236#[derive(Debug, Clone, PartialEq, Eq, Hash)]
258 db.intern_trait(loc) 237pub struct TraitLoc {
238 pub container: ModuleId,
239 pub ast_id: AstId<ast::TraitDef>,
240}
241
242impl Intern for TraitLoc {
243 type ID = TraitId;
244 fn intern(self, db: &impl db::DefDatabase) -> TraitId {
245 db.intern_trait(self)
259 } 246 }
260 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::TraitDef> { 247}
261 db.lookup_intern_trait(self) 248
249impl Lookup for TraitId {
250 type Data = TraitLoc;
251 fn lookup(&self, db: &impl db::DefDatabase) -> TraitLoc {
252 db.lookup_intern_trait(*self)
262 } 253 }
263} 254}
264 255
@@ -289,12 +280,24 @@ impl Lookup for TypeAliasId {
289#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 280#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
290pub struct ImplId(salsa::InternId); 281pub struct ImplId(salsa::InternId);
291impl_intern_key!(ImplId); 282impl_intern_key!(ImplId);
292impl AstItemDef<ast::ImplBlock> for ImplId { 283
293 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::ImplBlock>) -> Self { 284#[derive(Debug, Clone, PartialEq, Eq, Hash)]
294 db.intern_impl(loc) 285pub struct ImplLoc {
286 pub container: ModuleId,
287 pub ast_id: AstId<ast::ImplBlock>,
288}
289
290impl Intern for ImplLoc {
291 type ID = ImplId;
292 fn intern(self, db: &impl db::DefDatabase) -> ImplId {
293 db.intern_impl(self)
295 } 294 }
296 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::ImplBlock> { 295}
297 db.lookup_intern_impl(self) 296
297impl Lookup for ImplId {
298 type Data = ImplLoc;
299 fn lookup(&self, db: &impl db::DefDatabase) -> ImplLoc {
300 db.lookup_intern_impl(*self)
298 } 301 }
299} 302}
300 303
@@ -479,8 +482,8 @@ impl HasModule for FunctionLoc {
479 fn module(&self, db: &impl db::DefDatabase) -> ModuleId { 482 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
480 match self.container { 483 match self.container {
481 ContainerId::ModuleId(it) => it, 484 ContainerId::ModuleId(it) => it,
482 ContainerId::ImplId(it) => it.module(db), 485 ContainerId::ImplId(it) => it.lookup(db).container,
483 ContainerId::TraitId(it) => it.module(db), 486 ContainerId::TraitId(it) => it.lookup(db).container,
484 } 487 }
485 } 488 }
486} 489}
@@ -489,8 +492,8 @@ impl HasModule for TypeAliasLoc {
489 fn module(&self, db: &impl db::DefDatabase) -> ModuleId { 492 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
490 match self.container { 493 match self.container {
491 ContainerId::ModuleId(it) => it, 494 ContainerId::ModuleId(it) => it,
492 ContainerId::ImplId(it) => it.module(db), 495 ContainerId::ImplId(it) => it.lookup(db).container,
493 ContainerId::TraitId(it) => it.module(db), 496 ContainerId::TraitId(it) => it.lookup(db).container,
494 } 497 }
495 } 498 }
496} 499}
@@ -499,8 +502,8 @@ impl HasModule for ConstLoc {
499 fn module(&self, db: &impl db::DefDatabase) -> ModuleId { 502 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
500 match self.container { 503 match self.container {
501 ContainerId::ModuleId(it) => it, 504 ContainerId::ModuleId(it) => it,
502 ContainerId::ImplId(it) => it.module(db), 505 ContainerId::ImplId(it) => it.lookup(db).container,
503 ContainerId::TraitId(it) => it.module(db), 506 ContainerId::TraitId(it) => it.lookup(db).container,
504 } 507 }
505 } 508 }
506} 509}
@@ -508,9 +511,9 @@ impl HasModule for ConstLoc {
508impl HasModule for AdtId { 511impl HasModule for AdtId {
509 fn module(&self, db: &impl db::DefDatabase) -> ModuleId { 512 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
510 match self { 513 match self {
511 AdtId::StructId(it) => it.module(db), 514 AdtId::StructId(it) => it.lookup(db).container,
512 AdtId::UnionId(it) => it.module(db), 515 AdtId::UnionId(it) => it.lookup(db).container,
513 AdtId::EnumId(it) => it.module(db), 516 AdtId::EnumId(it) => it.lookup(db).container,
514 } 517 }
515 } 518 }
516} 519}
@@ -530,10 +533,10 @@ impl HasModule for GenericDefId {
530 match self { 533 match self {
531 GenericDefId::FunctionId(it) => it.lookup(db).module(db), 534 GenericDefId::FunctionId(it) => it.lookup(db).module(db),
532 GenericDefId::AdtId(it) => it.module(db), 535 GenericDefId::AdtId(it) => it.module(db),
533 GenericDefId::TraitId(it) => it.module(db), 536 GenericDefId::TraitId(it) => it.lookup(db).container,
534 GenericDefId::TypeAliasId(it) => it.lookup(db).module(db), 537 GenericDefId::TypeAliasId(it) => it.lookup(db).module(db),
535 GenericDefId::ImplId(it) => it.module(db), 538 GenericDefId::ImplId(it) => it.lookup(db).container,
536 GenericDefId::EnumVariantId(it) => it.parent.module(db), 539 GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container,
537 GenericDefId::ConstId(it) => it.lookup(db).module(db), 540 GenericDefId::ConstId(it) => it.lookup(db).module(db),
538 } 541 }
539 } 542 }
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index a80067979..04aadead1 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -24,9 +24,9 @@ use crate::{
24 }, 24 },
25 path::{Path, PathKind}, 25 path::{Path, PathKind},
26 per_ns::PerNs, 26 per_ns::PerNs,
27 AdtId, AstId, AstItemDef, ConstLoc, ContainerId, EnumId, EnumVariantId, FunctionLoc, ImplId, 27 AdtId, AstId, ConstLoc, ContainerId, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern,
28 Intern, LocalImportId, LocalModuleId, LocationCtx, ModuleDefId, ModuleId, StaticLoc, StructId, 28 LocalImportId, LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, TraitLoc,
29 TraitId, TypeAliasLoc, UnionId, 29 TypeAliasLoc, UnionLoc,
30}; 30};
31 31
32pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { 32pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap {
@@ -661,9 +661,11 @@ where
661 krate: self.def_collector.def_map.krate, 661 krate: self.def_collector.def_map.krate,
662 local_id: self.module_id, 662 local_id: self.module_id,
663 }; 663 };
664 let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id); 664 let ast_id = self.raw_items[imp].ast_id;
665 let imp_id = ImplId::from_ast_id(ctx, self.raw_items[imp].ast_id); 665 let impl_id =
666 self.def_collector.def_map.modules[self.module_id].impls.push(imp_id) 666 ImplLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) }
667 .intern(self.def_collector.db);
668 self.def_collector.def_map.modules[self.module_id].impls.push(impl_id)
667 } 669 }
668 } 670 }
669 } 671 }
@@ -751,8 +753,6 @@ where
751 753
752 fn define_def(&mut self, def: &raw::DefData, attrs: &Attrs) { 754 fn define_def(&mut self, def: &raw::DefData, attrs: &Attrs) {
753 let module = ModuleId { krate: self.def_collector.def_map.krate, local_id: self.module_id }; 755 let module = ModuleId { krate: self.def_collector.def_map.krate, local_id: self.module_id };
754 let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id);
755
756 // FIXME: check attrs to see if this is an attribute macro invocation; 756 // FIXME: check attrs to see if this is an attribute macro invocation;
757 // in which case we don't add the invocation, just a single attribute 757 // in which case we don't add the invocation, just a single attribute
758 // macro invocation 758 // macro invocation
@@ -771,14 +771,20 @@ where
771 PerNs::values(def.into()) 771 PerNs::values(def.into())
772 } 772 }
773 raw::DefKind::Struct(ast_id) => { 773 raw::DefKind::Struct(ast_id) => {
774 let id = StructId::from_ast_id(ctx, ast_id).into(); 774 let def = StructLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) }
775 PerNs::both(id, id) 775 .intern(self.def_collector.db);
776 PerNs::both(def.into(), def.into())
776 } 777 }
777 raw::DefKind::Union(ast_id) => { 778 raw::DefKind::Union(ast_id) => {
778 let id = UnionId::from_ast_id(ctx, ast_id).into(); 779 let def = UnionLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) }
779 PerNs::both(id, id) 780 .intern(self.def_collector.db);
781 PerNs::both(def.into(), def.into())
782 }
783 raw::DefKind::Enum(ast_id) => {
784 let def = EnumLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) }
785 .intern(self.def_collector.db);
786 PerNs::types(def.into())
780 } 787 }
781 raw::DefKind::Enum(ast_id) => PerNs::types(EnumId::from_ast_id(ctx, ast_id).into()),
782 raw::DefKind::Const(ast_id) => { 788 raw::DefKind::Const(ast_id) => {
783 let def = ConstLoc { 789 let def = ConstLoc {
784 container: ContainerId::ModuleId(module), 790 container: ContainerId::ModuleId(module),
@@ -794,7 +800,12 @@ where
794 800
795 PerNs::values(def.into()) 801 PerNs::values(def.into())
796 } 802 }
797 raw::DefKind::Trait(ast_id) => PerNs::types(TraitId::from_ast_id(ctx, ast_id).into()), 803 raw::DefKind::Trait(ast_id) => {
804 let def = TraitLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) }
805 .intern(self.def_collector.db);
806
807 PerNs::types(def.into())
808 }
798 raw::DefKind::TypeAlias(ast_id) => { 809 raw::DefKind::TypeAlias(ast_id) => {
799 let def = TypeAliasLoc { 810 let def = TypeAliasLoc {
800 container: ContainerId::ModuleId(module), 811 container: ContainerId::ModuleId(module),
diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs
index e547b2f03..ec9d13e82 100644
--- a/crates/ra_hir_def/src/path.rs
+++ b/crates/ra_hir_def/src/path.rs
@@ -1,4 +1,5 @@
1//! A desugared representation of paths like `crate::foo` or `<Type as Trait>::bar`. 1//! A desugared representation of paths like `crate::foo` or `<Type as Trait>::bar`.
2mod lower_use;
2 3
3use std::{iter, sync::Arc}; 4use std::{iter, sync::Arc};
4 5
@@ -9,7 +10,7 @@ use hir_expand::{
9}; 10};
10use ra_db::CrateId; 11use ra_db::CrateId;
11use ra_syntax::{ 12use ra_syntax::{
12 ast::{self, NameOwner, TypeAscriptionOwner}, 13 ast::{self, TypeAscriptionOwner},
13 AstNode, 14 AstNode,
14}; 15};
15 16
@@ -28,8 +29,7 @@ pub struct PathSegment {
28} 29}
29 30
30/// Generic arguments to a path segment (e.g. the `i32` in `Option<i32>`). This 31/// Generic arguments to a path segment (e.g. the `i32` in `Option<i32>`). This
31/// can (in the future) also include bindings of associated types, like in 32/// also includes bindings of associated types, like in `Iterator<Item = Foo>`.
32/// `Iterator<Item = Foo>`.
33#[derive(Debug, Clone, PartialEq, Eq, Hash)] 33#[derive(Debug, Clone, PartialEq, Eq, Hash)]
34pub struct GenericArgs { 34pub struct GenericArgs {
35 pub args: Vec<GenericArg>, 35 pub args: Vec<GenericArg>,
@@ -72,7 +72,7 @@ impl Path {
72 mut cb: impl FnMut(Path, &ast::UseTree, bool, Option<Name>), 72 mut cb: impl FnMut(Path, &ast::UseTree, bool, Option<Name>),
73 ) { 73 ) {
74 if let Some(tree) = item_src.value.use_tree() { 74 if let Some(tree) = item_src.value.use_tree() {
75 expand_use_tree(None, tree, hygiene, &mut cb); 75 lower_use::lower_use_tree(None, tree, hygiene, &mut cb);
76 } 76 }
77 } 77 }
78 78
@@ -296,108 +296,6 @@ impl From<Name> for Path {
296 } 296 }
297} 297}
298 298
299fn expand_use_tree(
300 prefix: Option<Path>,
301 tree: ast::UseTree,
302 hygiene: &Hygiene,
303 cb: &mut dyn FnMut(Path, &ast::UseTree, bool, Option<Name>),
304) {
305 if let Some(use_tree_list) = tree.use_tree_list() {
306 let prefix = match tree.path() {
307 // E.g. use something::{{{inner}}};
308 None => prefix,
309 // E.g. `use something::{inner}` (prefix is `None`, path is `something`)
310 // or `use something::{path::{inner::{innerer}}}` (prefix is `something::path`, path is `inner`)
311 Some(path) => match convert_path(prefix, path, hygiene) {
312 Some(it) => Some(it),
313 None => return, // FIXME: report errors somewhere
314 },
315 };
316 for child_tree in use_tree_list.use_trees() {
317 expand_use_tree(prefix.clone(), child_tree, hygiene, cb);
318 }
319 } else {
320 let alias = tree.alias().and_then(|a| a.name()).map(|a| a.as_name());
321 if let Some(ast_path) = tree.path() {
322 // Handle self in a path.
323 // E.g. `use something::{self, <...>}`
324 if ast_path.qualifier().is_none() {
325 if let Some(segment) = ast_path.segment() {
326 if segment.kind() == Some(ast::PathSegmentKind::SelfKw) {
327 if let Some(prefix) = prefix {
328 cb(prefix, &tree, false, alias);
329 return;
330 }
331 }
332 }
333 }
334 if let Some(path) = convert_path(prefix, ast_path, hygiene) {
335 let is_glob = tree.has_star();
336 cb(path, &tree, is_glob, alias)
337 }
338 // FIXME: report errors somewhere
339 // We get here if we do
340 }
341 }
342}
343
344fn convert_path(prefix: Option<Path>, path: ast::Path, hygiene: &Hygiene) -> Option<Path> {
345 let prefix = if let Some(qual) = path.qualifier() {
346 Some(convert_path(prefix, qual, hygiene)?)
347 } else {
348 prefix
349 };
350
351 let segment = path.segment()?;
352 let res = match segment.kind()? {
353 ast::PathSegmentKind::Name(name_ref) => {
354 match hygiene.name_ref_to_name(name_ref) {
355 Either::Left(name) => {
356 // no type args in use
357 let mut res = prefix.unwrap_or_else(|| Path {
358 kind: PathKind::Plain,
359 segments: Vec::with_capacity(1),
360 });
361 res.segments.push(PathSegment {
362 name,
363 args_and_bindings: None, // no type args in use
364 });
365 res
366 }
367 Either::Right(crate_id) => {
368 return Some(Path::from_simple_segments(
369 PathKind::DollarCrate(crate_id),
370 iter::empty(),
371 ))
372 }
373 }
374 }
375 ast::PathSegmentKind::CrateKw => {
376 if prefix.is_some() {
377 return None;
378 }
379 Path::from_simple_segments(PathKind::Crate, iter::empty())
380 }
381 ast::PathSegmentKind::SelfKw => {
382 if prefix.is_some() {
383 return None;
384 }
385 Path::from_simple_segments(PathKind::Self_, iter::empty())
386 }
387 ast::PathSegmentKind::SuperKw => {
388 if prefix.is_some() {
389 return None;
390 }
391 Path::from_simple_segments(PathKind::Super, iter::empty())
392 }
393 ast::PathSegmentKind::Type { .. } => {
394 // not allowed in imports
395 return None;
396 }
397 };
398 Some(res)
399}
400
401pub mod known { 299pub mod known {
402 use hir_expand::name; 300 use hir_expand::name;
403 301
diff --git a/crates/ra_hir_def/src/path/lower_use.rs b/crates/ra_hir_def/src/path/lower_use.rs
new file mode 100644
index 000000000..e2e1f716d
--- /dev/null
+++ b/crates/ra_hir_def/src/path/lower_use.rs
@@ -0,0 +1,115 @@
1//! Lowers a single complex use like `use foo::{bar, baz};` into a list of paths like
2//! `foo::bar`, `foo::baz`;
3
4use std::iter;
5
6use either::Either;
7use hir_expand::{
8 hygiene::Hygiene,
9 name::{AsName, Name},
10};
11use ra_syntax::ast::{self, NameOwner};
12
13use crate::path::{Path, PathKind, PathSegment};
14
15pub(crate) fn lower_use_tree(
16 prefix: Option<Path>,
17 tree: ast::UseTree,
18 hygiene: &Hygiene,
19 cb: &mut dyn FnMut(Path, &ast::UseTree, bool, Option<Name>),
20) {
21 if let Some(use_tree_list) = tree.use_tree_list() {
22 let prefix = match tree.path() {
23 // E.g. use something::{{{inner}}};
24 None => prefix,
25 // E.g. `use something::{inner}` (prefix is `None`, path is `something`)
26 // or `use something::{path::{inner::{innerer}}}` (prefix is `something::path`, path is `inner`)
27 Some(path) => match convert_path(prefix, path, hygiene) {
28 Some(it) => Some(it),
29 None => return, // FIXME: report errors somewhere
30 },
31 };
32 for child_tree in use_tree_list.use_trees() {
33 lower_use_tree(prefix.clone(), child_tree, hygiene, cb);
34 }
35 } else {
36 let alias = tree.alias().and_then(|a| a.name()).map(|a| a.as_name());
37 if let Some(ast_path) = tree.path() {
38 // Handle self in a path.
39 // E.g. `use something::{self, <...>}`
40 if ast_path.qualifier().is_none() {
41 if let Some(segment) = ast_path.segment() {
42 if segment.kind() == Some(ast::PathSegmentKind::SelfKw) {
43 if let Some(prefix) = prefix {
44 cb(prefix, &tree, false, alias);
45 return;
46 }
47 }
48 }
49 }
50 if let Some(path) = convert_path(prefix, ast_path, hygiene) {
51 let is_glob = tree.has_star();
52 cb(path, &tree, is_glob, alias)
53 }
54 // FIXME: report errors somewhere
55 // We get here if we do
56 }
57 }
58}
59
60fn convert_path(prefix: Option<Path>, path: ast::Path, hygiene: &Hygiene) -> Option<Path> {
61 let prefix = if let Some(qual) = path.qualifier() {
62 Some(convert_path(prefix, qual, hygiene)?)
63 } else {
64 prefix
65 };
66
67 let segment = path.segment()?;
68 let res = match segment.kind()? {
69 ast::PathSegmentKind::Name(name_ref) => {
70 match hygiene.name_ref_to_name(name_ref) {
71 Either::Left(name) => {
72 // no type args in use
73 let mut res = prefix.unwrap_or_else(|| Path {
74 kind: PathKind::Plain,
75 segments: Vec::with_capacity(1),
76 });
77 res.segments.push(PathSegment {
78 name,
79 args_and_bindings: None, // no type args in use
80 });
81 res
82 }
83 Either::Right(crate_id) => {
84 return Some(Path::from_simple_segments(
85 PathKind::DollarCrate(crate_id),
86 iter::empty(),
87 ))
88 }
89 }
90 }
91 ast::PathSegmentKind::CrateKw => {
92 if prefix.is_some() {
93 return None;
94 }
95 Path::from_simple_segments(PathKind::Crate, iter::empty())
96 }
97 ast::PathSegmentKind::SelfKw => {
98 if prefix.is_some() {
99 return None;
100 }
101 Path::from_simple_segments(PathKind::Self_, iter::empty())
102 }
103 ast::PathSegmentKind::SuperKw => {
104 if prefix.is_some() {
105 return None;
106 }
107 Path::from_simple_segments(PathKind::Super, iter::empty())
108 }
109 ast::PathSegmentKind::Type { .. } => {
110 // not allowed in imports
111 return None;
112 }
113 };
114 Some(res)
115}
diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs
index 9484a61d5..17b2169d2 100644
--- a/crates/ra_hir_def/src/resolver.rs
+++ b/crates/ra_hir_def/src/resolver.rs
@@ -17,9 +17,9 @@ use crate::{
17 nameres::{BuiltinShadowMode, CrateDefMap}, 17 nameres::{BuiltinShadowMode, CrateDefMap},
18 path::{Path, PathKind}, 18 path::{Path, PathKind},
19 per_ns::PerNs, 19 per_ns::PerNs,
20 AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, 20 AdtId, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId,
21 GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, 21 HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId,
22 StructId, TraitId, TypeAliasId, TypeParamId, VariantId, 22 TypeAliasId, TypeParamId, VariantId,
23}; 23};
24 24
25#[derive(Debug, Clone, Default)] 25#[derive(Debug, Clone, Default)]
@@ -524,7 +524,7 @@ impl HasResolver for ModuleId {
524 524
525impl HasResolver for TraitId { 525impl HasResolver for TraitId {
526 fn resolver(self, db: &impl DefDatabase) -> Resolver { 526 fn resolver(self, db: &impl DefDatabase) -> Resolver {
527 self.module(db).resolver(db).push_generic_params_scope(db, self.into()) 527 self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
528 } 528 }
529} 529}
530 530
@@ -564,7 +564,8 @@ impl HasResolver for TypeAliasId {
564 564
565impl HasResolver for ImplId { 565impl HasResolver for ImplId {
566 fn resolver(self, db: &impl DefDatabase) -> Resolver { 566 fn resolver(self, db: &impl DefDatabase) -> Resolver {
567 self.module(db) 567 self.lookup(db)
568 .container
568 .resolver(db) 569 .resolver(db)
569 .push_generic_params_scope(db, self.into()) 570 .push_generic_params_scope(db, self.into())
570 .push_impl_block_scope(self) 571 .push_impl_block_scope(self)
diff --git a/crates/ra_hir_def/src/src.rs b/crates/ra_hir_def/src/src.rs
index 27caa02cc..20200d1db 100644
--- a/crates/ra_hir_def/src/src.rs
+++ b/crates/ra_hir_def/src/src.rs
@@ -4,7 +4,10 @@ use hir_expand::InFile;
4use ra_arena::map::ArenaMap; 4use ra_arena::map::ArenaMap;
5use ra_syntax::ast; 5use ra_syntax::ast;
6 6
7use crate::{db::DefDatabase, ConstLoc, FunctionLoc, StaticLoc, TypeAliasLoc}; 7use crate::{
8 db::DefDatabase, ConstLoc, EnumLoc, FunctionLoc, ImplLoc, StaticLoc, StructLoc, TraitLoc,
9 TypeAliasLoc, UnionLoc,
10};
8 11
9pub trait HasSource { 12pub trait HasSource {
10 type Value; 13 type Value;
@@ -47,6 +50,51 @@ impl HasSource for StaticLoc {
47 } 50 }
48} 51}
49 52
53impl HasSource for ImplLoc {
54 type Value = ast::ImplBlock;
55
56 fn source(&self, db: &impl DefDatabase) -> InFile<ast::ImplBlock> {
57 let node = self.ast_id.to_node(db);
58 InFile::new(self.ast_id.file_id, node)
59 }
60}
61
62impl HasSource for TraitLoc {
63 type Value = ast::TraitDef;
64
65 fn source(&self, db: &impl DefDatabase) -> InFile<ast::TraitDef> {
66 let node = self.ast_id.to_node(db);
67 InFile::new(self.ast_id.file_id, node)
68 }
69}
70
71impl HasSource for StructLoc {
72 type Value = ast::StructDef;
73
74 fn source(&self, db: &impl DefDatabase) -> InFile<ast::StructDef> {
75 let node = self.ast_id.to_node(db);
76 InFile::new(self.ast_id.file_id, node)
77 }
78}
79
80impl HasSource for UnionLoc {
81 type Value = ast::UnionDef;
82
83 fn source(&self, db: &impl DefDatabase) -> InFile<ast::UnionDef> {
84 let node = self.ast_id.to_node(db);
85 InFile::new(self.ast_id.file_id, node)
86 }
87}
88
89impl HasSource for EnumLoc {
90 type Value = ast::EnumDef;
91
92 fn source(&self, db: &impl DefDatabase) -> InFile<ast::EnumDef> {
93 let node = self.ast_id.to_node(db);
94 InFile::new(self.ast_id.file_id, node)
95 }
96}
97
50pub trait HasChildSource { 98pub trait HasChildSource {
51 type ChildId; 99 type ChildId;
52 type Value; 100 type Value;
diff --git a/crates/ra_hir_expand/src/builtin_macro.rs b/crates/ra_hir_expand/src/builtin_macro.rs
index ec5ace757..be5f3cbe3 100644
--- a/crates/ra_hir_expand/src/builtin_macro.rs
+++ b/crates/ra_hir_expand/src/builtin_macro.rs
@@ -367,6 +367,9 @@ mod tests {
367 BuiltinFnLikeExpander::FormatArgs, 367 BuiltinFnLikeExpander::FormatArgs,
368 ); 368 );
369 369
370 assert_eq!(expanded, r#"std::fmt::Arguments::new_v1(&[] ,&[std::fmt::ArgumentV1::new(&(arg1(a,b,c)),std::fmt::Display::fmt),std::fmt::ArgumentV1::new(&(arg2),std::fmt::Display::fmt),])"#); 370 assert_eq!(
371 expanded,
372 r#"std::fmt::Arguments::new_v1(&[] ,&[std::fmt::ArgumentV1::new(&(arg1(a,b,c)),std::fmt::Display::fmt),std::fmt::ArgumentV1::new(&(arg2),std::fmt::Display::fmt),])"#
373 );
371 } 374 }
372} 375}
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs
index eab91229e..5f795bc02 100644
--- a/crates/ra_hir_ty/src/lower.rs
+++ b/crates/ra_hir_ty/src/lower.rs
@@ -14,7 +14,7 @@ use hir_def::{
14 path::{GenericArg, Path, PathKind, PathSegment}, 14 path::{GenericArg, Path, PathKind, PathSegment},
15 resolver::{HasResolver, Resolver, TypeNs}, 15 resolver::{HasResolver, Resolver, TypeNs},
16 type_ref::{TypeBound, TypeRef}, 16 type_ref::{TypeBound, TypeRef},
17 AdtId, AstItemDef, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, 17 AdtId, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId,
18 LocalStructFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, UnionId, VariantId, 18 LocalStructFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, UnionId, VariantId,
19}; 19};
20use ra_arena::map::ArenaMap; 20use ra_arena::map::ArenaMap;
@@ -698,10 +698,11 @@ impl_froms!(CallableDef: FunctionId, StructId, EnumVariantId);
698impl CallableDef { 698impl CallableDef {
699 pub fn krate(self, db: &impl HirDatabase) -> CrateId { 699 pub fn krate(self, db: &impl HirDatabase) -> CrateId {
700 match self { 700 match self {
701 CallableDef::FunctionId(f) => f.lookup(db).module(db).krate, 701 CallableDef::FunctionId(f) => f.lookup(db).module(db),
702 CallableDef::StructId(s) => s.module(db).krate, 702 CallableDef::StructId(s) => s.lookup(db).container,
703 CallableDef::EnumVariantId(e) => e.parent.module(db).krate, 703 CallableDef::EnumVariantId(e) => e.parent.lookup(db).container,
704 } 704 }
705 .krate
705 } 706 }
706} 707}
707 708
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs
index 7220d6e0a..848e306e9 100644
--- a/crates/ra_hir_ty/src/method_resolution.rs
+++ b/crates/ra_hir_ty/src/method_resolution.rs
@@ -6,8 +6,8 @@ use std::sync::Arc;
6 6
7use arrayvec::ArrayVec; 7use arrayvec::ArrayVec;
8use hir_def::{ 8use hir_def::{
9 lang_item::LangItemTarget, resolver::Resolver, type_ref::Mutability, AssocItemId, AstItemDef, 9 lang_item::LangItemTarget, resolver::Resolver, type_ref::Mutability, AssocItemId, FunctionId,
10 FunctionId, HasModule, ImplId, Lookup, TraitId, 10 HasModule, ImplId, Lookup, TraitId,
11}; 11};
12use hir_expand::name::Name; 12use hir_expand::name::Name;
13use ra_db::CrateId; 13use ra_db::CrateId;
@@ -134,7 +134,7 @@ impl Ty {
134 LangItemTarget::ImplBlockId(it) => Some(it), 134 LangItemTarget::ImplBlockId(it) => Some(it),
135 _ => None, 135 _ => None,
136 }) 136 })
137 .map(|it| it.module(db).krate) 137 .map(|it| it.lookup(db).container.krate)
138 .collect(); 138 .collect();
139 Some(res) 139 Some(res)
140 } 140 }
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index 1e7ff93d5..fc21872b2 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -9,9 +9,7 @@ use chalk_ir::{
9}; 9};
10use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum}; 10use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum};
11 11
12use hir_def::{ 12use hir_def::{AssocItemId, ContainerId, GenericDefId, ImplId, Lookup, TraitId, TypeAliasId};
13 AssocItemId, AstItemDef, ContainerId, GenericDefId, ImplId, Lookup, TraitId, TypeAliasId,
14};
15use ra_db::{ 13use ra_db::{
16 salsa::{InternId, InternKey}, 14 salsa::{InternId, InternKey},
17 CrateId, 15 CrateId,
@@ -593,7 +591,7 @@ pub(crate) fn trait_datum_query(
593 let bound_vars = Substs::bound_vars(&generic_params); 591 let bound_vars = Substs::bound_vars(&generic_params);
594 let flags = chalk_rust_ir::TraitFlags { 592 let flags = chalk_rust_ir::TraitFlags {
595 auto: trait_data.auto, 593 auto: trait_data.auto,
596 upstream: trait_.module(db).krate != krate, 594 upstream: trait_.lookup(db).container.krate != krate,
597 non_enumerable: true, 595 non_enumerable: true,
598 coinductive: false, // only relevant for Chalk testing 596 coinductive: false, // only relevant for Chalk testing
599 // FIXME set these flags correctly 597 // FIXME set these flags correctly
@@ -673,7 +671,7 @@ fn impl_block_datum(
673 let bound_vars = Substs::bound_vars(&generic_params); 671 let bound_vars = Substs::bound_vars(&generic_params);
674 let trait_ref = trait_ref.subst(&bound_vars); 672 let trait_ref = trait_ref.subst(&bound_vars);
675 let trait_ = trait_ref.trait_; 673 let trait_ = trait_ref.trait_;
676 let impl_type = if impl_id.module(db).krate == krate { 674 let impl_type = if impl_id.lookup(db).container.krate == krate {
677 chalk_rust_ir::ImplType::Local 675 chalk_rust_ir::ImplType::Local
678 } else { 676 } else {
679 chalk_rust_ir::ImplType::External 677 chalk_rust_ir::ImplType::External
diff --git a/crates/ra_lsp_server/Cargo.toml b/crates/ra_lsp_server/Cargo.toml
index 41672eaff..e29b688fd 100644
--- a/crates/ra_lsp_server/Cargo.toml
+++ b/crates/ra_lsp_server/Cargo.toml
@@ -14,7 +14,7 @@ serde_json = "1.0.34"
14serde = { version = "1.0.83", features = ["derive"] } 14serde = { version = "1.0.83", features = ["derive"] }
15crossbeam-channel = "0.4" 15crossbeam-channel = "0.4"
16log = "0.4.3" 16log = "0.4.3"
17lsp-types = { version = "0.61.0", features = ["proposed"] } 17lsp-types = { version = "0.63.1", features = ["proposed"] }
18rustc-hash = "1.0" 18rustc-hash = "1.0"
19parking_lot = "0.10.0" 19parking_lot = "0.10.0"
20jod-thread = "0.1.0" 20jod-thread = "0.1.0"
diff --git a/crates/ra_lsp_server/src/caps.rs b/crates/ra_lsp_server/src/caps.rs
index eea0965ed..e0bb75666 100644
--- a/crates/ra_lsp_server/src/caps.rs
+++ b/crates/ra_lsp_server/src/caps.rs
@@ -5,7 +5,7 @@ use lsp_types::{
5 DocumentOnTypeFormattingOptions, FoldingRangeProviderCapability, GenericCapability, 5 DocumentOnTypeFormattingOptions, FoldingRangeProviderCapability, GenericCapability,
6 ImplementationProviderCapability, RenameOptions, RenameProviderCapability, ServerCapabilities, 6 ImplementationProviderCapability, RenameOptions, RenameProviderCapability, ServerCapabilities,
7 SignatureHelpOptions, TextDocumentSyncCapability, TextDocumentSyncKind, 7 SignatureHelpOptions, TextDocumentSyncCapability, TextDocumentSyncKind,
8 TextDocumentSyncOptions, TypeDefinitionProviderCapability, 8 TextDocumentSyncOptions, TypeDefinitionProviderCapability, WorkDoneProgressOptions,
9}; 9};
10 10
11pub fn server_capabilities() -> ServerCapabilities { 11pub fn server_capabilities() -> ServerCapabilities {
@@ -21,10 +21,14 @@ pub fn server_capabilities() -> ServerCapabilities {
21 completion_provider: Some(CompletionOptions { 21 completion_provider: Some(CompletionOptions {
22 resolve_provider: None, 22 resolve_provider: None,
23 trigger_characters: Some(vec![":".to_string(), ".".to_string()]), 23 trigger_characters: Some(vec![":".to_string(), ".".to_string()]),
24 work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None },
24 }), 25 }),
25 signature_help_provider: Some(SignatureHelpOptions { 26 signature_help_provider: Some(SignatureHelpOptions {
26 trigger_characters: Some(vec!["(".to_string(), ",".to_string(), ")".to_string()]), 27 trigger_characters: Some(vec!["(".to_string(), ",".to_string()]),
28 retrigger_characters: None,
29 work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None },
27 }), 30 }),
31 declaration_provider: None,
28 definition_provider: Some(true), 32 definition_provider: Some(true),
29 type_definition_provider: Some(TypeDefinitionProviderCapability::Simple(true)), 33 type_definition_provider: Some(TypeDefinitionProviderCapability::Simple(true)),
30 implementation_provider: Some(ImplementationProviderCapability::Simple(true)), 34 implementation_provider: Some(ImplementationProviderCapability::Simple(true)),
@@ -44,6 +48,7 @@ pub fn server_capabilities() -> ServerCapabilities {
44 folding_range_provider: Some(FoldingRangeProviderCapability::Simple(true)), 48 folding_range_provider: Some(FoldingRangeProviderCapability::Simple(true)),
45 rename_provider: Some(RenameProviderCapability::Options(RenameOptions { 49 rename_provider: Some(RenameProviderCapability::Options(RenameOptions {
46 prepare_provider: Some(true), 50 prepare_provider: Some(true),
51 work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None },
47 })), 52 })),
48 document_link_provider: None, 53 document_link_provider: None,
49 color_provider: None, 54 color_provider: None,
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs
index 83845f1e0..158cac0be 100644
--- a/crates/ra_lsp_server/src/main_loop.rs
+++ b/crates/ra_lsp_server/src/main_loop.rs
@@ -520,7 +520,8 @@ fn on_notification(
520 if let Some(file_id) = state.vfs.write().remove_file_overlay(path.as_path()) { 520 if let Some(file_id) = state.vfs.write().remove_file_overlay(path.as_path()) {
521 subs.remove_sub(FileId(file_id.0)); 521 subs.remove_sub(FileId(file_id.0));
522 } 522 }
523 let params = req::PublishDiagnosticsParams { uri, diagnostics: Vec::new() }; 523 let params =
524 req::PublishDiagnosticsParams { uri, diagnostics: Vec::new(), version: None };
524 let not = notification_new::<req::PublishDiagnostics>(params); 525 let not = notification_new::<req::PublishDiagnostics>(params);
525 msg_sender.send(not.into()).unwrap(); 526 msg_sender.send(not.into()).unwrap();
526 return Ok(()); 527 return Ok(());
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs
index 409583634..5b64b27cd 100644
--- a/crates/ra_lsp_server/src/main_loop/handlers.rs
+++ b/crates/ra_lsp_server/src/main_loop/handlers.rs
@@ -648,6 +648,7 @@ pub fn handle_code_action(
648 diagnostics: None, 648 diagnostics: None,
649 edit: None, 649 edit: None,
650 command: Some(command), 650 command: Some(command),
651 is_preferred: None,
651 }; 652 };
652 res.push(action.into()); 653 res.push(action.into());
653 } 654 }
@@ -670,6 +671,7 @@ pub fn handle_code_action(
670 diagnostics: None, 671 diagnostics: None,
671 edit: None, 672 edit: None,
672 command: Some(command), 673 command: Some(command),
674 is_preferred: None,
673 }; 675 };
674 res.push(action.into()); 676 res.push(action.into());
675 } 677 }
@@ -828,9 +830,10 @@ pub fn publish_diagnostics(
828 source: Some("rust-analyzer".to_string()), 830 source: Some("rust-analyzer".to_string()),
829 message: d.message, 831 message: d.message,
830 related_information: None, 832 related_information: None,
833 tags: None,
831 }) 834 })
832 .collect(); 835 .collect();
833 Ok(req::PublishDiagnosticsParams { uri, diagnostics }) 836 Ok(req::PublishDiagnosticsParams { uri, diagnostics, version: None })
834} 837}
835 838
836pub fn publish_decorations( 839pub fn publish_decorations(
diff --git a/crates/ra_lsp_server/tests/heavy_tests/main.rs b/crates/ra_lsp_server/tests/heavy_tests/main.rs
index cfbf16ea5..dff63a12d 100644
--- a/crates/ra_lsp_server/tests/heavy_tests/main.rs
+++ b/crates/ra_lsp_server/tests/heavy_tests/main.rs
@@ -4,7 +4,8 @@ use std::{collections::HashMap, time::Instant};
4 4
5use lsp_types::{ 5use lsp_types::{
6 CodeActionContext, DidOpenTextDocumentParams, DocumentFormattingParams, FormattingOptions, 6 CodeActionContext, DidOpenTextDocumentParams, DocumentFormattingParams, FormattingOptions,
7 Position, Range, TextDocumentItem, TextDocumentPositionParams, 7 PartialResultParams, Position, Range, TextDocumentItem, TextDocumentPositionParams,
8 WorkDoneProgressParams,
8}; 9};
9use ra_lsp_server::req::{ 10use ra_lsp_server::req::{
10 CodeActionParams, CodeActionRequest, Completion, CompletionParams, DidOpenTextDocument, 11 CodeActionParams, CodeActionRequest, Completion, CompletionParams, DidOpenTextDocument,
@@ -48,6 +49,8 @@ use std::collections::Spam;
48 Position::new(0, 23), 49 Position::new(0, 23),
49 ), 50 ),
50 context: None, 51 context: None,
52 partial_result_params: PartialResultParams::default(),
53 work_done_progress_params: WorkDoneProgressParams::default(),
51 }); 54 });
52 assert!(format!("{}", res).contains("HashMap")); 55 assert!(format!("{}", res).contains("HashMap"));
53 eprintln!("completion took {:?}", completion_start.elapsed()); 56 eprintln!("completion took {:?}", completion_start.elapsed());
@@ -211,8 +214,12 @@ pub use std::collections::HashMap;
211 options: FormattingOptions { 214 options: FormattingOptions {
212 tab_size: 4, 215 tab_size: 4,
213 insert_spaces: false, 216 insert_spaces: false,
217 insert_final_newline: None,
218 trim_final_newlines: None,
219 trim_trailing_whitespace: None,
214 properties: HashMap::new(), 220 properties: HashMap::new(),
215 }, 221 },
222 work_done_progress_params: WorkDoneProgressParams::default(),
216 }, 223 },
217 json!([ 224 json!([
218 { 225 {
@@ -272,7 +279,11 @@ pub use std::collections::HashMap;
272 tab_size: 4, 279 tab_size: 4,
273 insert_spaces: false, 280 insert_spaces: false,
274 properties: HashMap::new(), 281 properties: HashMap::new(),
282 insert_final_newline: None,
283 trim_final_newlines: None,
284 trim_trailing_whitespace: None,
275 }, 285 },
286 work_done_progress_params: WorkDoneProgressParams::default(),
276 }, 287 },
277 json!([ 288 json!([
278 { 289 {
@@ -325,6 +336,8 @@ fn main() {}
325 text_document: server.doc_id("src/lib.rs"), 336 text_document: server.doc_id("src/lib.rs"),
326 range: Range::new(Position::new(0, 4), Position::new(0, 7)), 337 range: Range::new(Position::new(0, 4), Position::new(0, 7)),
327 context: empty_context(), 338 context: empty_context(),
339 partial_result_params: PartialResultParams::default(),
340 work_done_progress_params: WorkDoneProgressParams::default(),
328 }, 341 },
329 json!([ 342 json!([
330 { 343 {
@@ -356,6 +369,8 @@ fn main() {}
356 text_document: server.doc_id("src/lib.rs"), 369 text_document: server.doc_id("src/lib.rs"),
357 range: Range::new(Position::new(2, 4), Position::new(2, 7)), 370 range: Range::new(Position::new(2, 4), Position::new(2, 7)),
358 context: empty_context(), 371 context: empty_context(),
372 partial_result_params: PartialResultParams::default(),
373 work_done_progress_params: WorkDoneProgressParams::default(),
359 }, 374 },
360 json!([]), 375 json!([]),
361 ); 376 );
@@ -404,6 +419,8 @@ fn main() {{}}
404 text_document: server.doc_id("src/lib.rs"), 419 text_document: server.doc_id("src/lib.rs"),
405 range: Range::new(Position::new(0, 4), Position::new(0, 7)), 420 range: Range::new(Position::new(0, 4), Position::new(0, 7)),
406 context: empty_context(), 421 context: empty_context(),
422 partial_result_params: PartialResultParams::default(),
423 work_done_progress_params: WorkDoneProgressParams::default(),
407 }, 424 },
408 json!([ 425 json!([
409 { 426 {
@@ -435,6 +452,8 @@ fn main() {{}}
435 text_document: server.doc_id("src/lib.rs"), 452 text_document: server.doc_id("src/lib.rs"),
436 range: Range::new(Position::new(2, 4), Position::new(2, 7)), 453 range: Range::new(Position::new(2, 4), Position::new(2, 7)),
437 context: empty_context(), 454 context: empty_context(),
455 partial_result_params: PartialResultParams::default(),
456 work_done_progress_params: WorkDoneProgressParams::default(),
438 }, 457 },
439 json!([]), 458 json!([]),
440 ); 459 );
diff --git a/crates/ra_syntax/Cargo.toml b/crates/ra_syntax/Cargo.toml
index 1c0b184e1..b6ebb129d 100644
--- a/crates/ra_syntax/Cargo.toml
+++ b/crates/ra_syntax/Cargo.toml
@@ -18,13 +18,14 @@ rustc-hash = "1.0.1"
18arrayvec = "0.5.1" 18arrayvec = "0.5.1"
19once_cell = "1.2.0" 19once_cell = "1.2.0"
20 20
21ra_text_edit = { path = "../ra_text_edit" }
22ra_parser = { path = "../ra_parser" }
23
21# This crate transitively depends on `smol_str` via `rowan`. 24# This crate transitively depends on `smol_str` via `rowan`.
22# ideally, `serde` should be enabled by `ra_lsp_server`, but we enable it here 25# ideally, `serde` should be enabled by `ra_lsp_server`, but we enable it here
23# to reduce number of compilations 26# to reduce number of compilations
24smol_str = { version = "0.1.12", features = ["serde"] } 27smol_str = { version = "0.1.12", features = ["serde"] }
25 28serde = { version = "1", features = ["derive"] }
26ra_text_edit = { path = "../ra_text_edit" }
27ra_parser = { path = "../ra_parser" }
28 29
29[dev-dependencies] 30[dev-dependencies]
30test_utils = { path = "../test_utils" } 31test_utils = { path = "../test_utils" }
diff --git a/editors/code/src/commands/analyzer_status.ts b/editors/code/src/commands/analyzer_status.ts
index 9e4ce0eb3..2777ced24 100644
--- a/editors/code/src/commands/analyzer_status.ts
+++ b/editors/code/src/commands/analyzer_status.ts
@@ -9,7 +9,7 @@ export class TextDocumentContentProvider
9 public syntaxTree: string = 'Not available'; 9 public syntaxTree: string = 'Not available';
10 10
11 public provideTextDocumentContent( 11 public provideTextDocumentContent(
12 uri: vscode.Uri, 12 _uri: vscode.Uri,
13 ): vscode.ProviderResult<string> { 13 ): vscode.ProviderResult<string> {
14 const editor = vscode.window.activeTextEditor; 14 const editor = vscode.window.activeTextEditor;
15 if (editor == null) { 15 if (editor == null) {
diff --git a/editors/code/src/commands/expand_macro.ts b/editors/code/src/commands/expand_macro.ts
index 842898020..17c78280a 100644
--- a/editors/code/src/commands/expand_macro.ts
+++ b/editors/code/src/commands/expand_macro.ts
@@ -11,7 +11,7 @@ export class ExpandMacroContentProvider
11 public eventEmitter = new vscode.EventEmitter<vscode.Uri>(); 11 public eventEmitter = new vscode.EventEmitter<vscode.Uri>();
12 12
13 public provideTextDocumentContent( 13 public provideTextDocumentContent(
14 uri: vscode.Uri, 14 _uri: vscode.Uri,
15 ): vscode.ProviderResult<string> { 15 ): vscode.ProviderResult<string> {
16 async function handle() { 16 async function handle() {
17 const editor = vscode.window.activeTextEditor; 17 const editor = vscode.window.activeTextEditor;
diff --git a/editors/code/src/commands/runnables.ts b/editors/code/src/commands/runnables.ts
index 9b1c6643d..cf980e257 100644
--- a/editors/code/src/commands/runnables.ts
+++ b/editors/code/src/commands/runnables.ts
@@ -73,7 +73,7 @@ function createTask(spec: Runnable): vscode.Task {
73} 73}
74 74
75let prevRunnable: RunnableQuickPick | undefined; 75let prevRunnable: RunnableQuickPick | undefined;
76export async function handle() { 76export async function handle(): Promise<vscode.TaskExecution | undefined> {
77 const editor = vscode.window.activeTextEditor; 77 const editor = vscode.window.activeTextEditor;
78 if (editor == null || editor.document.languageId !== 'rust') { 78 if (editor == null || editor.document.languageId !== 'rust') {
79 return; 79 return;
@@ -105,12 +105,14 @@ export async function handle() {
105 items.push(new RunnableQuickPick(r)); 105 items.push(new RunnableQuickPick(r));
106 } 106 }
107 const item = await vscode.window.showQuickPick(items); 107 const item = await vscode.window.showQuickPick(items);
108 if (item) { 108 if (!item) {
109 item.detail = 'rerun'; 109 return;
110 prevRunnable = item;
111 const task = createTask(item.runnable);
112 return await vscode.tasks.executeTask(task);
113 } 110 }
111
112 item.detail = 'rerun';
113 prevRunnable = item;
114 const task = createTask(item.runnable);
115 return await vscode.tasks.executeTask(task);
114} 116}
115 117
116export async function handleSingle(runnable: Runnable) { 118export async function handleSingle(runnable: Runnable) {
@@ -178,7 +180,7 @@ export async function startCargoWatch(
178 } 180 }
179 181
180 const label = 'install-cargo-watch'; 182 const label = 'install-cargo-watch';
181 const taskFinished = new Promise((resolve, reject) => { 183 const taskFinished = new Promise((resolve, _reject) => {
182 const disposable = vscode.tasks.onDidEndTask(({ execution }) => { 184 const disposable = vscode.tasks.onDidEndTask(({ execution }) => {
183 if (execution.task.name === label) { 185 if (execution.task.name === label) {
184 disposable.dispose(); 186 disposable.dispose();
diff --git a/editors/code/src/test/utils/diagnotics/SuggestedFix.test.ts b/editors/code/src/test/utils/diagnotics/SuggestedFix.test.ts
index 96ec8c614..2b25eb705 100644
--- a/editors/code/src/test/utils/diagnotics/SuggestedFix.test.ts
+++ b/editors/code/src/test/utils/diagnotics/SuggestedFix.test.ts
@@ -114,7 +114,8 @@ describe('SuggestedFix', () => {
114 114
115 const edit = codeAction.edit; 115 const edit = codeAction.edit;
116 if (!edit) { 116 if (!edit) {
117 return assert.fail('Code Action edit unexpectedly missing'); 117 assert.fail('Code Action edit unexpectedly missing');
118 return;
118 } 119 }
119 120
120 const editEntries = edit.entries(); 121 const editEntries = edit.entries();
diff --git a/editors/code/src/test/utils/diagnotics/SuggestedFixCollection.test.ts b/editors/code/src/test/utils/diagnotics/SuggestedFixCollection.test.ts
index 4c1467b57..ef09013f4 100644
--- a/editors/code/src/test/utils/diagnotics/SuggestedFixCollection.test.ts
+++ b/editors/code/src/test/utils/diagnotics/SuggestedFixCollection.test.ts
@@ -53,7 +53,8 @@ describe('SuggestedFixCollection', () => {
53 53
54 const { diagnostics } = codeAction; 54 const { diagnostics } = codeAction;
55 if (!diagnostics) { 55 if (!diagnostics) {
56 return assert.fail('Diagnostics unexpectedly missing'); 56 assert.fail('Diagnostics unexpectedly missing');
57 return;
57 } 58 }
58 59
59 assert.strictEqual(diagnostics.length, 1); 60 assert.strictEqual(diagnostics.length, 1);
@@ -114,7 +115,8 @@ describe('SuggestedFixCollection', () => {
114 const { diagnostics } = codeAction; 115 const { diagnostics } = codeAction;
115 116
116 if (!diagnostics) { 117 if (!diagnostics) {
117 return assert.fail('Diagnostics unexpectedly missing'); 118 assert.fail('Diagnostics unexpectedly missing');
119 return;
118 } 120 }
119 121
120 // We should be associated with both diagnostics 122 // We should be associated with both diagnostics
diff --git a/editors/code/src/test/utils/diagnotics/rust.test.ts b/editors/code/src/test/utils/diagnotics/rust.test.ts
index cee59061f..0222dbbaa 100644
--- a/editors/code/src/test/utils/diagnotics/rust.test.ts
+++ b/editors/code/src/test/utils/diagnotics/rust.test.ts
@@ -120,7 +120,8 @@ describe('mapRustDiagnosticToVsCode', () => {
120 // One related information for the original definition 120 // One related information for the original definition
121 const relatedInformation = diagnostic.relatedInformation; 121 const relatedInformation = diagnostic.relatedInformation;
122 if (!relatedInformation) { 122 if (!relatedInformation) {
123 return assert.fail('Related information unexpectedly undefined'); 123 assert.fail('Related information unexpectedly undefined');
124 return;
124 } 125 }
125 assert.strictEqual(relatedInformation.length, 1); 126 assert.strictEqual(relatedInformation.length, 1);
126 const [related] = relatedInformation; 127 const [related] = relatedInformation;
@@ -154,7 +155,8 @@ describe('mapRustDiagnosticToVsCode', () => {
154 // One related information for the lint definition 155 // One related information for the lint definition
155 const relatedInformation = diagnostic.relatedInformation; 156 const relatedInformation = diagnostic.relatedInformation;
156 if (!relatedInformation) { 157 if (!relatedInformation) {
157 return assert.fail('Related information unexpectedly undefined'); 158 assert.fail('Related information unexpectedly undefined');
159 return;
158 } 160 }
159 assert.strictEqual(relatedInformation.length, 1); 161 assert.strictEqual(relatedInformation.length, 1);
160 const [related] = relatedInformation; 162 const [related] = relatedInformation;
diff --git a/editors/code/tsconfig.json b/editors/code/tsconfig.json
index 9ad2e967b..5e11c3775 100644
--- a/editors/code/tsconfig.json
+++ b/editors/code/tsconfig.json
@@ -1,13 +1,16 @@
1{ 1{
2 "compilerOptions": { 2 "compilerOptions": {
3 "module": "commonjs", 3 "module": "commonjs",
4 "target": "es6", 4 "target": "es2018",
5 "outDir": "out", 5 "outDir": "out",
6 "lib": ["es6"], 6 "lib": ["es2018"],
7 "sourceMap": true, 7 "sourceMap": true,
8 "rootDir": "src", 8 "rootDir": "src",
9 "strict": true, 9 "strict": true,
10 "noUnusedLocals": true 10 "noUnusedLocals": true,
11 "noUnusedParameters": true,
12 "noImplicitReturns": true,
13 "noFallthroughCasesInSwitch": true
11 }, 14 },
12 "exclude": ["node_modules", ".vscode-test"] 15 "exclude": ["node_modules", ".vscode-test"]
13} 16}
diff --git a/editors/code/tslint.json b/editors/code/tslint.json
index bdeb4895e..b69c5574d 100644
--- a/editors/code/tslint.json
+++ b/editors/code/tslint.json
@@ -4,6 +4,8 @@
4 "rules": { 4 "rules": {
5 "quotemark": [true, "single"], 5 "quotemark": [true, "single"],
6 "interface-name": false, 6 "interface-name": false,
7 "object-literal-sort-keys": false 7 "object-literal-sort-keys": false,
8 // Allow `_bar` to sort with tsc's `noUnusedParameters` option
9 "variable-name": [true, "allow-leading-underscore"]
8 } 10 }
9} 11}