aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_batch/src/lib.rs6
-rw-r--r--crates/ra_db/src/input.rs2
-rw-r--r--crates/ra_hir/src/adt.rs19
-rw-r--r--crates/ra_hir/src/code_model_api.rs94
-rw-r--r--crates/ra_hir/src/code_model_impl/function.rs7
-rw-r--r--crates/ra_hir/src/code_model_impl/konst.rs6
-rw-r--r--crates/ra_hir/src/code_model_impl/krate.rs9
-rw-r--r--crates/ra_hir/src/code_model_impl/module.rs15
-rw-r--r--crates/ra_hir/src/db.rs6
-rw-r--r--crates/ra_hir/src/expr.rs14
-rw-r--r--crates/ra_hir/src/expr/scope.rs4
-rw-r--r--crates/ra_hir/src/generics.rs6
-rw-r--r--crates/ra_hir/src/ids.rs28
-rw-r--r--crates/ra_hir/src/impl_block.rs31
-rw-r--r--crates/ra_hir/src/lib.rs2
-rw-r--r--crates/ra_hir/src/mock.rs6
-rw-r--r--crates/ra_hir/src/nameres.rs17
-rw-r--r--crates/ra_hir/src/nameres/collector.rs13
-rw-r--r--crates/ra_hir/src/nameres/raw.rs9
-rw-r--r--crates/ra_hir/src/path.rs6
-rw-r--r--crates/ra_hir/src/resolve.rs4
-rw-r--r--crates/ra_hir/src/source_binder.rs6
-rw-r--r--crates/ra_hir/src/ty/autoderef.rs2
-rw-r--r--crates/ra_hir/src/ty/infer.rs50
-rw-r--r--crates/ra_hir/src/ty/lower.rs6
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs2
-rw-r--r--crates/ra_hir/src/ty/tests.rs23
-rw-r--r--crates/ra_hir/src/type_alias.rs7
-rw-r--r--crates/ra_ide_api/Cargo.toml10
-rw-r--r--crates/ra_ide_api/src/completion/complete_dot.rs2
-rw-r--r--crates/ra_ide_api/src/completion/complete_pattern.rs2
-rw-r--r--crates/ra_ide_api/src/completion/complete_struct_literal.rs2
-rw-r--r--crates/ra_ide_api/src/db.rs2
-rw-r--r--crates/ra_ide_api/src/diagnostics.rs28
-rw-r--r--crates/ra_ide_api/src/goto_definition.rs2
-rw-r--r--crates/ra_ide_api/src/hover.rs2
-rw-r--r--crates/ra_ide_api/src/join_lines.rs (renamed from crates/ra_ide_api_light/src/join_lines.rs)18
-rw-r--r--crates/ra_ide_api/src/lib.rs56
-rw-r--r--crates/ra_ide_api/src/line_index.rs2
-rw-r--r--crates/ra_ide_api/src/matching_brace.rs45
-rw-r--r--crates/ra_ide_api/src/snapshots/tests__highlighting.snap34
-rw-r--r--crates/ra_ide_api/src/symbol_index.rs2
-rw-r--r--crates/ra_ide_api/src/syntax_highlighting.rs81
-rw-r--r--crates/ra_ide_api/src/test_utils.rs (renamed from crates/ra_ide_api_light/src/test_utils.rs)15
-rw-r--r--crates/ra_ide_api/src/typing.rs (renamed from crates/ra_ide_api_light/src/typing.rs)82
-rw-r--r--crates/ra_ide_api_light/Cargo.toml7
-rw-r--r--crates/ra_ide_api_light/src/lib.rs144
-rw-r--r--crates/ra_ide_api_light/src/snapshots/tests__highlighting.snap32
-rw-r--r--crates/ra_parser/src/grammar/items/consts.rs2
-rw-r--r--crates/ra_parser/src/grammar/items/nominal.rs2
-rw-r--r--crates/ra_parser/src/grammar/items/traits.rs2
-rw-r--r--crates/ra_parser/src/grammar/items/use_item.rs4
-rw-r--r--crates/ra_parser/src/grammar/types.rs3
-rw-r--r--crates/ra_parser/src/parser.rs4
-rw-r--r--crates/ra_project_model/src/lib.rs2
-rw-r--r--crates/ra_syntax/src/validation/char.rs2
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0081_for_type.rs2
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0081_for_type.txt126
-rw-r--r--crates/ra_syntax/tests/test.rs2
-rw-r--r--crates/ra_text_edit/Cargo.toml7
-rw-r--r--crates/tools/tests/cli.rs26
61 files changed, 623 insertions, 529 deletions
diff --git a/crates/ra_batch/src/lib.rs b/crates/ra_batch/src/lib.rs
index deb9f95d7..3bbcdb0b8 100644
--- a/crates/ra_batch/src/lib.rs
+++ b/crates/ra_batch/src/lib.rs
@@ -16,11 +16,7 @@ use vfs_filter::IncludeRustFiles;
16 16
17type Result<T> = std::result::Result<T, failure::Error>; 17type Result<T> = std::result::Result<T, failure::Error>;
18 18
19#[salsa::database( 19#[salsa::database(ra_db::SourceDatabaseStorage, db::HirDatabaseStorage, db::DefDatabaseStorage)]
20 ra_db::SourceDatabaseStorage,
21 db::HirDatabaseStorage,
22 db::PersistentHirDatabaseStorage
23)]
24#[derive(Debug)] 20#[derive(Debug)]
25pub struct BatchDatabase { 21pub struct BatchDatabase {
26 runtime: salsa::Runtime<BatchDatabase>, 22 runtime: salsa::Runtime<BatchDatabase>,
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs
index 2b1001d48..a5f4e489f 100644
--- a/crates/ra_db/src/input.rs
+++ b/crates/ra_db/src/input.rs
@@ -136,7 +136,7 @@ impl CrateGraph {
136 self.arena[&crate_id].edition 136 self.arena[&crate_id].edition
137 } 137 }
138 138
139 // TODO: this only finds one crate with the given root; we could have multiple 139 // FIXME: this only finds one crate with the given root; we could have multiple
140 pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> { 140 pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> {
141 let (&crate_id, _) = self.arena.iter().find(|(_crate_id, data)| data.file_id == file_id)?; 141 let (&crate_id, _) = self.arena.iter().find(|(_crate_id, data)| data.file_id == file_id)?;
142 Some(crate_id) 142 Some(crate_id)
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs
index 325f1d7b6..78ea8976b 100644
--- a/crates/ra_hir/src/adt.rs
+++ b/crates/ra_hir/src/adt.rs
@@ -12,7 +12,7 @@ use ra_syntax::{
12use crate::{ 12use crate::{
13 Name, AsName, Struct, Enum, EnumVariant, Crate, 13 Name, AsName, Struct, Enum, EnumVariant, Crate,
14 HirDatabase, HirFileId, StructField, FieldSource, 14 HirDatabase, HirFileId, StructField, FieldSource,
15 type_ref::TypeRef, PersistentHirDatabase, 15 type_ref::TypeRef, DefDatabase,
16}; 16};
17 17
18#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 18#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
@@ -33,7 +33,7 @@ impl AdtDef {
33} 33}
34 34
35impl Struct { 35impl Struct {
36 pub(crate) fn variant_data(&self, db: &impl PersistentHirDatabase) -> Arc<VariantData> { 36 pub(crate) fn variant_data(&self, db: &impl DefDatabase) -> Arc<VariantData> {
37 db.struct_data((*self).into()).variant_data.clone() 37 db.struct_data((*self).into()).variant_data.clone()
38 } 38 }
39} 39}
@@ -52,10 +52,7 @@ impl StructData {
52 StructData { name, variant_data } 52 StructData { name, variant_data }
53 } 53 }
54 54
55 pub(crate) fn struct_data_query( 55 pub(crate) fn struct_data_query(db: &impl DefDatabase, struct_: Struct) -> Arc<StructData> {
56 db: &impl PersistentHirDatabase,
57 struct_: Struct,
58 ) -> Arc<StructData> {
59 let (_, struct_def) = struct_.source(db); 56 let (_, struct_def) = struct_.source(db);
60 Arc::new(StructData::new(&*struct_def)) 57 Arc::new(StructData::new(&*struct_def))
61 } 58 }
@@ -68,7 +65,7 @@ fn variants(enum_def: &ast::EnumDef) -> impl Iterator<Item = &ast::EnumVariant>
68impl EnumVariant { 65impl EnumVariant {
69 pub(crate) fn source_impl( 66 pub(crate) fn source_impl(
70 &self, 67 &self,
71 db: &impl PersistentHirDatabase, 68 db: &impl DefDatabase,
72 ) -> (HirFileId, TreeArc<ast::EnumVariant>) { 69 ) -> (HirFileId, TreeArc<ast::EnumVariant>) {
73 let (file_id, enum_def) = self.parent.source(db); 70 let (file_id, enum_def) = self.parent.source(db);
74 let var = variants(&*enum_def) 71 let var = variants(&*enum_def)
@@ -79,7 +76,7 @@ impl EnumVariant {
79 .to_owned(); 76 .to_owned();
80 (file_id, var) 77 (file_id, var)
81 } 78 }
82 pub(crate) fn variant_data(&self, db: &impl PersistentHirDatabase) -> Arc<VariantData> { 79 pub(crate) fn variant_data(&self, db: &impl DefDatabase) -> Arc<VariantData> {
83 db.enum_data(self.parent).variants[self.id].variant_data.clone() 80 db.enum_data(self.parent).variants[self.id].variant_data.clone()
84 } 81 }
85} 82}
@@ -91,7 +88,7 @@ pub struct EnumData {
91} 88}
92 89
93impl EnumData { 90impl EnumData {
94 pub(crate) fn enum_data_query(db: &impl PersistentHirDatabase, e: Enum) -> Arc<EnumData> { 91 pub(crate) fn enum_data_query(db: &impl DefDatabase, e: Enum) -> Arc<EnumData> {
95 let (_file_id, enum_def) = e.source(db); 92 let (_file_id, enum_def) = e.source(db);
96 let name = enum_def.name().map(|n| n.as_name()); 93 let name = enum_def.name().map(|n| n.as_name());
97 let variants = variants(&*enum_def) 94 let variants = variants(&*enum_def)
@@ -189,7 +186,7 @@ impl VariantDef {
189 VariantDef::EnumVariant(it) => it.field(db, name), 186 VariantDef::EnumVariant(it) => it.field(db, name),
190 } 187 }
191 } 188 }
192 pub(crate) fn variant_data(self, db: &impl PersistentHirDatabase) -> Arc<VariantData> { 189 pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
193 match self { 190 match self {
194 VariantDef::Struct(it) => it.variant_data(db), 191 VariantDef::Struct(it) => it.variant_data(db),
195 VariantDef::EnumVariant(it) => it.variant_data(db), 192 VariantDef::EnumVariant(it) => it.variant_data(db),
@@ -198,7 +195,7 @@ impl VariantDef {
198} 195}
199 196
200impl StructField { 197impl StructField {
201 pub(crate) fn source_impl(&self, db: &impl PersistentHirDatabase) -> (HirFileId, FieldSource) { 198 pub(crate) fn source_impl(&self, db: &impl DefDatabase) -> (HirFileId, FieldSource) {
202 let var_data = self.parent.variant_data(db); 199 let var_data = self.parent.variant_data(db);
203 let fields = var_data.fields().unwrap(); 200 let fields = var_data.fields().unwrap();
204 let ss; 201 let ss;
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs
index b00481cd5..45fa4cd11 100644
--- a/crates/ra_hir/src/code_model_api.rs
+++ b/crates/ra_hir/src/code_model_api.rs
@@ -6,7 +6,7 @@ use ra_syntax::{ast::self, TreeArc, SyntaxNode};
6 6
7use crate::{ 7use crate::{
8 Name, ScopesWithSourceMap, Ty, HirFileId, 8 Name, ScopesWithSourceMap, Ty, HirFileId,
9 HirDatabase, PersistentHirDatabase, 9 HirDatabase, DefDatabase,
10 type_ref::TypeRef, 10 type_ref::TypeRef,
11 nameres::{ModuleScope, Namespace, ImportId, CrateModuleId}, 11 nameres::{ModuleScope, Namespace, ImportId, CrateModuleId},
12 expr::{Body, BodySourceMap}, 12 expr::{Body, BodySourceMap},
@@ -38,24 +38,21 @@ impl Crate {
38 self.crate_id 38 self.crate_id
39 } 39 }
40 40
41 pub fn dependencies(&self, db: &impl PersistentHirDatabase) -> Vec<CrateDependency> { 41 pub fn dependencies(&self, db: &impl DefDatabase) -> Vec<CrateDependency> {
42 self.dependencies_impl(db) 42 self.dependencies_impl(db)
43 } 43 }
44 44
45 pub fn root_module(&self, db: &impl PersistentHirDatabase) -> Option<Module> { 45 pub fn root_module(&self, db: &impl DefDatabase) -> Option<Module> {
46 self.root_module_impl(db) 46 self.root_module_impl(db)
47 } 47 }
48 48
49 pub fn edition(&self, db: &impl PersistentHirDatabase) -> Edition { 49 pub fn edition(&self, db: &impl DefDatabase) -> Edition {
50 let crate_graph = db.crate_graph(); 50 let crate_graph = db.crate_graph();
51 crate_graph.edition(self.crate_id) 51 crate_graph.edition(self.crate_id)
52 } 52 }
53 53
54 // TODO: should this be in source_binder? 54 // FIXME: should this be in source_binder?
55 pub fn source_root_crates( 55 pub fn source_root_crates(db: &impl DefDatabase, source_root: SourceRootId) -> Vec<Crate> {
56 db: &impl PersistentHirDatabase,
57 source_root: SourceRootId,
58 ) -> Vec<Crate> {
59 let crate_ids = db.source_root_crates(source_root); 56 let crate_ids = db.source_root_crates(source_root);
60 crate_ids.iter().map(|&crate_id| Crate { crate_id }).collect() 57 crate_ids.iter().map(|&crate_id| Crate { crate_id }).collect()
61 } 58 }
@@ -101,7 +98,6 @@ pub enum ModuleSource {
101#[derive(Clone, Debug, Hash, PartialEq, Eq)] 98#[derive(Clone, Debug, Hash, PartialEq, Eq)]
102pub enum Problem { 99pub enum Problem {
103 UnresolvedModule { candidate: RelativePathBuf }, 100 UnresolvedModule { candidate: RelativePathBuf },
104 NotDirOwner { move_to: RelativePathBuf, candidate: RelativePathBuf },
105} 101}
106 102
107impl Module { 103impl Module {
@@ -111,7 +107,7 @@ impl Module {
111 } 107 }
112 108
113 /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. 109 /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items.
114 pub fn definition_source(&self, db: &impl PersistentHirDatabase) -> (HirFileId, ModuleSource) { 110 pub fn definition_source(&self, db: &impl DefDatabase) -> (HirFileId, ModuleSource) {
115 self.definition_source_impl(db) 111 self.definition_source_impl(db)
116 } 112 }
117 113
@@ -134,14 +130,14 @@ impl Module {
134 } 130 }
135 131
136 /// Returns the crate this module is part of. 132 /// Returns the crate this module is part of.
137 pub fn krate(&self, _db: &impl PersistentHirDatabase) -> Option<Crate> { 133 pub fn krate(&self, _db: &impl DefDatabase) -> Option<Crate> {
138 Some(self.krate) 134 Some(self.krate)
139 } 135 }
140 136
141 /// Topmost parent of this module. Every module has a `crate_root`, but some 137 /// Topmost parent of this module. Every module has a `crate_root`, but some
142 /// might be missing `krate`. This can happen if a module's file is not included 138 /// might be missing `krate`. This can happen if a module's file is not included
143 /// in the module tree of any target in `Cargo.toml`. 139 /// in the module tree of any target in `Cargo.toml`.
144 pub fn crate_root(&self, db: &impl PersistentHirDatabase) -> Module { 140 pub fn crate_root(&self, db: &impl DefDatabase) -> Module {
145 self.crate_root_impl(db) 141 self.crate_root_impl(db)
146 } 142 }
147 143
@@ -151,12 +147,12 @@ impl Module {
151 } 147 }
152 148
153 /// Iterates over all child modules. 149 /// Iterates over all child modules.
154 pub fn children(&self, db: &impl PersistentHirDatabase) -> impl Iterator<Item = Module> { 150 pub fn children(&self, db: &impl DefDatabase) -> impl Iterator<Item = Module> {
155 self.children_impl(db) 151 self.children_impl(db)
156 } 152 }
157 153
158 /// Finds a parent module. 154 /// Finds a parent module.
159 pub fn parent(&self, db: &impl PersistentHirDatabase) -> Option<Module> { 155 pub fn parent(&self, db: &impl DefDatabase) -> Option<Module> {
160 self.parent_impl(db) 156 self.parent_impl(db)
161 } 157 }
162 158
@@ -229,7 +225,7 @@ impl StructField {
229 self.parent.variant_data(db).fields().unwrap()[self.id].name.clone() 225 self.parent.variant_data(db).fields().unwrap()[self.id].name.clone()
230 } 226 }
231 227
232 pub fn source(&self, db: &impl PersistentHirDatabase) -> (HirFileId, FieldSource) { 228 pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, FieldSource) {
233 self.source_impl(db) 229 self.source_impl(db)
234 } 230 }
235 231
@@ -257,7 +253,7 @@ pub struct Struct {
257} 253}
258 254
259impl Struct { 255impl Struct {
260 pub fn source(&self, db: &impl PersistentHirDatabase) -> (HirFileId, TreeArc<ast::StructDef>) { 256 pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::StructDef>) {
261 self.id.source(db) 257 self.id.source(db)
262 } 258 }
263 259
@@ -289,7 +285,7 @@ impl Struct {
289 .map(|(id, _)| StructField { parent: (*self).into(), id }) 285 .map(|(id, _)| StructField { parent: (*self).into(), id })
290 } 286 }
291 287
292 pub fn generic_params(&self, db: &impl PersistentHirDatabase) -> Arc<GenericParams> { 288 pub fn generic_params(&self, db: &impl DefDatabase) -> Arc<GenericParams> {
293 db.generic_params((*self).into()) 289 db.generic_params((*self).into())
294 } 290 }
295 291
@@ -301,7 +297,7 @@ impl Struct {
301 db.type_for_def((*self).into(), Namespace::Values) 297 db.type_for_def((*self).into(), Namespace::Values)
302 } 298 }
303 299
304 // TODO move to a more general type 300 // FIXME move to a more general type
305 /// Builds a resolver for type references inside this struct. 301 /// Builds a resolver for type references inside this struct.
306 pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { 302 pub fn resolver(&self, db: &impl HirDatabase) -> Resolver {
307 // take the outer scope... 303 // take the outer scope...
@@ -325,7 +321,7 @@ pub struct Enum {
325} 321}
326 322
327impl Enum { 323impl Enum {
328 pub fn source(&self, db: &impl PersistentHirDatabase) -> (HirFileId, TreeArc<ast::EnumDef>) { 324 pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::EnumDef>) {
329 self.id.source(db) 325 self.id.source(db)
330 } 326 }
331 327
@@ -337,7 +333,7 @@ impl Enum {
337 db.enum_data(*self).name.clone() 333 db.enum_data(*self).name.clone()
338 } 334 }
339 335
340 pub fn variants(&self, db: &impl PersistentHirDatabase) -> Vec<EnumVariant> { 336 pub fn variants(&self, db: &impl DefDatabase) -> Vec<EnumVariant> {
341 db.enum_data(*self) 337 db.enum_data(*self)
342 .variants 338 .variants
343 .iter() 339 .iter()
@@ -345,7 +341,7 @@ impl Enum {
345 .collect() 341 .collect()
346 } 342 }
347 343
348 pub fn variant(&self, db: &impl PersistentHirDatabase, name: &Name) -> Option<EnumVariant> { 344 pub fn variant(&self, db: &impl DefDatabase, name: &Name) -> Option<EnumVariant> {
349 db.enum_data(*self) 345 db.enum_data(*self)
350 .variants 346 .variants
351 .iter() 347 .iter()
@@ -353,7 +349,7 @@ impl Enum {
353 .map(|(id, _)| EnumVariant { parent: *self, id }) 349 .map(|(id, _)| EnumVariant { parent: *self, id })
354 } 350 }
355 351
356 pub fn generic_params(&self, db: &impl PersistentHirDatabase) -> Arc<GenericParams> { 352 pub fn generic_params(&self, db: &impl DefDatabase) -> Arc<GenericParams> {
357 db.generic_params((*self).into()) 353 db.generic_params((*self).into())
358 } 354 }
359 355
@@ -361,7 +357,7 @@ impl Enum {
361 db.type_for_def((*self).into(), Namespace::Types) 357 db.type_for_def((*self).into(), Namespace::Types)
362 } 358 }
363 359
364 // TODO: move to a more general type 360 // FIXME: move to a more general type
365 /// Builds a resolver for type references inside this struct. 361 /// Builds a resolver for type references inside this struct.
366 pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { 362 pub fn resolver(&self, db: &impl HirDatabase) -> Resolver {
367 // take the outer scope... 363 // take the outer scope...
@@ -386,20 +382,17 @@ pub struct EnumVariant {
386} 382}
387 383
388impl EnumVariant { 384impl EnumVariant {
389 pub fn source( 385 pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::EnumVariant>) {
390 &self,
391 db: &impl PersistentHirDatabase,
392 ) -> (HirFileId, TreeArc<ast::EnumVariant>) {
393 self.source_impl(db) 386 self.source_impl(db)
394 } 387 }
395 pub fn module(&self, db: &impl HirDatabase) -> Module { 388 pub fn module(&self, db: &impl HirDatabase) -> Module {
396 self.parent.module(db) 389 self.parent.module(db)
397 } 390 }
398 pub fn parent_enum(&self, _db: &impl PersistentHirDatabase) -> Enum { 391 pub fn parent_enum(&self, _db: &impl DefDatabase) -> Enum {
399 self.parent 392 self.parent
400 } 393 }
401 394
402 pub fn name(&self, db: &impl PersistentHirDatabase) -> Option<Name> { 395 pub fn name(&self, db: &impl DefDatabase) -> Option<Name> {
403 db.enum_data(self.parent).variants[self.id].name.clone() 396 db.enum_data(self.parent).variants[self.id].name.clone()
404 } 397 }
405 398
@@ -465,11 +458,11 @@ impl FnSignature {
465} 458}
466 459
467impl Function { 460impl Function {
468 pub fn source(&self, db: &impl PersistentHirDatabase) -> (HirFileId, TreeArc<ast::FnDef>) { 461 pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::FnDef>) {
469 self.id.source(db) 462 self.id.source(db)
470 } 463 }
471 464
472 pub fn module(&self, db: &impl PersistentHirDatabase) -> Module { 465 pub fn module(&self, db: &impl DefDatabase) -> Module {
473 self.id.module(db) 466 self.id.module(db)
474 } 467 }
475 468
@@ -503,17 +496,17 @@ impl Function {
503 db.infer(*self) 496 db.infer(*self)
504 } 497 }
505 498
506 pub fn generic_params(&self, db: &impl PersistentHirDatabase) -> Arc<GenericParams> { 499 pub fn generic_params(&self, db: &impl DefDatabase) -> Arc<GenericParams> {
507 db.generic_params((*self).into()) 500 db.generic_params((*self).into())
508 } 501 }
509 502
510 /// The containing impl block, if this is a method. 503 /// The containing impl block, if this is a method.
511 pub fn impl_block(&self, db: &impl PersistentHirDatabase) -> Option<ImplBlock> { 504 pub fn impl_block(&self, db: &impl DefDatabase) -> Option<ImplBlock> {
512 let module_impls = db.impls_in_module(self.module(db)); 505 let module_impls = db.impls_in_module(self.module(db));
513 ImplBlock::containing(module_impls, (*self).into()) 506 ImplBlock::containing(module_impls, (*self).into())
514 } 507 }
515 508
516 // TODO: move to a more general type for 'body-having' items 509 // FIXME: move to a more general type for 'body-having' items
517 /// Builds a resolver for code inside this item. 510 /// Builds a resolver for code inside this item.
518 pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { 511 pub fn resolver(&self, db: &impl HirDatabase) -> Resolver {
519 // take the outer scope... 512 // take the outer scope...
@@ -540,11 +533,11 @@ pub struct Const {
540} 533}
541 534
542impl Const { 535impl Const {
543 pub fn source(&self, db: &impl PersistentHirDatabase) -> (HirFileId, TreeArc<ast::ConstDef>) { 536 pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::ConstDef>) {
544 self.id.source(db) 537 self.id.source(db)
545 } 538 }
546 539
547 pub fn module(&self, db: &impl PersistentHirDatabase) -> Module { 540 pub fn module(&self, db: &impl DefDatabase) -> Module {
548 self.id.module(db) 541 self.id.module(db)
549 } 542 }
550 543
@@ -553,12 +546,12 @@ impl Const {
553 } 546 }
554 547
555 /// The containing impl block, if this is a method. 548 /// The containing impl block, if this is a method.
556 pub fn impl_block(&self, db: &impl PersistentHirDatabase) -> Option<ImplBlock> { 549 pub fn impl_block(&self, db: &impl DefDatabase) -> Option<ImplBlock> {
557 let module_impls = db.impls_in_module(self.module(db)); 550 let module_impls = db.impls_in_module(self.module(db));
558 ImplBlock::containing(module_impls, (*self).into()) 551 ImplBlock::containing(module_impls, (*self).into())
559 } 552 }
560 553
561 // TODO: move to a more general type for 'body-having' items 554 // FIXME: move to a more general type for 'body-having' items
562 /// Builds a resolver for code inside this item. 555 /// Builds a resolver for code inside this item.
563 pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { 556 pub fn resolver(&self, db: &impl HirDatabase) -> Resolver {
564 // take the outer scope... 557 // take the outer scope...
@@ -599,11 +592,11 @@ pub struct Static {
599} 592}
600 593
601impl Static { 594impl Static {
602 pub fn source(&self, db: &impl PersistentHirDatabase) -> (HirFileId, TreeArc<ast::StaticDef>) { 595 pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::StaticDef>) {
603 self.id.source(db) 596 self.id.source(db)
604 } 597 }
605 598
606 pub fn module(&self, db: &impl PersistentHirDatabase) -> Module { 599 pub fn module(&self, db: &impl DefDatabase) -> Module {
607 self.id.module(db) 600 self.id.module(db)
608 } 601 }
609 602
@@ -630,15 +623,15 @@ pub struct Trait {
630} 623}
631 624
632impl Trait { 625impl Trait {
633 pub fn source(&self, db: &impl PersistentHirDatabase) -> (HirFileId, TreeArc<ast::TraitDef>) { 626 pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::TraitDef>) {
634 self.id.source(db) 627 self.id.source(db)
635 } 628 }
636 629
637 pub fn module(&self, db: &impl PersistentHirDatabase) -> Module { 630 pub fn module(&self, db: &impl DefDatabase) -> Module {
638 self.id.module(db) 631 self.id.module(db)
639 } 632 }
640 633
641 pub fn generic_params(&self, db: &impl PersistentHirDatabase) -> Arc<GenericParams> { 634 pub fn generic_params(&self, db: &impl DefDatabase) -> Arc<GenericParams> {
642 db.generic_params((*self).into()) 635 db.generic_params((*self).into())
643 } 636 }
644} 637}
@@ -655,28 +648,25 @@ pub struct TypeAlias {
655} 648}
656 649
657impl TypeAlias { 650impl TypeAlias {
658 pub fn source( 651 pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::TypeAliasDef>) {
659 &self,
660 db: &impl PersistentHirDatabase,
661 ) -> (HirFileId, TreeArc<ast::TypeAliasDef>) {
662 self.id.source(db) 652 self.id.source(db)
663 } 653 }
664 654
665 pub fn generic_params(&self, db: &impl PersistentHirDatabase) -> Arc<GenericParams> { 655 pub fn generic_params(&self, db: &impl DefDatabase) -> Arc<GenericParams> {
666 db.generic_params((*self).into()) 656 db.generic_params((*self).into())
667 } 657 }
668 658
669 pub fn module(&self, db: &impl PersistentHirDatabase) -> Module { 659 pub fn module(&self, db: &impl DefDatabase) -> Module {
670 self.id.module(db) 660 self.id.module(db)
671 } 661 }
672 662
673 /// The containing impl block, if this is a method. 663 /// The containing impl block, if this is a method.
674 pub fn impl_block(&self, db: &impl PersistentHirDatabase) -> Option<ImplBlock> { 664 pub fn impl_block(&self, db: &impl DefDatabase) -> Option<ImplBlock> {
675 let module_impls = db.impls_in_module(self.module(db)); 665 let module_impls = db.impls_in_module(self.module(db));
676 ImplBlock::containing(module_impls, (*self).into()) 666 ImplBlock::containing(module_impls, (*self).into())
677 } 667 }
678 668
679 pub fn type_ref(self, db: &impl PersistentHirDatabase) -> Arc<TypeRef> { 669 pub fn type_ref(self, db: &impl DefDatabase) -> Arc<TypeRef> {
680 db.type_alias_ref(self) 670 db.type_alias_ref(self)
681 } 671 }
682 672
diff --git a/crates/ra_hir/src/code_model_impl/function.rs b/crates/ra_hir/src/code_model_impl/function.rs
index c1654b069..334cb302b 100644
--- a/crates/ra_hir/src/code_model_impl/function.rs
+++ b/crates/ra_hir/src/code_model_impl/function.rs
@@ -5,14 +5,11 @@ use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
5use crate::{ 5use crate::{
6 Name, AsName, Function, FnSignature, 6 Name, AsName, Function, FnSignature,
7 type_ref::{TypeRef, Mutability}, 7 type_ref::{TypeRef, Mutability},
8 PersistentHirDatabase, 8 DefDatabase,
9}; 9};
10 10
11impl FnSignature { 11impl FnSignature {
12 pub(crate) fn fn_signature_query( 12 pub(crate) fn fn_signature_query(db: &impl DefDatabase, func: Function) -> Arc<FnSignature> {
13 db: &impl PersistentHirDatabase,
14 func: Function,
15 ) -> Arc<FnSignature> {
16 let (_, node) = func.source(db); 13 let (_, node) = func.source(db);
17 let name = node.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); 14 let name = node.name().map(|n| n.as_name()).unwrap_or_else(Name::missing);
18 let mut params = Vec::new(); 15 let mut params = Vec::new();
diff --git a/crates/ra_hir/src/code_model_impl/konst.rs b/crates/ra_hir/src/code_model_impl/konst.rs
index 8b861a81f..db4e5ce5c 100644
--- a/crates/ra_hir/src/code_model_impl/konst.rs
+++ b/crates/ra_hir/src/code_model_impl/konst.rs
@@ -5,7 +5,7 @@ use ra_syntax::ast::{NameOwner, TypeAscriptionOwner};
5use crate::{ 5use crate::{
6 Name, AsName, Const, ConstSignature, Static, 6 Name, AsName, Const, ConstSignature, Static,
7 type_ref::{TypeRef}, 7 type_ref::{TypeRef},
8 PersistentHirDatabase, 8 DefDatabase,
9}; 9};
10 10
11fn const_signature_for<N: NameOwner + TypeAscriptionOwner>(node: &N) -> Arc<ConstSignature> { 11fn const_signature_for<N: NameOwner + TypeAscriptionOwner>(node: &N) -> Arc<ConstSignature> {
@@ -17,7 +17,7 @@ fn const_signature_for<N: NameOwner + TypeAscriptionOwner>(node: &N) -> Arc<Cons
17 17
18impl ConstSignature { 18impl ConstSignature {
19 pub(crate) fn const_signature_query( 19 pub(crate) fn const_signature_query(
20 db: &impl PersistentHirDatabase, 20 db: &impl DefDatabase,
21 konst: Const, 21 konst: Const,
22 ) -> Arc<ConstSignature> { 22 ) -> Arc<ConstSignature> {
23 let (_, node) = konst.source(db); 23 let (_, node) = konst.source(db);
@@ -25,7 +25,7 @@ impl ConstSignature {
25 } 25 }
26 26
27 pub(crate) fn static_signature_query( 27 pub(crate) fn static_signature_query(
28 db: &impl PersistentHirDatabase, 28 db: &impl DefDatabase,
29 konst: Static, 29 konst: Static,
30 ) -> Arc<ConstSignature> { 30 ) -> Arc<ConstSignature> {
31 let (_, node) = konst.source(db); 31 let (_, node) = konst.source(db);
diff --git a/crates/ra_hir/src/code_model_impl/krate.rs b/crates/ra_hir/src/code_model_impl/krate.rs
index cc87c6f14..914414fc3 100644
--- a/crates/ra_hir/src/code_model_impl/krate.rs
+++ b/crates/ra_hir/src/code_model_impl/krate.rs
@@ -1,12 +1,9 @@
1use crate::{ 1use crate::{
2 Crate, CrateDependency, AsName, Module, PersistentHirDatabase, 2 Crate, CrateDependency, AsName, Module, DefDatabase,
3}; 3};
4 4
5impl Crate { 5impl Crate {
6 pub(crate) fn dependencies_impl( 6 pub(crate) fn dependencies_impl(&self, db: &impl DefDatabase) -> Vec<CrateDependency> {
7 &self,
8 db: &impl PersistentHirDatabase,
9 ) -> Vec<CrateDependency> {
10 let crate_graph = db.crate_graph(); 7 let crate_graph = db.crate_graph();
11 crate_graph 8 crate_graph
12 .dependencies(self.crate_id) 9 .dependencies(self.crate_id)
@@ -17,7 +14,7 @@ impl Crate {
17 }) 14 })
18 .collect() 15 .collect()
19 } 16 }
20 pub(crate) fn root_module_impl(&self, db: &impl PersistentHirDatabase) -> Option<Module> { 17 pub(crate) fn root_module_impl(&self, db: &impl DefDatabase) -> Option<Module> {
21 let module_id = db.crate_def_map(*self).root(); 18 let module_id = db.crate_def_map(*self).root();
22 let module = Module { krate: *self, module_id }; 19 let module = Module { krate: *self, module_id };
23 Some(module) 20 Some(module)
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs
index f7d15c55e..52a33e981 100644
--- a/crates/ra_hir/src/code_model_impl/module.rs
+++ b/crates/ra_hir/src/code_model_impl/module.rs
@@ -4,13 +4,13 @@ use ra_syntax::{ast, SyntaxNode, TreeArc, AstNode};
4use crate::{ 4use crate::{
5 Module, ModuleSource, Problem, Name, 5 Module, ModuleSource, Problem, Name,
6 nameres::{CrateModuleId, ImportId}, 6 nameres::{CrateModuleId, ImportId},
7 HirDatabase, PersistentHirDatabase, 7 HirDatabase, DefDatabase,
8 HirFileId, SourceItemId, 8 HirFileId, SourceItemId,
9}; 9};
10 10
11impl ModuleSource { 11impl ModuleSource {
12 pub(crate) fn new( 12 pub(crate) fn new(
13 db: &impl PersistentHirDatabase, 13 db: &impl DefDatabase,
14 file_id: Option<FileId>, 14 file_id: Option<FileId>,
15 decl_id: Option<SourceItemId>, 15 decl_id: Option<SourceItemId>,
16 ) -> ModuleSource { 16 ) -> ModuleSource {
@@ -49,7 +49,7 @@ impl Module {
49 49
50 pub(crate) fn definition_source_impl( 50 pub(crate) fn definition_source_impl(
51 &self, 51 &self,
52 db: &impl PersistentHirDatabase, 52 db: &impl DefDatabase,
53 ) -> (HirFileId, ModuleSource) { 53 ) -> (HirFileId, ModuleSource) {
54 let def_map = db.crate_def_map(self.krate); 54 let def_map = db.crate_def_map(self.krate);
55 let decl_id = def_map[self.module_id].declaration; 55 let decl_id = def_map[self.module_id].declaration;
@@ -80,7 +80,7 @@ impl Module {
80 source_map.get(&source, import) 80 source_map.get(&source, import)
81 } 81 }
82 82
83 pub(crate) fn crate_root_impl(&self, db: &impl PersistentHirDatabase) -> Module { 83 pub(crate) fn crate_root_impl(&self, db: &impl DefDatabase) -> Module {
84 let def_map = db.crate_def_map(self.krate); 84 let def_map = db.crate_def_map(self.krate);
85 self.with_module_id(def_map.root()) 85 self.with_module_id(def_map.root())
86 } 86 }
@@ -93,10 +93,7 @@ impl Module {
93 } 93 }
94 94
95 /// Iterates over all child modules. 95 /// Iterates over all child modules.
96 pub(crate) fn children_impl( 96 pub(crate) fn children_impl(&self, db: &impl DefDatabase) -> impl Iterator<Item = Module> {
97 &self,
98 db: &impl PersistentHirDatabase,
99 ) -> impl Iterator<Item = Module> {
100 let def_map = db.crate_def_map(self.krate); 97 let def_map = db.crate_def_map(self.krate);
101 let children = def_map[self.module_id] 98 let children = def_map[self.module_id]
102 .children 99 .children
@@ -106,7 +103,7 @@ impl Module {
106 children.into_iter() 103 children.into_iter()
107 } 104 }
108 105
109 pub(crate) fn parent_impl(&self, db: &impl PersistentHirDatabase) -> Option<Module> { 106 pub(crate) fn parent_impl(&self, db: &impl DefDatabase) -> Option<Module> {
110 let def_map = db.crate_def_map(self.krate); 107 let def_map = db.crate_def_map(self.krate);
111 let parent_id = def_map[self.module_id].parent?; 108 let parent_id = def_map[self.module_id].parent?;
112 Some(self.with_module_id(parent_id)) 109 Some(self.with_module_id(parent_id))
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index c7bad7e2b..d3908f8ac 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -16,8 +16,8 @@ use crate::{
16 type_ref::TypeRef, 16 type_ref::TypeRef,
17}; 17};
18 18
19#[salsa::query_group(PersistentHirDatabaseStorage)] 19#[salsa::query_group(DefDatabaseStorage)]
20pub trait PersistentHirDatabase: SourceDatabase + AsRef<HirInterner> { 20pub trait DefDatabase: SourceDatabase + AsRef<HirInterner> {
21 #[salsa::invoke(HirFileId::hir_parse)] 21 #[salsa::invoke(HirFileId::hir_parse)]
22 fn hir_parse(&self, file_id: HirFileId) -> TreeArc<SourceFile>; 22 fn hir_parse(&self, file_id: HirFileId) -> TreeArc<SourceFile>;
23 23
@@ -71,7 +71,7 @@ pub trait PersistentHirDatabase: SourceDatabase + AsRef<HirInterner> {
71} 71}
72 72
73#[salsa::query_group(HirDatabaseStorage)] 73#[salsa::query_group(HirDatabaseStorage)]
74pub trait HirDatabase: PersistentHirDatabase { 74pub trait HirDatabase: DefDatabase {
75 #[salsa::invoke(ExprScopes::expr_scopes_query)] 75 #[salsa::invoke(ExprScopes::expr_scopes_query)]
76 fn expr_scopes(&self, func: Function) -> Arc<ExprScopes>; 76 fn expr_scopes(&self, func: Function) -> Arc<ExprScopes>;
77 77
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index 0fadab560..703d99d9b 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -27,7 +27,7 @@ impl_arena_id!(ExprId);
27/// The body of an item (function, const etc.). 27/// The body of an item (function, const etc.).
28#[derive(Debug, Eq, PartialEq)] 28#[derive(Debug, Eq, PartialEq)]
29pub struct Body { 29pub struct Body {
30 // TODO: this should be more general, consts & statics also have bodies 30 // FIXME: this should be more general, consts & statics also have bodies
31 /// The Function of the item this body belongs to 31 /// The Function of the item this body belongs to
32 owner: Function, 32 owner: Function,
33 exprs: Arena<ExprId, Expr>, 33 exprs: Arena<ExprId, Expr>,
@@ -406,7 +406,7 @@ pub enum Pat {
406 Struct { 406 Struct {
407 path: Option<Path>, 407 path: Option<Path>,
408 args: Vec<FieldPat>, 408 args: Vec<FieldPat>,
409 // TODO: 'ellipsis' option 409 // FIXME: 'ellipsis' option
410 }, 410 },
411 Range { 411 Range {
412 start: ExprId, 412 start: ExprId,
@@ -547,7 +547,7 @@ impl ExprCollector {
547 if condition.pat().is_none() { 547 if condition.pat().is_none() {
548 self.collect_expr_opt(condition.expr()) 548 self.collect_expr_opt(condition.expr())
549 } else { 549 } else {
550 // TODO handle while let 550 // FIXME handle while let
551 return self.alloc_expr(Expr::Missing, syntax_ptr); 551 return self.alloc_expr(Expr::Missing, syntax_ptr);
552 } 552 }
553 } else { 553 } else {
@@ -610,7 +610,7 @@ impl ExprCollector {
610 self.alloc_expr(path, syntax_ptr) 610 self.alloc_expr(path, syntax_ptr)
611 } 611 }
612 ast::ExprKind::ContinueExpr(_e) => { 612 ast::ExprKind::ContinueExpr(_e) => {
613 // TODO: labels 613 // FIXME: labels
614 self.alloc_expr(Expr::Continue, syntax_ptr) 614 self.alloc_expr(Expr::Continue, syntax_ptr)
615 } 615 }
616 ast::ExprKind::BreakExpr(e) => { 616 ast::ExprKind::BreakExpr(e) => {
@@ -751,7 +751,7 @@ impl ExprCollector {
751 self.alloc_expr(Expr::Literal(lit), syntax_ptr) 751 self.alloc_expr(Expr::Literal(lit), syntax_ptr)
752 } 752 }
753 753
754 // TODO implement HIR for these: 754 // FIXME implement HIR for these:
755 ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), 755 ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
756 ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), 756 ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
757 ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), 757 ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
@@ -844,7 +844,7 @@ impl ExprCollector {
844 Pat::Struct { path, args: fields } 844 Pat::Struct { path, args: fields }
845 } 845 }
846 846
847 // TODO: implement 847 // FIXME: implement
848 ast::PatKind::LiteralPat(_) => Pat::Missing, 848 ast::PatKind::LiteralPat(_) => Pat::Missing,
849 ast::PatKind::SlicePat(_) | ast::PatKind::RangePat(_) => Pat::Missing, 849 ast::PatKind::SlicePat(_) | ast::PatKind::RangePat(_) => Pat::Missing,
850 }; 850 };
@@ -910,7 +910,7 @@ pub(crate) fn body_with_source_map_query(
910) -> (Arc<Body>, Arc<BodySourceMap>) { 910) -> (Arc<Body>, Arc<BodySourceMap>) {
911 let mut collector = ExprCollector::new(func); 911 let mut collector = ExprCollector::new(func);
912 912
913 // TODO: consts, etc. 913 // FIXME: consts, etc.
914 collector.collect_fn_body(&func.source(db).1); 914 collector.collect_fn_body(&func.source(db).1);
915 915
916 let (body, source_map) = collector.finish(); 916 let (body, source_map) = collector.finish();
diff --git a/crates/ra_hir/src/expr/scope.rs b/crates/ra_hir/src/expr/scope.rs
index 81fbc509e..ed005c9f7 100644
--- a/crates/ra_hir/src/expr/scope.rs
+++ b/crates/ra_hir/src/expr/scope.rs
@@ -39,7 +39,7 @@ pub struct ScopeData {
39} 39}
40 40
41impl ExprScopes { 41impl ExprScopes {
42 // TODO: This should take something more general than Function 42 // FIXME: This should take something more general than Function
43 pub(crate) fn expr_scopes_query(db: &impl HirDatabase, function: Function) -> Arc<ExprScopes> { 43 pub(crate) fn expr_scopes_query(db: &impl HirDatabase, function: Function) -> Arc<ExprScopes> {
44 let body = db.body_hir(function); 44 let body = db.body_hir(function);
45 let res = ExprScopes::new(body); 45 let res = ExprScopes::new(body);
@@ -148,7 +148,7 @@ impl ScopesWithSourceMap {
148 148
149 // XXX: during completion, cursor might be outside of any particular 149 // XXX: during completion, cursor might be outside of any particular
150 // expression. Try to figure out the correct scope... 150 // expression. Try to figure out the correct scope...
151 // TODO: move this to source binder? 151 // FIXME: move this to source binder?
152 fn adjust(&self, ptr: SyntaxNodePtr, original_scope: ScopeId, offset: TextUnit) -> ScopeId { 152 fn adjust(&self, ptr: SyntaxNodePtr, original_scope: ScopeId, offset: TextUnit) -> ScopeId {
153 let r = ptr.range(); 153 let r = ptr.range();
154 let child_scopes = self 154 let child_scopes = self
diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs
index 0f759a235..84fe94289 100644
--- a/crates/ra_hir/src/generics.rs
+++ b/crates/ra_hir/src/generics.rs
@@ -8,14 +8,14 @@ use std::sync::Arc;
8use ra_syntax::ast::{self, NameOwner, TypeParamsOwner}; 8use ra_syntax::ast::{self, NameOwner, TypeParamsOwner};
9 9
10use crate::{ 10use crate::{
11 db::PersistentHirDatabase, 11 db::DefDatabase,
12 Name, AsName, Function, Struct, Enum, Trait, TypeAlias, ImplBlock 12 Name, AsName, Function, Struct, Enum, Trait, TypeAlias, ImplBlock
13}; 13};
14 14
15/// Data about a generic parameter (to a function, struct, impl, ...). 15/// Data about a generic parameter (to a function, struct, impl, ...).
16#[derive(Clone, PartialEq, Eq, Debug)] 16#[derive(Clone, PartialEq, Eq, Debug)]
17pub struct GenericParam { 17pub struct GenericParam {
18 // TODO: give generic params proper IDs 18 // FIXME: give generic params proper IDs
19 pub(crate) idx: u32, 19 pub(crate) idx: u32,
20 pub(crate) name: Name, 20 pub(crate) name: Name,
21} 21}
@@ -40,7 +40,7 @@ impl_froms!(GenericDef: Function, Struct, Enum, Trait, TypeAlias, ImplBlock);
40 40
41impl GenericParams { 41impl GenericParams {
42 pub(crate) fn generic_params_query( 42 pub(crate) fn generic_params_query(
43 db: &impl PersistentHirDatabase, 43 db: &impl DefDatabase,
44 def: GenericDef, 44 def: GenericDef,
45 ) -> Arc<GenericParams> { 45 ) -> Arc<GenericParams> {
46 let mut generics = GenericParams::default(); 46 let mut generics = GenericParams::default();
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs
index 3d0a881c2..18401f865 100644
--- a/crates/ra_hir/src/ids.rs
+++ b/crates/ra_hir/src/ids.rs
@@ -10,7 +10,7 @@ use ra_arena::{Arena, RawId, ArenaId, impl_arena_id};
10 10
11use crate::{ 11use crate::{
12 Module, 12 Module,
13 PersistentHirDatabase, 13 DefDatabase,
14}; 14};
15 15
16#[derive(Debug, Default)] 16#[derive(Debug, Default)]
@@ -63,7 +63,7 @@ pub struct HirFileId(HirFileIdRepr);
63impl HirFileId { 63impl HirFileId {
64 /// For macro-expansion files, returns the file original source file the 64 /// For macro-expansion files, returns the file original source file the
65 /// expansion originated from. 65 /// expansion originated from.
66 pub fn original_file(self, db: &impl PersistentHirDatabase) -> FileId { 66 pub fn original_file(self, db: &impl DefDatabase) -> FileId {
67 match self.0 { 67 match self.0 {
68 HirFileIdRepr::File(file_id) => file_id, 68 HirFileIdRepr::File(file_id) => file_id,
69 HirFileIdRepr::Macro(macro_call_id) => { 69 HirFileIdRepr::Macro(macro_call_id) => {
@@ -83,10 +83,7 @@ impl HirFileId {
83 } 83 }
84 } 84 }
85 85
86 pub(crate) fn hir_parse( 86 pub(crate) fn hir_parse(db: &impl DefDatabase, file_id: HirFileId) -> TreeArc<SourceFile> {
87 db: &impl PersistentHirDatabase,
88 file_id: HirFileId,
89 ) -> TreeArc<SourceFile> {
90 match file_id.0 { 87 match file_id.0 {
91 HirFileIdRepr::File(file_id) => db.parse(file_id), 88 HirFileIdRepr::File(file_id) => db.parse(file_id),
92 HirFileIdRepr::Macro(macro_call_id) => { 89 HirFileIdRepr::Macro(macro_call_id) => {
@@ -97,10 +94,7 @@ impl HirFileId {
97 } 94 }
98} 95}
99 96
100fn parse_macro( 97fn parse_macro(db: &impl DefDatabase, macro_call_id: MacroCallId) -> Option<TreeArc<SourceFile>> {
101 db: &impl PersistentHirDatabase,
102 macro_call_id: MacroCallId,
103) -> Option<TreeArc<SourceFile>> {
104 let loc = macro_call_id.loc(db); 98 let loc = macro_call_id.loc(db);
105 let syntax = db.file_item(loc.source_item_id); 99 let syntax = db.file_item(loc.source_item_id);
106 let macro_call = ast::MacroCall::cast(&syntax).unwrap(); 100 let macro_call = ast::MacroCall::cast(&syntax).unwrap();
@@ -190,7 +184,7 @@ pub(crate) struct LocationCtx<DB> {
190 file_id: HirFileId, 184 file_id: HirFileId,
191} 185}
192 186
193impl<'a, DB: PersistentHirDatabase> LocationCtx<&'a DB> { 187impl<'a, DB: DefDatabase> LocationCtx<&'a DB> {
194 pub(crate) fn new(db: &'a DB, module: Module, file_id: HirFileId) -> LocationCtx<&'a DB> { 188 pub(crate) fn new(db: &'a DB, module: Module, file_id: HirFileId) -> LocationCtx<&'a DB> {
195 LocationCtx { db, module, file_id } 189 LocationCtx { db, module, file_id }
196 } 190 }
@@ -205,13 +199,13 @@ impl<'a, DB: PersistentHirDatabase> LocationCtx<&'a DB> {
205 199
206pub(crate) trait AstItemDef<N: AstNode>: ArenaId + Clone { 200pub(crate) trait AstItemDef<N: AstNode>: ArenaId + Clone {
207 fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<N>, Self>; 201 fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<N>, Self>;
208 fn from_ast(ctx: LocationCtx<&impl PersistentHirDatabase>, ast: &N) -> Self { 202 fn from_ast(ctx: LocationCtx<&impl DefDatabase>, ast: &N) -> Self {
209 let items = ctx.db.file_items(ctx.file_id); 203 let items = ctx.db.file_items(ctx.file_id);
210 let item_id = items.id_of(ctx.file_id, ast.syntax()); 204 let item_id = items.id_of(ctx.file_id, ast.syntax());
211 Self::from_source_item_id_unchecked(ctx, item_id) 205 Self::from_source_item_id_unchecked(ctx, item_id)
212 } 206 }
213 fn from_source_item_id_unchecked( 207 fn from_source_item_id_unchecked(
214 ctx: LocationCtx<&impl PersistentHirDatabase>, 208 ctx: LocationCtx<&impl DefDatabase>,
215 item_id: SourceFileItemId, 209 item_id: SourceFileItemId,
216 ) -> Self { 210 ) -> Self {
217 let raw = SourceItemId { file_id: ctx.file_id, item_id }; 211 let raw = SourceItemId { file_id: ctx.file_id, item_id };
@@ -219,7 +213,7 @@ pub(crate) trait AstItemDef<N: AstNode>: ArenaId + Clone {
219 213
220 Self::interner(ctx.db.as_ref()).loc2id(&loc) 214 Self::interner(ctx.db.as_ref()).loc2id(&loc)
221 } 215 }
222 fn source(self, db: &impl PersistentHirDatabase) -> (HirFileId, TreeArc<N>) { 216 fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc<N>) {
223 let int = Self::interner(db.as_ref()); 217 let int = Self::interner(db.as_ref());
224 let loc = int.id2loc(self); 218 let loc = int.id2loc(self);
225 let syntax = db.file_item(loc.raw); 219 let syntax = db.file_item(loc.raw);
@@ -227,7 +221,7 @@ pub(crate) trait AstItemDef<N: AstNode>: ArenaId + Clone {
227 N::cast(&syntax).unwrap_or_else(|| panic!("invalid ItemLoc: {:?}", loc.raw)).to_owned(); 221 N::cast(&syntax).unwrap_or_else(|| panic!("invalid ItemLoc: {:?}", loc.raw)).to_owned();
228 (loc.raw.file_id, ast) 222 (loc.raw.file_id, ast)
229 } 223 }
230 fn module(self, db: &impl PersistentHirDatabase) -> Module { 224 fn module(self, db: &impl DefDatabase) -> Module {
231 let int = Self::interner(db.as_ref()); 225 let int = Self::interner(db.as_ref());
232 let loc = int.id2loc(self); 226 let loc = int.id2loc(self);
233 loc.module 227 loc.module
@@ -324,7 +318,7 @@ pub struct SourceFileItems {
324 318
325impl SourceFileItems { 319impl SourceFileItems {
326 pub(crate) fn file_items_query( 320 pub(crate) fn file_items_query(
327 db: &impl PersistentHirDatabase, 321 db: &impl DefDatabase,
328 file_id: HirFileId, 322 file_id: HirFileId,
329 ) -> Arc<SourceFileItems> { 323 ) -> Arc<SourceFileItems> {
330 let source_file = db.hir_parse(file_id); 324 let source_file = db.hir_parse(file_id);
@@ -332,7 +326,7 @@ impl SourceFileItems {
332 } 326 }
333 327
334 pub(crate) fn file_item_query( 328 pub(crate) fn file_item_query(
335 db: &impl PersistentHirDatabase, 329 db: &impl DefDatabase,
336 source_item_id: SourceItemId, 330 source_item_id: SourceItemId,
337 ) -> TreeArc<SyntaxNode> { 331 ) -> TreeArc<SyntaxNode> {
338 let source_file = db.hir_parse(source_item_id.file_id); 332 let source_file = db.hir_parse(source_item_id.file_id);
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs
index 8807a4b56..40d368cd9 100644
--- a/crates/ra_hir/src/impl_block.rs
+++ b/crates/ra_hir/src/impl_block.rs
@@ -9,7 +9,7 @@ use ra_syntax::{
9 9
10use crate::{ 10use crate::{
11 Const, TypeAlias, Function, HirFileId, 11 Const, TypeAlias, Function, HirFileId,
12 HirDatabase, PersistentHirDatabase, 12 HirDatabase, DefDatabase,
13 ModuleDef, Trait, Resolution, 13 ModuleDef, Trait, Resolution,
14 type_ref::TypeRef, 14 type_ref::TypeRef,
15 ids::LocationCtx, 15 ids::LocationCtx,
@@ -59,7 +59,7 @@ impl ImplBlock {
59 } 59 }
60 60
61 /// Returns the syntax of the impl block 61 /// Returns the syntax of the impl block
62 pub fn source(&self, db: &impl PersistentHirDatabase) -> (HirFileId, TreeArc<ast::ImplBlock>) { 62 pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::ImplBlock>) {
63 let source_map = db.impls_in_module_source_map(self.module); 63 let source_map = db.impls_in_module_source_map(self.module);
64 let (file_id, source) = self.module.definition_source(db); 64 let (file_id, source) = self.module.definition_source(db);
65 (file_id, source_map.get(&source, self.impl_id)) 65 (file_id, source_map.get(&source, self.impl_id))
@@ -73,11 +73,11 @@ impl ImplBlock {
73 self.module 73 self.module
74 } 74 }
75 75
76 pub fn target_trait_ref(&self, db: &impl PersistentHirDatabase) -> Option<TypeRef> { 76 pub fn target_trait_ref(&self, db: &impl DefDatabase) -> Option<TypeRef> {
77 db.impls_in_module(self.module).impls[self.impl_id].target_trait().cloned() 77 db.impls_in_module(self.module).impls[self.impl_id].target_trait().cloned()
78 } 78 }
79 79
80 pub fn target_type(&self, db: &impl PersistentHirDatabase) -> TypeRef { 80 pub fn target_type(&self, db: &impl DefDatabase) -> TypeRef {
81 db.impls_in_module(self.module).impls[self.impl_id].target_type().clone() 81 db.impls_in_module(self.module).impls[self.impl_id].target_type().clone()
82 } 82 }
83 83
@@ -97,11 +97,11 @@ impl ImplBlock {
97 None 97 None
98 } 98 }
99 99
100 pub fn items(&self, db: &impl PersistentHirDatabase) -> Vec<ImplItem> { 100 pub fn items(&self, db: &impl DefDatabase) -> Vec<ImplItem> {
101 db.impls_in_module(self.module).impls[self.impl_id].items().to_vec() 101 db.impls_in_module(self.module).impls[self.impl_id].items().to_vec()
102 } 102 }
103 103
104 pub fn generic_params(&self, db: &impl PersistentHirDatabase) -> Arc<GenericParams> { 104 pub fn generic_params(&self, db: &impl DefDatabase) -> Arc<GenericParams> {
105 db.generic_params((*self).into()) 105 db.generic_params((*self).into())
106 } 106 }
107 107
@@ -124,7 +124,7 @@ pub struct ImplData {
124 124
125impl ImplData { 125impl ImplData {
126 pub(crate) fn from_ast( 126 pub(crate) fn from_ast(
127 db: &impl PersistentHirDatabase, 127 db: &impl DefDatabase,
128 file_id: HirFileId, 128 file_id: HirFileId,
129 module: Module, 129 module: Module,
130 node: &ast::ImplBlock, 130 node: &ast::ImplBlock,
@@ -161,7 +161,7 @@ impl ImplData {
161} 161}
162 162
163#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 163#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
164//TODO: rename to ImplDef? 164//FIXME: rename to ImplDef?
165pub enum ImplItem { 165pub enum ImplItem {
166 Method(Function), 166 Method(Function),
167 Const(Const), 167 Const(Const),
@@ -193,11 +193,7 @@ pub struct ModuleImplBlocks {
193} 193}
194 194
195impl ModuleImplBlocks { 195impl ModuleImplBlocks {
196 fn collect( 196 fn collect(db: &impl DefDatabase, module: Module, source_map: &mut ImplSourceMap) -> Self {
197 db: &impl PersistentHirDatabase,
198 module: Module,
199 source_map: &mut ImplSourceMap,
200 ) -> Self {
201 let mut m = ModuleImplBlocks { 197 let mut m = ModuleImplBlocks {
202 module, 198 module,
203 impls: Arena::default(), 199 impls: Arena::default(),
@@ -228,7 +224,7 @@ impl ModuleImplBlocks {
228} 224}
229 225
230pub(crate) fn impls_in_module_with_source_map_query( 226pub(crate) fn impls_in_module_with_source_map_query(
231 db: &impl PersistentHirDatabase, 227 db: &impl DefDatabase,
232 module: Module, 228 module: Module,
233) -> (Arc<ModuleImplBlocks>, Arc<ImplSourceMap>) { 229) -> (Arc<ModuleImplBlocks>, Arc<ImplSourceMap>) {
234 let mut source_map = ImplSourceMap::default(); 230 let mut source_map = ImplSourceMap::default();
@@ -238,15 +234,12 @@ pub(crate) fn impls_in_module_with_source_map_query(
238 (Arc::new(result), Arc::new(source_map)) 234 (Arc::new(result), Arc::new(source_map))
239} 235}
240 236
241pub(crate) fn impls_in_module( 237pub(crate) fn impls_in_module(db: &impl DefDatabase, module: Module) -> Arc<ModuleImplBlocks> {
242 db: &impl PersistentHirDatabase,
243 module: Module,
244) -> Arc<ModuleImplBlocks> {
245 db.impls_in_module_with_source_map(module).0 238 db.impls_in_module_with_source_map(module).0
246} 239}
247 240
248pub(crate) fn impls_in_module_source_map_query( 241pub(crate) fn impls_in_module_source_map_query(
249 db: &impl PersistentHirDatabase, 242 db: &impl DefDatabase,
250 module: Module, 243 module: Module,
251) -> Arc<ImplSourceMap> { 244) -> Arc<ImplSourceMap> {
252 db.impls_in_module_with_source_map(module).1 245 db.impls_in_module_with_source_map(module).1
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 5926b5758..a89c916f8 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -43,7 +43,7 @@ mod code_model_impl;
43mod marks; 43mod marks;
44 44
45use crate::{ 45use crate::{
46 db::{HirDatabase, PersistentHirDatabase}, 46 db::{HirDatabase, DefDatabase},
47 name::{AsName, KnownName}, 47 name::{AsName, KnownName},
48 ids::{SourceItemId, SourceFileItems}, 48 ids::{SourceItemId, SourceFileItems},
49}; 49};
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs
index f1cad77c5..10d4c1b8c 100644
--- a/crates/ra_hir/src/mock.rs
+++ b/crates/ra_hir/src/mock.rs
@@ -13,11 +13,7 @@ use crate::{db, HirInterner};
13 13
14pub const WORKSPACE: SourceRootId = SourceRootId(0); 14pub const WORKSPACE: SourceRootId = SourceRootId(0);
15 15
16#[salsa::database( 16#[salsa::database(ra_db::SourceDatabaseStorage, db::HirDatabaseStorage, db::DefDatabaseStorage)]
17 ra_db::SourceDatabaseStorage,
18 db::HirDatabaseStorage,
19 db::PersistentHirDatabaseStorage
20)]
21#[derive(Debug)] 17#[derive(Debug)]
22pub struct MockDatabase { 18pub struct MockDatabase {
23 events: Mutex<Option<Vec<salsa::Event<MockDatabase>>>>, 19 events: Mutex<Option<Vec<salsa::Event<MockDatabase>>>>,
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs
index edd2f25f7..d361cf9e6 100644
--- a/crates/ra_hir/src/nameres.rs
+++ b/crates/ra_hir/src/nameres.rs
@@ -62,7 +62,7 @@ use test_utils::tested_by;
62 62
63use crate::{ 63use crate::{
64 ModuleDef, Name, Crate, Module, Problem, 64 ModuleDef, Name, Crate, Module, Problem,
65 PersistentHirDatabase, Path, PathKind, HirFileId, 65 DefDatabase, Path, PathKind, HirFileId,
66 ids::{SourceItemId, SourceFileItemId, MacroCallId}, 66 ids::{SourceItemId, SourceFileItemId, MacroCallId},
67}; 67};
68 68
@@ -196,10 +196,7 @@ enum ReachedFixedPoint {
196} 196}
197 197
198impl CrateDefMap { 198impl CrateDefMap {
199 pub(crate) fn crate_def_map_query( 199 pub(crate) fn crate_def_map_query(db: &impl DefDatabase, krate: Crate) -> Arc<CrateDefMap> {
200 db: &impl PersistentHirDatabase,
201 krate: Crate,
202 ) -> Arc<CrateDefMap> {
203 let start = std::time::Instant::now(); 200 let start = std::time::Instant::now();
204 let def_map = { 201 let def_map = {
205 let edition = krate.edition(db); 202 let edition = krate.edition(db);
@@ -268,7 +265,7 @@ impl CrateDefMap {
268 265
269 pub(crate) fn resolve_path( 266 pub(crate) fn resolve_path(
270 &self, 267 &self,
271 db: &impl PersistentHirDatabase, 268 db: &impl DefDatabase,
272 original_module: CrateModuleId, 269 original_module: CrateModuleId,
273 path: &Path, 270 path: &Path,
274 ) -> (PerNs<ModuleDef>, Option<usize>) { 271 ) -> (PerNs<ModuleDef>, Option<usize>) {
@@ -280,7 +277,7 @@ impl CrateDefMap {
280 // the result. 277 // the result.
281 fn resolve_path_fp( 278 fn resolve_path_fp(
282 &self, 279 &self,
283 db: &impl PersistentHirDatabase, 280 db: &impl DefDatabase,
284 mode: ResolveMode, 281 mode: ResolveMode,
285 original_module: CrateModuleId, 282 original_module: CrateModuleId,
286 path: &Path, 283 path: &Path,
@@ -296,7 +293,7 @@ impl CrateDefMap {
296 // plain import or absolute path in 2015: crate-relative with 293 // plain import or absolute path in 2015: crate-relative with
297 // fallback to extern prelude (with the simplification in 294 // fallback to extern prelude (with the simplification in
298 // rust-lang/rust#57745) 295 // rust-lang/rust#57745)
299 // TODO there must be a nicer way to write this condition 296 // FIXME there must be a nicer way to write this condition
300 PathKind::Plain | PathKind::Abs 297 PathKind::Plain | PathKind::Abs
301 if self.edition == Edition::Edition2015 298 if self.edition == Edition::Edition2015
302 && (path.kind == PathKind::Abs || mode == ResolveMode::Import) => 299 && (path.kind == PathKind::Abs || mode == ResolveMode::Import) =>
@@ -422,7 +419,7 @@ impl CrateDefMap {
422 419
423 pub(crate) fn resolve_name_in_module( 420 pub(crate) fn resolve_name_in_module(
424 &self, 421 &self,
425 db: &impl PersistentHirDatabase, 422 db: &impl DefDatabase,
426 module: CrateModuleId, 423 module: CrateModuleId,
427 name: &Name, 424 name: &Name,
428 ) -> PerNs<ModuleDef> { 425 ) -> PerNs<ModuleDef> {
@@ -442,7 +439,7 @@ impl CrateDefMap {
442 self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it)) 439 self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it))
443 } 440 }
444 441
445 fn resolve_in_prelude(&self, db: &impl PersistentHirDatabase, name: &Name) -> PerNs<ModuleDef> { 442 fn resolve_in_prelude(&self, db: &impl DefDatabase, name: &Name) -> PerNs<ModuleDef> {
446 if let Some(prelude) = self.prelude { 443 if let Some(prelude) = self.prelude {
447 let resolution = if prelude.krate == self.krate { 444 let resolution = if prelude.krate == self.krate {
448 self[prelude.module_id].scope.items.get(name).cloned() 445 self[prelude.module_id].scope.items.get(name).cloned()
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs
index 3ea8d592c..c5b73cfbe 100644
--- a/crates/ra_hir/src/nameres/collector.rs
+++ b/crates/ra_hir/src/nameres/collector.rs
@@ -6,7 +6,7 @@ use ra_db::FileId;
6 6
7use crate::{ 7use crate::{
8 Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias, 8 Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias,
9 PersistentHirDatabase, HirFileId, Name, Path, Problem, Crate, 9 DefDatabase, HirFileId, Name, Path, Problem, Crate,
10 KnownName, 10 KnownName,
11 nameres::{Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode, raw}, 11 nameres::{Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode, raw},
12 ids::{AstItemDef, LocationCtx, MacroCallLoc, SourceItemId, MacroCallId}, 12 ids::{AstItemDef, LocationCtx, MacroCallLoc, SourceItemId, MacroCallId},
@@ -14,10 +14,7 @@ use crate::{
14 14
15use super::{CrateDefMap, CrateModuleId, ModuleData, CrateMacroId}; 15use super::{CrateDefMap, CrateModuleId, ModuleData, CrateMacroId};
16 16
17pub(super) fn collect_defs( 17pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap {
18 db: &impl PersistentHirDatabase,
19 mut def_map: CrateDefMap,
20) -> CrateDefMap {
21 // populate external prelude 18 // populate external prelude
22 for dep in def_map.krate.dependencies(db) { 19 for dep in def_map.krate.dependencies(db) {
23 log::debug!("crate dep {:?} -> {:?}", dep.name, dep.krate); 20 log::debug!("crate dep {:?} -> {:?}", dep.name, dep.krate);
@@ -57,7 +54,7 @@ struct DefCollector<DB> {
57 54
58impl<'a, DB> DefCollector<&'a DB> 55impl<'a, DB> DefCollector<&'a DB>
59where 56where
60 DB: PersistentHirDatabase, 57 DB: DefDatabase,
61{ 58{
62 fn collect(&mut self) { 59 fn collect(&mut self) {
63 let crate_graph = self.db.crate_graph(); 60 let crate_graph = self.db.crate_graph();
@@ -370,7 +367,7 @@ struct ModCollector<'a, D> {
370 367
371impl<DB> ModCollector<'_, &'_ mut DefCollector<&'_ DB>> 368impl<DB> ModCollector<'_, &'_ mut DefCollector<&'_ DB>>
372where 369where
373 DB: PersistentHirDatabase, 370 DB: DefDatabase,
374{ 371{
375 fn collect(&mut self, items: &[raw::RawItem]) { 372 fn collect(&mut self, items: &[raw::RawItem]) {
376 for item in items { 373 for item in items {
@@ -523,7 +520,7 @@ fn is_macro_rules(path: &Path) -> bool {
523} 520}
524 521
525fn resolve_submodule( 522fn resolve_submodule(
526 db: &impl PersistentHirDatabase, 523 db: &impl DefDatabase,
527 file_id: HirFileId, 524 file_id: HirFileId,
528 name: &Name, 525 name: &Name,
529 is_root: bool, 526 is_root: bool,
diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs
index 3226bbf0d..f8ba398ec 100644
--- a/crates/ra_hir/src/nameres/raw.rs
+++ b/crates/ra_hir/src/nameres/raw.rs
@@ -12,7 +12,7 @@ use ra_syntax::{
12}; 12};
13 13
14use crate::{ 14use crate::{
15 PersistentHirDatabase, Name, AsName, Path, HirFileId, ModuleSource, 15 DefDatabase, Name, AsName, Path, HirFileId, ModuleSource,
16 ids::{SourceFileItemId, SourceFileItems}, 16 ids::{SourceFileItemId, SourceFileItems},
17}; 17};
18 18
@@ -47,15 +47,12 @@ impl ImportSourceMap {
47} 47}
48 48
49impl RawItems { 49impl RawItems {
50 pub(crate) fn raw_items_query( 50 pub(crate) fn raw_items_query(db: &impl DefDatabase, file_id: FileId) -> Arc<RawItems> {
51 db: &impl PersistentHirDatabase,
52 file_id: FileId,
53 ) -> Arc<RawItems> {
54 db.raw_items_with_source_map(file_id).0 51 db.raw_items_with_source_map(file_id).0
55 } 52 }
56 53
57 pub(crate) fn raw_items_with_source_map_query( 54 pub(crate) fn raw_items_with_source_map_query(
58 db: &impl PersistentHirDatabase, 55 db: &impl DefDatabase,
59 file_id: FileId, 56 file_id: FileId,
60 ) -> (Arc<RawItems>, Arc<ImportSourceMap>) { 57 ) -> (Arc<RawItems>, Arc<ImportSourceMap>) {
61 let mut collector = RawItemsCollector { 58 let mut collector = RawItemsCollector {
diff --git a/crates/ra_hir/src/path.rs b/crates/ra_hir/src/path.rs
index 6ca373e34..6cc8104f4 100644
--- a/crates/ra_hir/src/path.rs
+++ b/crates/ra_hir/src/path.rs
@@ -96,7 +96,7 @@ impl Path {
96 if let Some(q) = path.qualifier() { 96 if let Some(q) = path.qualifier() {
97 return Some(q); 97 return Some(q);
98 } 98 }
99 // TODO: this bottom up traversal is not too precise. 99 // FIXME: this bottom up traversal is not too precise.
100 // Should we handle do a top-down analysis, recording results? 100 // Should we handle do a top-down analysis, recording results?
101 let use_tree_list = path.syntax().ancestors().find_map(ast::UseTreeList::cast)?; 101 let use_tree_list = path.syntax().ancestors().find_map(ast::UseTreeList::cast)?;
102 let use_tree = use_tree_list.parent_use_tree(); 102 let use_tree = use_tree_list.parent_use_tree();
@@ -166,7 +166,7 @@ fn expand_use_tree<'a>(
166 // or `use something::{path::{inner::{innerer}}}` (prefix is `something::path`, path is `inner`) 166 // or `use something::{path::{inner::{innerer}}}` (prefix is `something::path`, path is `inner`)
167 Some(path) => match convert_path(prefix, path) { 167 Some(path) => match convert_path(prefix, path) {
168 Some(it) => Some(it), 168 Some(it) => Some(it),
169 None => return, // TODO: report errors somewhere 169 None => return, // FIXME: report errors somewhere
170 }, 170 },
171 }; 171 };
172 for child_tree in use_tree_list.use_trees() { 172 for child_tree in use_tree_list.use_trees() {
@@ -194,7 +194,7 @@ fn expand_use_tree<'a>(
194 cb(path, Some(segment), alias) 194 cb(path, Some(segment), alias)
195 }; 195 };
196 } 196 }
197 // TODO: report errors somewhere 197 // FIXME: report errors somewhere
198 // We get here if we do 198 // We get here if we do
199 } 199 }
200 } 200 }
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs
index 59af4ec60..f28154517 100644
--- a/crates/ra_hir/src/resolve.rs
+++ b/crates/ra_hir/src/resolve.rs
@@ -19,7 +19,7 @@ pub struct Resolver {
19 scopes: Vec<Scope>, 19 scopes: Vec<Scope>,
20} 20}
21 21
22// TODO how to store these best 22// FIXME how to store these best
23#[derive(Debug, Clone)] 23#[derive(Debug, Clone)]
24pub(crate) struct ModuleItemMap { 24pub(crate) struct ModuleItemMap {
25 crate_def_map: Arc<CrateDefMap>, 25 crate_def_map: Arc<CrateDefMap>,
@@ -260,7 +260,7 @@ impl Scope {
260 fn collect_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, PerNs<Resolution>)) { 260 fn collect_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, PerNs<Resolution>)) {
261 match self { 261 match self {
262 Scope::ModuleScope(m) => { 262 Scope::ModuleScope(m) => {
263 // TODO: should we provide `self` here? 263 // FIXME: should we provide `self` here?
264 // f( 264 // f(
265 // Name::self_param(), 265 // Name::self_param(),
266 // PerNs::types(Resolution::Def { 266 // PerNs::types(Resolution::Def {
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 902110913..3645b73b4 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -164,7 +164,7 @@ pub fn resolver_for_position(db: &impl HirDatabase, position: FilePosition) -> R
164 let scope = scopes.scope_for_offset(position.offset); 164 let scope = scopes.scope_for_offset(position.offset);
165 Some(expr::resolver_for_scope(func.body(db), db, scope)) 165 Some(expr::resolver_for_scope(func.body(db), db, scope))
166 } else { 166 } else {
167 // TODO const/static/array length 167 // FIXME const/static/array length
168 None 168 None
169 } 169 }
170 } else { 170 } else {
@@ -184,7 +184,7 @@ pub fn resolver_for_node(db: &impl HirDatabase, file_id: FileId, node: &SyntaxNo
184 let scope = scopes.scope_for(&node); 184 let scope = scopes.scope_for(&node);
185 Some(expr::resolver_for_scope(func.body(db), db, scope)) 185 Some(expr::resolver_for_scope(func.body(db), db, scope))
186 } else { 186 } else {
187 // TODO const/static/array length 187 // FIXME const/static/array length
188 None 188 None
189 } 189 }
190 } else { 190 } else {
@@ -212,7 +212,7 @@ fn try_get_resolver_for_node(
212 } else if let Some(f) = ast::FnDef::cast(node) { 212 } else if let Some(f) = ast::FnDef::cast(node) {
213 function_from_source(db, file_id, f).map(|f| f.resolver(db)) 213 function_from_source(db, file_id, f).map(|f| f.resolver(db))
214 } else { 214 } else {
215 // TODO add missing cases 215 // FIXME add missing cases
216 None 216 None
217 } 217 }
218} 218}
diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs
index d95879e46..ab5f008ef 100644
--- a/crates/ra_hir/src/ty/autoderef.rs
+++ b/crates/ra_hir/src/ty/autoderef.rs
@@ -15,7 +15,7 @@ impl Ty {
15 } 15 }
16 16
17 fn autoderef_step(&self, _db: &impl HirDatabase) -> Option<Ty> { 17 fn autoderef_step(&self, _db: &impl HirDatabase) -> Option<Ty> {
18 // TODO Deref::deref 18 // FIXME Deref::deref
19 self.builtin_deref() 19 self.builtin_deref()
20 } 20 }
21} 21}
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 7cf465266..cff7e7481 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -207,7 +207,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
207 fn make_ty(&mut self, type_ref: &TypeRef) -> Ty { 207 fn make_ty(&mut self, type_ref: &TypeRef) -> Ty {
208 let ty = Ty::from_hir( 208 let ty = Ty::from_hir(
209 self.db, 209 self.db,
210 // TODO use right resolver for block 210 // FIXME use right resolver for block
211 &self.resolver, 211 &self.resolver,
212 type_ref, 212 type_ref,
213 ); 213 );
@@ -407,18 +407,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
407 407
408 let substs = 408 let substs =
409 Ty::substs_from_path_segment(self.db, &self.resolver, segment, typable); 409 Ty::substs_from_path_segment(self.db, &self.resolver, segment, typable);
410 self.db.type_for_def(typable, Namespace::Types).apply_substs(substs) 410 self.db.type_for_def(typable, Namespace::Types).subst(&substs)
411 } 411 }
412 Resolution::LocalBinding(_) => { 412 Resolution::LocalBinding(_) => {
413 // can't have a local binding in an associated item path 413 // can't have a local binding in an associated item path
414 return None; 414 return None;
415 } 415 }
416 Resolution::GenericParam(..) => { 416 Resolution::GenericParam(..) => {
417 // TODO associated item of generic param 417 // FIXME associated item of generic param
418 return None; 418 return None;
419 } 419 }
420 Resolution::SelfType(_) => { 420 Resolution::SelfType(_) => {
421 // TODO associated item of self type 421 // FIXME associated item of self type
422 return None; 422 return None;
423 } 423 }
424 }; 424 };
@@ -446,7 +446,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
446 } 446 }
447 } 447 }
448 448
449 // TODO: Resolve associated types 449 // FIXME: Resolve associated types
450 crate::ImplItem::TypeAlias(_) => None, 450 crate::ImplItem::TypeAlias(_) => None,
451 }; 451 };
452 match matching_def { 452 match matching_def {
@@ -466,7 +466,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
466 let typable: Option<TypableDef> = def.into(); 466 let typable: Option<TypableDef> = def.into();
467 let typable = typable?; 467 let typable = typable?;
468 let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable); 468 let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable);
469 let ty = self.db.type_for_def(typable, Namespace::Values).apply_substs(substs); 469 let ty = self.db.type_for_def(typable, Namespace::Values).subst(&substs);
470 let ty = self.insert_type_vars(ty); 470 let ty = self.insert_type_vars(ty);
471 Some(ty) 471 Some(ty)
472 } 472 }
@@ -504,7 +504,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
504 return (Ty::Unknown, None); 504 return (Ty::Unknown, None);
505 } 505 }
506 Some(Resolution::SelfType(..)) => { 506 Some(Resolution::SelfType(..)) => {
507 // TODO this is allowed in an impl for a struct, handle this 507 // FIXME this is allowed in an impl for a struct, handle this
508 return (Ty::Unknown, None); 508 return (Ty::Unknown, None);
509 } 509 }
510 None => return (Ty::Unknown, None), 510 None => return (Ty::Unknown, None),
@@ -513,7 +513,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
513 None => return (Ty::Unknown, None), 513 None => return (Ty::Unknown, None),
514 Some(it) => it, 514 Some(it) => it,
515 }; 515 };
516 // TODO remove the duplication between here and `Ty::from_path`? 516 // FIXME remove the duplication between here and `Ty::from_path`?
517 let substs = Ty::substs_from_path(self.db, resolver, path, def); 517 let substs = Ty::substs_from_path(self.db, resolver, path, def);
518 match def { 518 match def {
519 TypableDef::Struct(s) => { 519 TypableDef::Struct(s) => {
@@ -590,7 +590,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
590 | Pat::Struct { .. } 590 | Pat::Struct { .. }
591 | Pat::Range { .. } 591 | Pat::Range { .. }
592 | Pat::Slice { .. } => true, 592 | Pat::Slice { .. } => true,
593 // TODO: Path/Lit might actually evaluate to ref, but inference is unimplemented. 593 // FIXME: Path/Lit might actually evaluate to ref, but inference is unimplemented.
594 Pat::Path(..) | Pat::Lit(..) => true, 594 Pat::Path(..) | Pat::Lit(..) => true,
595 Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Missing => false, 595 Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Missing => false,
596 }; 596 };
@@ -635,7 +635,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
635 let expectation = match expected.as_reference() { 635 let expectation = match expected.as_reference() {
636 Some((inner_ty, exp_mut)) => { 636 Some((inner_ty, exp_mut)) => {
637 if *mutability != exp_mut { 637 if *mutability != exp_mut {
638 // TODO: emit type error? 638 // FIXME: emit type error?
639 } 639 }
640 inner_ty 640 inner_ty
641 } 641 }
@@ -651,7 +651,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
651 self.infer_struct_pat(p.as_ref(), fields, expected, default_bm) 651 self.infer_struct_pat(p.as_ref(), fields, expected, default_bm)
652 } 652 }
653 Pat::Path(path) => { 653 Pat::Path(path) => {
654 // TODO use correct resolver for the surrounding expression 654 // FIXME use correct resolver for the surrounding expression
655 let resolver = self.resolver.clone(); 655 let resolver = self.resolver.clone();
656 self.infer_path_expr(&resolver, &path, pat.into()).unwrap_or(Ty::Unknown) 656 self.infer_path_expr(&resolver, &path, pat.into()).unwrap_or(Ty::Unknown)
657 } 657 }
@@ -741,7 +741,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
741 Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected), 741 Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected),
742 Expr::Loop { body } => { 742 Expr::Loop { body } => {
743 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 743 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
744 // TODO handle break with value 744 // FIXME handle break with value
745 Ty::simple(TypeCtor::Never) 745 Ty::simple(TypeCtor::Never)
746 } 746 }
747 Expr::While { condition, body } => { 747 Expr::While { condition, body } => {
@@ -769,7 +769,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
769 self.infer_pat(*arg_pat, &expected, BindingMode::default()); 769 self.infer_pat(*arg_pat, &expected, BindingMode::default());
770 } 770 }
771 771
772 // TODO: infer lambda type etc. 772 // FIXME: infer lambda type etc.
773 let _body_ty = self.infer_expr(*body, &Expectation::none()); 773 let _body_ty = self.infer_expr(*body, &Expectation::none());
774 Ty::Unknown 774 Ty::Unknown
775 } 775 }
@@ -795,7 +795,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
795 }, 795 },
796 _ => { 796 _ => {
797 // not callable 797 // not callable
798 // TODO report an error? 798 // FIXME report an error?
799 (Vec::new(), Ty::Unknown) 799 (Vec::new(), Ty::Unknown)
800 } 800 }
801 }; 801 };
@@ -894,14 +894,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
894 expected.ty 894 expected.ty
895 } 895 }
896 Expr::Path(p) => { 896 Expr::Path(p) => {
897 // TODO this could be more efficient... 897 // FIXME this could be more efficient...
898 let resolver = expr::resolver_for_expr(self.body.clone(), self.db, tgt_expr); 898 let resolver = expr::resolver_for_expr(self.body.clone(), self.db, tgt_expr);
899 self.infer_path_expr(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) 899 self.infer_path_expr(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown)
900 } 900 }
901 Expr::Continue => Ty::simple(TypeCtor::Never), 901 Expr::Continue => Ty::simple(TypeCtor::Never),
902 Expr::Break { expr } => { 902 Expr::Break { expr } => {
903 if let Some(expr) = expr { 903 if let Some(expr) = expr {
904 // TODO handle break with value 904 // FIXME handle break with value
905 self.infer_expr(*expr, &Expectation::none()); 905 self.infer_expr(*expr, &Expectation::none());
906 } 906 }
907 Ty::simple(TypeCtor::Never) 907 Ty::simple(TypeCtor::Never)
@@ -957,21 +957,21 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
957 Expr::Cast { expr, type_ref } => { 957 Expr::Cast { expr, type_ref } => {
958 let _inner_ty = self.infer_expr(*expr, &Expectation::none()); 958 let _inner_ty = self.infer_expr(*expr, &Expectation::none());
959 let cast_ty = self.make_ty(type_ref); 959 let cast_ty = self.make_ty(type_ref);
960 // TODO check the cast... 960 // FIXME check the cast...
961 cast_ty 961 cast_ty
962 } 962 }
963 Expr::Ref { expr, mutability } => { 963 Expr::Ref { expr, mutability } => {
964 let expectation = 964 let expectation =
965 if let Some((exp_inner, exp_mutability)) = &expected.ty.as_reference() { 965 if let Some((exp_inner, exp_mutability)) = &expected.ty.as_reference() {
966 if *exp_mutability == Mutability::Mut && *mutability == Mutability::Shared { 966 if *exp_mutability == Mutability::Mut && *mutability == Mutability::Shared {
967 // TODO: throw type error - expected mut reference but found shared ref, 967 // FIXME: throw type error - expected mut reference but found shared ref,
968 // which cannot be coerced 968 // which cannot be coerced
969 } 969 }
970 Expectation::has_type(Ty::clone(exp_inner)) 970 Expectation::has_type(Ty::clone(exp_inner))
971 } else { 971 } else {
972 Expectation::none() 972 Expectation::none()
973 }; 973 };
974 // TODO reference coercions etc. 974 // FIXME reference coercions etc.
975 let inner_ty = self.infer_expr(*expr, &expectation); 975 let inner_ty = self.infer_expr(*expr, &expectation);
976 Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) 976 Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty)
977 } 977 }
@@ -982,7 +982,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
982 if let Some(derefed_ty) = inner_ty.builtin_deref() { 982 if let Some(derefed_ty) = inner_ty.builtin_deref() {
983 derefed_ty 983 derefed_ty
984 } else { 984 } else {
985 // TODO Deref::deref 985 // FIXME Deref::deref
986 Ty::Unknown 986 Ty::Unknown
987 } 987 }
988 } 988 }
@@ -1002,7 +1002,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1002 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => { 1002 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => {
1003 inner_ty 1003 inner_ty
1004 } 1004 }
1005 // TODO: resolve ops::Neg trait 1005 // FIXME: resolve ops::Neg trait
1006 _ => Ty::Unknown, 1006 _ => Ty::Unknown,
1007 } 1007 }
1008 } 1008 }
@@ -1013,7 +1013,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1013 _ => Ty::Unknown, 1013 _ => Ty::Unknown,
1014 }, 1014 },
1015 Ty::Infer(InferTy::IntVar(..)) => inner_ty, 1015 Ty::Infer(InferTy::IntVar(..)) => inner_ty,
1016 // TODO: resolve ops::Not trait for inner_ty 1016 // FIXME: resolve ops::Not trait for inner_ty
1017 _ => Ty::Unknown, 1017 _ => Ty::Unknown,
1018 } 1018 }
1019 } 1019 }
@@ -1028,12 +1028,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1028 _ => Expectation::none(), 1028 _ => Expectation::none(),
1029 }; 1029 };
1030 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); 1030 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation);
1031 // TODO: find implementation of trait corresponding to operation 1031 // FIXME: find implementation of trait corresponding to operation
1032 // symbol and resolve associated `Output` type 1032 // symbol and resolve associated `Output` type
1033 let rhs_expectation = op::binary_op_rhs_expectation(*op, lhs_ty); 1033 let rhs_expectation = op::binary_op_rhs_expectation(*op, lhs_ty);
1034 let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation)); 1034 let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation));
1035 1035
1036 // TODO: similar as above, return ty is often associated trait type 1036 // FIXME: similar as above, return ty is often associated trait type
1037 op::binary_op_return_ty(*op, rhs_ty) 1037 op::binary_op_return_ty(*op, rhs_ty)
1038 } 1038 }
1039 _ => Ty::Unknown, 1039 _ => Ty::Unknown,
@@ -1227,7 +1227,7 @@ impl InferTy {
1227#[derive(Clone, PartialEq, Eq, Debug)] 1227#[derive(Clone, PartialEq, Eq, Debug)]
1228struct Expectation { 1228struct Expectation {
1229 ty: Ty, 1229 ty: Ty,
1230 // TODO: In some cases, we need to be aware whether the expectation is that 1230 // FIXME: In some cases, we need to be aware whether the expectation is that
1231 // the type match exactly what we passed, or whether it just needs to be 1231 // the type match exactly what we passed, or whether it just needs to be
1232 // coercible to the expected type. See Expectation::rvalue_hint in rustc. 1232 // coercible to the expected type. See Expectation::rvalue_hint in rustc.
1233} 1233}
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs
index 7f9af307b..003a89f0d 100644
--- a/crates/ra_hir/src/ty/lower.rs
+++ b/crates/ra_hir/src/ty/lower.rs
@@ -60,7 +60,7 @@ impl Ty {
60 60
61 pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Self { 61 pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Self {
62 if let Some(name) = path.as_ident() { 62 if let Some(name) = path.as_ident() {
63 // TODO handle primitive type names in resolver as well? 63 // FIXME handle primitive type names in resolver as well?
64 if let Some(int_ty) = primitive::IntTy::from_type_name(name) { 64 if let Some(int_ty) = primitive::IntTy::from_type_name(name) {
65 return Ty::simple(TypeCtor::Int(primitive::UncertainIntTy::Known(int_ty))); 65 return Ty::simple(TypeCtor::Int(primitive::UncertainIntTy::Known(int_ty)));
66 } else if let Some(float_ty) = primitive::FloatTy::from_type_name(name) { 66 } else if let Some(float_ty) = primitive::FloatTy::from_type_name(name) {
@@ -87,7 +87,7 @@ impl Ty {
87 Some(Resolution::GenericParam(idx)) => { 87 Some(Resolution::GenericParam(idx)) => {
88 return Ty::Param { 88 return Ty::Param {
89 idx, 89 idx,
90 // TODO: maybe return name in resolution? 90 // FIXME: maybe return name in resolution?
91 name: path 91 name: path
92 .as_ident() 92 .as_ident()
93 .expect("generic param should be single-segment path") 93 .expect("generic param should be single-segment path")
@@ -139,7 +139,7 @@ impl Ty {
139 } 139 }
140 } 140 }
141 // add placeholders for args that were not provided 141 // add placeholders for args that were not provided
142 // TODO: handle defaults 142 // FIXME: handle defaults
143 let supplied_params = substs.len(); 143 let supplied_params = substs.len();
144 for _ in supplied_params..def_generics.count_params_including_parent() { 144 for _ in supplied_params..def_generics.count_params_including_parent() {
145 substs.push(Ty::Unknown); 145 substs.push(Ty::Unknown);
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index ed75bfaee..b1684acf9 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -120,7 +120,7 @@ fn def_crate(db: &impl HirDatabase, ty: &Ty) -> Option<Crate> {
120} 120}
121 121
122impl Ty { 122impl Ty {
123 // TODO: cache this as a query? 123 // FIXME: cache this as a query?
124 // - if so, what signature? (TyFingerprint, Name)? 124 // - if so, what signature? (TyFingerprint, Name)?
125 // - or maybe cache all names and def_ids of methods per fingerprint? 125 // - or maybe cache all names and def_ids of methods per fingerprint?
126 /// Look up the method with the given name, returning the actual autoderefed 126 /// Look up the method with the given name, returning the actual autoderefed
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index 0f2172ddf..5d8ad4aa7 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -1792,6 +1792,29 @@ fn test<R>(query_response: Canonical<QueryResponse<R>>) {
1792} 1792}
1793 1793
1794#[test] 1794#[test]
1795fn bug_1030() {
1796 assert_snapshot_matches!(infer(r#"
1797struct HashSet<T, H>;
1798struct FxHasher;
1799type FxHashSet<T> = HashSet<T, FxHasher>;
1800
1801impl<T, H> HashSet<T, H> {
1802 fn default() -> HashSet<T, H> {}
1803}
1804
1805pub fn main_loop() {
1806 FxHashSet::default();
1807}
1808"#),
1809 @r###"
1810[144; 146) '{}': ()
1811[169; 198) '{ ...t(); }': ()
1812[175; 193) 'FxHash...efault': fn default<{unknown}, {unknown}>() -> HashSet<T, H>
1813[175; 195) 'FxHash...ault()': HashSet<{unknown}, {unknown}>"###
1814 );
1815}
1816
1817#[test]
1795fn cross_crate_associated_method_call() { 1818fn cross_crate_associated_method_call() {
1796 let (mut db, pos) = MockDatabase::with_position( 1819 let (mut db, pos) = MockDatabase::with_position(
1797 r#" 1820 r#"
diff --git a/crates/ra_hir/src/type_alias.rs b/crates/ra_hir/src/type_alias.rs
index d02762d20..e35adcb2f 100644
--- a/crates/ra_hir/src/type_alias.rs
+++ b/crates/ra_hir/src/type_alias.rs
@@ -2,12 +2,9 @@
2 2
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use crate::{TypeAlias, db::PersistentHirDatabase, type_ref::TypeRef}; 5use crate::{TypeAlias, db::DefDatabase, type_ref::TypeRef};
6 6
7pub(crate) fn type_alias_ref_query( 7pub(crate) fn type_alias_ref_query(db: &impl DefDatabase, typ: TypeAlias) -> Arc<TypeRef> {
8 db: &impl PersistentHirDatabase,
9 typ: TypeAlias,
10) -> Arc<TypeRef> {
11 let (_, node) = typ.source(db); 8 let (_, node) = typ.source(db);
12 Arc::new(TypeRef::from_ast_opt(node.type_ref())) 9 Arc::new(TypeRef::from_ast_opt(node.type_ref()))
13} 10}
diff --git a/crates/ra_ide_api/Cargo.toml b/crates/ra_ide_api/Cargo.toml
index ac8c8057b..c64226801 100644
--- a/crates/ra_ide_api/Cargo.toml
+++ b/crates/ra_ide_api/Cargo.toml
@@ -10,7 +10,7 @@ join_to_string = "0.1.3"
10log = "0.4.5" 10log = "0.4.5"
11relative-path = "0.4.0" 11relative-path = "0.4.0"
12rayon = "1.0.2" 12rayon = "1.0.2"
13fst = "0.3.1" 13fst = { version = "0.3.1", default-features = false }
14rustc-hash = "1.0" 14rustc-hash = "1.0"
15parking_lot = "0.7.0" 15parking_lot = "0.7.0"
16unicase = "2.2.0" 16unicase = "2.2.0"
@@ -23,13 +23,19 @@ ra_syntax = { path = "../ra_syntax" }
23ra_ide_api_light = { path = "../ra_ide_api_light" } 23ra_ide_api_light = { path = "../ra_ide_api_light" }
24ra_text_edit = { path = "../ra_text_edit" } 24ra_text_edit = { path = "../ra_text_edit" }
25ra_db = { path = "../ra_db" } 25ra_db = { path = "../ra_db" }
26ra_fmt = { path = "../ra_fmt" }
26hir = { path = "../ra_hir", package = "ra_hir" } 27hir = { path = "../ra_hir", package = "ra_hir" }
27test_utils = { path = "../test_utils" } 28test_utils = { path = "../test_utils" }
28ra_assists = { path = "../ra_assists" } 29ra_assists = { path = "../ra_assists" }
29 30
30[dev-dependencies] 31[dev-dependencies]
31insta = "0.7.0" 32insta = "0.7.0"
32proptest = "0.9.0" 33
34[dev-dependencies.proptest]
35version = "0.9.0"
36# Disable `fork` feature to allow compiling on webassembly
37default-features = false
38features = ["std", "bit-set", "break-dead-code"]
33 39
34[features] 40[features]
35jemalloc = [ "jemallocator", "jemalloc-ctl" ] 41jemalloc = [ "jemallocator", "jemalloc-ctl" ]
diff --git a/crates/ra_ide_api/src/completion/complete_dot.rs b/crates/ra_ide_api/src/completion/complete_dot.rs
index 31d5374ba..f54a02d1d 100644
--- a/crates/ra_ide_api/src/completion/complete_dot.rs
+++ b/crates/ra_ide_api/src/completion/complete_dot.rs
@@ -30,7 +30,7 @@ fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty)
30 acc.add_field(ctx, field, &a_ty.parameters); 30 acc.add_field(ctx, field, &a_ty.parameters);
31 } 31 }
32 } 32 }
33 // TODO unions 33 // FIXME unions
34 TypeCtor::Tuple => { 34 TypeCtor::Tuple => {
35 for (i, ty) in a_ty.parameters.iter().enumerate() { 35 for (i, ty) in a_ty.parameters.iter().enumerate() {
36 acc.add_pos_field(ctx, i, ty); 36 acc.add_pos_field(ctx, i, ty);
diff --git a/crates/ra_ide_api/src/completion/complete_pattern.rs b/crates/ra_ide_api/src/completion/complete_pattern.rs
index 3cf79c080..7abcd019b 100644
--- a/crates/ra_ide_api/src/completion/complete_pattern.rs
+++ b/crates/ra_ide_api/src/completion/complete_pattern.rs
@@ -5,7 +5,7 @@ pub(super) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
5 if !ctx.is_pat_binding { 5 if !ctx.is_pat_binding {
6 return; 6 return;
7 } 7 }
8 // TODO: ideally, we should look at the type we are matching against and 8 // FIXME: ideally, we should look at the type we are matching against and
9 // suggest variants + auto-imports 9 // suggest variants + auto-imports
10 let names = ctx.resolver.all_names(ctx.db); 10 let names = ctx.resolver.all_names(ctx.db);
11 for (name, res) in names.into_iter() { 11 for (name, res) in names.into_iter() {
diff --git a/crates/ra_ide_api/src/completion/complete_struct_literal.rs b/crates/ra_ide_api/src/completion/complete_struct_literal.rs
index b75526282..f58bcd03e 100644
--- a/crates/ra_ide_api/src/completion/complete_struct_literal.rs
+++ b/crates/ra_ide_api/src/completion/complete_struct_literal.rs
@@ -26,7 +26,7 @@ pub(super) fn complete_struct_literal(acc: &mut Completions, ctx: &CompletionCon
26 } 26 }
27 } 27 }
28 28
29 // TODO unions 29 // FIXME unions
30 AdtDef::Enum(_) => (), 30 AdtDef::Enum(_) => (),
31 }; 31 };
32} 32}
diff --git a/crates/ra_ide_api/src/db.rs b/crates/ra_ide_api/src/db.rs
index 00f4bdfd2..ea4255d35 100644
--- a/crates/ra_ide_api/src/db.rs
+++ b/crates/ra_ide_api/src/db.rs
@@ -15,7 +15,7 @@ use crate::{LineIndex, symbol_index::{self, SymbolsDatabase}};
15 LineIndexDatabaseStorage, 15 LineIndexDatabaseStorage,
16 symbol_index::SymbolsDatabaseStorage, 16 symbol_index::SymbolsDatabaseStorage,
17 hir::db::HirDatabaseStorage, 17 hir::db::HirDatabaseStorage,
18 hir::db::PersistentHirDatabaseStorage 18 hir::db::DefDatabaseStorage
19)] 19)]
20#[derive(Debug)] 20#[derive(Debug)]
21pub(crate) struct RootDatabase { 21pub(crate) struct RootDatabase {
diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs
index 069092528..b9dc424c6 100644
--- a/crates/ra_ide_api/src/diagnostics.rs
+++ b/crates/ra_ide_api/src/diagnostics.rs
@@ -1,6 +1,5 @@
1use itertools::Itertools; 1use itertools::Itertools;
2use hir::{Problem, source_binder}; 2use hir::{Problem, source_binder};
3use ra_ide_api_light::Severity;
4use ra_db::SourceDatabase; 3use ra_db::SourceDatabase;
5use ra_syntax::{ 4use ra_syntax::{
6 Location, SourceFile, SyntaxKind, TextRange, SyntaxNode, 5 Location, SourceFile, SyntaxKind, TextRange, SyntaxNode,
@@ -11,6 +10,12 @@ use ra_text_edit::{TextEdit, TextEditBuilder};
11 10
12use crate::{Diagnostic, FileId, FileSystemEdit, SourceChange, SourceFileEdit, db::RootDatabase}; 11use crate::{Diagnostic, FileId, FileSystemEdit, SourceChange, SourceFileEdit, db::RootDatabase};
13 12
13#[derive(Debug, Copy, Clone)]
14pub enum Severity {
15 Error,
16 WeakWarning,
17}
18
14pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic> { 19pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic> {
15 let source_file = db.parse(file_id); 20 let source_file = db.parse(file_id);
16 let mut res = Vec::new(); 21 let mut res = Vec::new();
@@ -152,27 +157,6 @@ fn check_module(
152 fix: Some(fix), 157 fix: Some(fix),
153 } 158 }
154 } 159 }
155 Problem::NotDirOwner { move_to, candidate } => {
156 let move_file = FileSystemEdit::MoveFile {
157 src: file_id,
158 dst_source_root: source_root,
159 dst_path: move_to.clone(),
160 };
161 let create_file =
162 FileSystemEdit::CreateFile { source_root, path: move_to.join(candidate) };
163 let fix = SourceChange {
164 label: "move file and create module".to_string(),
165 source_file_edits: Vec::new(),
166 file_system_edits: vec![move_file, create_file],
167 cursor_position: None,
168 };
169 Diagnostic {
170 range: name_node.range(),
171 message: "can't declare module at this location".to_string(),
172 severity: Severity::Error,
173 fix: Some(fix),
174 }
175 }
176 }; 160 };
177 acc.push(diag) 161 acc.push(diag)
178 } 162 }
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs
index f94487d94..660b43cfa 100644
--- a/crates/ra_ide_api/src/goto_definition.rs
+++ b/crates/ra_ide_api/src/goto_definition.rs
@@ -117,7 +117,7 @@ pub(crate) fn reference_definition(
117 return Exact(nav); 117 return Exact(nav);
118 } 118 }
119 Some(Resolution::GenericParam(..)) => { 119 Some(Resolution::GenericParam(..)) => {
120 // TODO: go to the generic param def 120 // FIXME: go to the generic param def
121 } 121 }
122 Some(Resolution::SelfType(impl_block)) => { 122 Some(Resolution::SelfType(impl_block)) => {
123 let ty = impl_block.target_ty(db); 123 let ty = impl_block.target_ty(db);
diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs
index f6443580d..3206e68b9 100644
--- a/crates/ra_ide_api/src/hover.rs
+++ b/crates/ra_ide_api/src/hover.rs
@@ -204,7 +204,7 @@ impl NavigationTarget {
204 /// 204 ///
205 /// e.g. `struct Name`, `enum Name`, `fn Name` 205 /// e.g. `struct Name`, `enum Name`, `fn Name`
206 fn description(&self, db: &RootDatabase) -> Option<String> { 206 fn description(&self, db: &RootDatabase) -> Option<String> {
207 // TODO: After type inference is done, add type information to improve the output 207 // FIXME: After type inference is done, add type information to improve the output
208 let node = self.node(db)?; 208 let node = self.node(db)?;
209 209
210 fn visit_ascribed_node<T>(node: &T, prefix: &str) -> Option<String> 210 fn visit_ascribed_node<T>(node: &T, prefix: &str) -> Option<String>
diff --git a/crates/ra_ide_api_light/src/join_lines.rs b/crates/ra_ide_api/src/join_lines.rs
index b5bcd62fb..8fb3eaa06 100644
--- a/crates/ra_ide_api_light/src/join_lines.rs
+++ b/crates/ra_ide_api/src/join_lines.rs
@@ -9,22 +9,14 @@ use ra_syntax::{
9use ra_fmt::{ 9use ra_fmt::{
10 compute_ws, extract_trivial_expression 10 compute_ws, extract_trivial_expression
11}; 11};
12use crate::{ 12use ra_text_edit::{TextEdit, TextEditBuilder};
13 LocalEdit, TextEditBuilder,
14};
15 13
16pub fn join_lines(file: &SourceFile, range: TextRange) -> LocalEdit { 14pub fn join_lines(file: &SourceFile, range: TextRange) -> TextEdit {
17 let range = if range.is_empty() { 15 let range = if range.is_empty() {
18 let syntax = file.syntax(); 16 let syntax = file.syntax();
19 let text = syntax.text().slice(range.start()..); 17 let text = syntax.text().slice(range.start()..);
20 let pos = match text.find('\n') { 18 let pos = match text.find('\n') {
21 None => { 19 None => return TextEditBuilder::default().finish(),
22 return LocalEdit {
23 label: "join lines".to_string(),
24 edit: TextEditBuilder::default().finish(),
25 cursor_position: None,
26 };
27 }
28 Some(pos) => pos, 20 Some(pos) => pos,
29 }; 21 };
30 TextRange::offset_len(range.start() + pos, TextUnit::of_char('\n')) 22 TextRange::offset_len(range.start() + pos, TextUnit::of_char('\n'))
@@ -52,7 +44,7 @@ pub fn join_lines(file: &SourceFile, range: TextRange) -> LocalEdit {
52 } 44 }
53 } 45 }
54 46
55 LocalEdit { label: "join lines".to_string(), edit: edit.finish(), cursor_position: None } 47 edit.finish()
56} 48}
57 49
58fn remove_newline( 50fn remove_newline(
@@ -514,7 +506,7 @@ fn foo() {
514 let (sel, before) = extract_range(before); 506 let (sel, before) = extract_range(before);
515 let file = SourceFile::parse(&before); 507 let file = SourceFile::parse(&before);
516 let result = join_lines(&file, sel); 508 let result = join_lines(&file, sel);
517 let actual = result.edit.apply(&before); 509 let actual = result.apply(&before);
518 assert_eq_text!(after, &actual); 510 assert_eq_text!(after, &actual);
519 } 511 }
520 512
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs
index d6f63490d..99f18b6b8 100644
--- a/crates/ra_ide_api/src/lib.rs
+++ b/crates/ra_ide_api/src/lib.rs
@@ -36,9 +36,14 @@ mod syntax_tree;
36mod line_index; 36mod line_index;
37mod folding_ranges; 37mod folding_ranges;
38mod line_index_utils; 38mod line_index_utils;
39mod join_lines;
40mod typing;
41mod matching_brace;
39 42
40#[cfg(test)] 43#[cfg(test)]
41mod marks; 44mod marks;
45#[cfg(test)]
46mod test_utils;
42 47
43use std::sync::Arc; 48use std::sync::Arc;
44 49
@@ -66,10 +71,10 @@ pub use crate::{
66 line_index::{LineIndex, LineCol}, 71 line_index::{LineIndex, LineCol},
67 line_index_utils::translate_offset_with_edit, 72 line_index_utils::translate_offset_with_edit,
68 folding_ranges::{Fold, FoldKind}, 73 folding_ranges::{Fold, FoldKind},
74 syntax_highlighting::HighlightedRange,
75 diagnostics::Severity,
69}; 76};
70pub use ra_ide_api_light::{ 77pub use ra_ide_api_light::StructureNode;
71 HighlightedRange, Severity, StructureNode, LocalEdit,
72};
73pub use ra_db::{ 78pub use ra_db::{
74 Canceled, CrateGraph, CrateId, FileId, FilePosition, FileRange, SourceRootId, 79 Canceled, CrateGraph, CrateId, FileId, FilePosition, FileRange, SourceRootId,
75 Edition 80 Edition
@@ -263,7 +268,7 @@ impl Analysis {
263 /// supported). 268 /// supported).
264 pub fn matching_brace(&self, position: FilePosition) -> Option<TextUnit> { 269 pub fn matching_brace(&self, position: FilePosition) -> Option<TextUnit> {
265 let file = self.db.parse(position.file_id); 270 let file = self.db.parse(position.file_id);
266 ra_ide_api_light::matching_brace(&file, position.offset) 271 matching_brace::matching_brace(&file, position.offset)
267 } 272 }
268 273
269 /// Returns a syntax tree represented as `String`, for debug purposes. 274 /// Returns a syntax tree represented as `String`, for debug purposes.
@@ -276,18 +281,22 @@ impl Analysis {
276 /// stuff like trailing commas. 281 /// stuff like trailing commas.
277 pub fn join_lines(&self, frange: FileRange) -> SourceChange { 282 pub fn join_lines(&self, frange: FileRange) -> SourceChange {
278 let file = self.db.parse(frange.file_id); 283 let file = self.db.parse(frange.file_id);
279 SourceChange::from_local_edit( 284 let file_edit = SourceFileEdit {
280 frange.file_id, 285 file_id: frange.file_id,
281 ra_ide_api_light::join_lines(&file, frange.range), 286 edit: join_lines::join_lines(&file, frange.range),
282 ) 287 };
288 SourceChange {
289 label: "join lines".to_string(),
290 source_file_edits: vec![file_edit],
291 file_system_edits: vec![],
292 cursor_position: None,
293 }
283 } 294 }
284 295
285 /// Returns an edit which should be applied when opening a new line, fixing 296 /// Returns an edit which should be applied when opening a new line, fixing
286 /// up minor stuff like continuing the comment. 297 /// up minor stuff like continuing the comment.
287 pub fn on_enter(&self, position: FilePosition) -> Option<SourceChange> { 298 pub fn on_enter(&self, position: FilePosition) -> Option<SourceChange> {
288 let file = self.db.parse(position.file_id); 299 typing::on_enter(&self.db, position)
289 let edit = ra_ide_api_light::on_enter(&file, position.offset)?;
290 Some(SourceChange::from_local_edit(position.file_id, edit))
291 } 300 }
292 301
293 /// Returns an edit which should be applied after `=` was typed. Primarily, 302 /// Returns an edit which should be applied after `=` was typed. Primarily,
@@ -295,15 +304,18 @@ impl Analysis {
295 // FIXME: use a snippet completion instead of this hack here. 304 // FIXME: use a snippet completion instead of this hack here.
296 pub fn on_eq_typed(&self, position: FilePosition) -> Option<SourceChange> { 305 pub fn on_eq_typed(&self, position: FilePosition) -> Option<SourceChange> {
297 let file = self.db.parse(position.file_id); 306 let file = self.db.parse(position.file_id);
298 let edit = ra_ide_api_light::on_eq_typed(&file, position.offset)?; 307 let edit = typing::on_eq_typed(&file, position.offset)?;
299 Some(SourceChange::from_local_edit(position.file_id, edit)) 308 Some(SourceChange {
309 label: "add semicolon".to_string(),
310 source_file_edits: vec![SourceFileEdit { edit, file_id: position.file_id }],
311 file_system_edits: vec![],
312 cursor_position: None,
313 })
300 } 314 }
301 315
302 /// Returns an edit which should be applied when a dot ('.') is typed on a blank line, indenting the line appropriately. 316 /// Returns an edit which should be applied when a dot ('.') is typed on a blank line, indenting the line appropriately.
303 pub fn on_dot_typed(&self, position: FilePosition) -> Option<SourceChange> { 317 pub fn on_dot_typed(&self, position: FilePosition) -> Option<SourceChange> {
304 let file = self.db.parse(position.file_id); 318 typing::on_dot_typed(&self.db, position)
305 let edit = ra_ide_api_light::on_dot_typed(&file, position.offset)?;
306 Some(SourceChange::from_local_edit(position.file_id, edit))
307 } 319 }
308 320
309 /// Returns a tree representation of symbols in the file. Useful to draw a 321 /// Returns a tree representation of symbols in the file. Useful to draw a
@@ -425,18 +437,6 @@ impl Analysis {
425 } 437 }
426} 438}
427 439
428impl SourceChange {
429 pub(crate) fn from_local_edit(file_id: FileId, edit: LocalEdit) -> SourceChange {
430 let file_edit = SourceFileEdit { file_id, edit: edit.edit };
431 SourceChange {
432 label: edit.label,
433 source_file_edits: vec![file_edit],
434 file_system_edits: vec![],
435 cursor_position: edit.cursor_position.map(|offset| FilePosition { offset, file_id }),
436 }
437 }
438}
439
440#[test] 440#[test]
441fn analysis_is_send() { 441fn analysis_is_send() {
442 fn is_send<T: Send>() {} 442 fn is_send<T: Send>() {}
diff --git a/crates/ra_ide_api/src/line_index.rs b/crates/ra_ide_api/src/line_index.rs
index bf004c33a..fd33d6767 100644
--- a/crates/ra_ide_api/src/line_index.rs
+++ b/crates/ra_ide_api/src/line_index.rs
@@ -77,7 +77,7 @@ impl LineIndex {
77 } 77 }
78 78
79 pub fn offset(&self, line_col: LineCol) -> TextUnit { 79 pub fn offset(&self, line_col: LineCol) -> TextUnit {
80 //TODO: return Result 80 //FIXME: return Result
81 let col = self.utf16_to_utf8_col(line_col.line, line_col.col_utf16); 81 let col = self.utf16_to_utf8_col(line_col.line, line_col.col_utf16);
82 self.newlines[line_col.line as usize] + col 82 self.newlines[line_col.line as usize] + col
83 } 83 }
diff --git a/crates/ra_ide_api/src/matching_brace.rs b/crates/ra_ide_api/src/matching_brace.rs
new file mode 100644
index 000000000..d1405f14f
--- /dev/null
+++ b/crates/ra_ide_api/src/matching_brace.rs
@@ -0,0 +1,45 @@
1use ra_syntax::{
2 SourceFile, TextUnit,
3 algo::find_leaf_at_offset,
4 SyntaxKind::{self, *},
5 ast::AstNode,
6};
7
8pub fn matching_brace(file: &SourceFile, offset: TextUnit) -> Option<TextUnit> {
9 const BRACES: &[SyntaxKind] =
10 &[L_CURLY, R_CURLY, L_BRACK, R_BRACK, L_PAREN, R_PAREN, L_ANGLE, R_ANGLE];
11 let (brace_node, brace_idx) = find_leaf_at_offset(file.syntax(), offset)
12 .filter_map(|node| {
13 let idx = BRACES.iter().position(|&brace| brace == node.kind())?;
14 Some((node, idx))
15 })
16 .next()?;
17 let parent = brace_node.parent()?;
18 let matching_kind = BRACES[brace_idx ^ 1];
19 let matching_node = parent.children().find(|node| node.kind() == matching_kind)?;
20 Some(matching_node.range().start())
21}
22
23#[cfg(test)]
24mod tests {
25 use test_utils::{add_cursor, assert_eq_text, extract_offset};
26
27 use super::*;
28
29 #[test]
30 fn test_matching_brace() {
31 fn do_check(before: &str, after: &str) {
32 let (pos, before) = extract_offset(before);
33 let file = SourceFile::parse(&before);
34 let new_pos = match matching_brace(&file, pos) {
35 None => pos,
36 Some(pos) => pos,
37 };
38 let actual = add_cursor(&before, new_pos);
39 assert_eq_text!(after, &actual);
40 }
41
42 do_check("struct Foo { a: i32, }<|>", "struct Foo <|>{ a: i32, }");
43 }
44
45}
diff --git a/crates/ra_ide_api/src/snapshots/tests__highlighting.snap b/crates/ra_ide_api/src/snapshots/tests__highlighting.snap
new file mode 100644
index 000000000..72029e0ed
--- /dev/null
+++ b/crates/ra_ide_api/src/snapshots/tests__highlighting.snap
@@ -0,0 +1,34 @@
1---
2created: "2019-03-23T16:20:31.394314144Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/syntax_highlighting.rs
5expression: result
6---
7Ok(
8 [
9 HighlightedRange {
10 range: [1; 11),
11 tag: "comment"
12 },
13 HighlightedRange {
14 range: [12; 14),
15 tag: "keyword"
16 },
17 HighlightedRange {
18 range: [15; 19),
19 tag: "function"
20 },
21 HighlightedRange {
22 range: [29; 37),
23 tag: "macro"
24 },
25 HighlightedRange {
26 range: [38; 50),
27 tag: "string"
28 },
29 HighlightedRange {
30 range: [52; 54),
31 tag: "literal"
32 }
33 ]
34)
diff --git a/crates/ra_ide_api/src/symbol_index.rs b/crates/ra_ide_api/src/symbol_index.rs
index 23c743bef..0978d164a 100644
--- a/crates/ra_ide_api/src/symbol_index.rs
+++ b/crates/ra_ide_api/src/symbol_index.rs
@@ -68,7 +68,7 @@ fn file_symbols(db: &impl SymbolsDatabase, file_id: FileId) -> Arc<SymbolIndex>
68 68
69 let symbols = source_file_to_file_symbols(&source_file, file_id); 69 let symbols = source_file_to_file_symbols(&source_file, file_id);
70 70
71 // TODO: add macros here 71 // FIXME: add macros here
72 72
73 Arc::new(SymbolIndex::new(symbols)) 73 Arc::new(SymbolIndex::new(symbols))
74} 74}
diff --git a/crates/ra_ide_api/src/syntax_highlighting.rs b/crates/ra_ide_api/src/syntax_highlighting.rs
index fdd87bcff..a0c5e78ad 100644
--- a/crates/ra_ide_api/src/syntax_highlighting.rs
+++ b/crates/ra_ide_api/src/syntax_highlighting.rs
@@ -1,12 +1,81 @@
1use ra_syntax::AstNode; 1use rustc_hash::FxHashSet;
2
3use ra_syntax::{ast, AstNode, TextRange, Direction, SyntaxKind::*};
2use ra_db::SourceDatabase; 4use ra_db::SourceDatabase;
3 5
4use crate::{ 6use crate::{FileId, db::RootDatabase};
5 FileId, HighlightedRange, 7
6 db::RootDatabase, 8#[derive(Debug)]
7}; 9pub struct HighlightedRange {
10 pub range: TextRange,
11 pub tag: &'static str,
12}
8 13
9pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> { 14pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> {
10 let source_file = db.parse(file_id); 15 let source_file = db.parse(file_id);
11 ra_ide_api_light::highlight(source_file.syntax()) 16
17 // Visited nodes to handle highlighting priorities
18 let mut highlighted = FxHashSet::default();
19 let mut res = Vec::new();
20 for node in source_file.syntax().descendants() {
21 if highlighted.contains(&node) {
22 continue;
23 }
24 let tag = match node.kind() {
25 COMMENT => "comment",
26 STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => "string",
27 ATTR => "attribute",
28 NAME_REF => "text",
29 NAME => "function",
30 INT_NUMBER | FLOAT_NUMBER | CHAR | BYTE => "literal",
31 LIFETIME => "parameter",
32 k if k.is_keyword() => "keyword",
33 _ => {
34 if let Some(macro_call) = ast::MacroCall::cast(node) {
35 if let Some(path) = macro_call.path() {
36 if let Some(segment) = path.segment() {
37 if let Some(name_ref) = segment.name_ref() {
38 highlighted.insert(name_ref.syntax());
39 let range_start = name_ref.syntax().range().start();
40 let mut range_end = name_ref.syntax().range().end();
41 for sibling in path.syntax().siblings(Direction::Next) {
42 match sibling.kind() {
43 EXCL | IDENT => range_end = sibling.range().end(),
44 _ => (),
45 }
46 }
47 res.push(HighlightedRange {
48 range: TextRange::from_to(range_start, range_end),
49 tag: "macro",
50 })
51 }
52 }
53 }
54 }
55 continue;
56 }
57 };
58 res.push(HighlightedRange { range: node.range(), tag })
59 }
60 res
61}
62
63#[cfg(test)]
64mod tests {
65 use insta::assert_debug_snapshot_matches;
66
67 use crate::mock_analysis::single_file;
68
69 #[test]
70 fn test_highlighting() {
71 let (analysis, file_id) = single_file(
72 r#"
73// comment
74fn main() {}
75 println!("Hello, {}!", 92);
76"#,
77 );
78 let result = analysis.highlight(file_id);
79 assert_debug_snapshot_matches!("highlighting", result);
80 }
12} 81}
diff --git a/crates/ra_ide_api_light/src/test_utils.rs b/crates/ra_ide_api/src/test_utils.rs
index bfac0fce3..d0bd3a1e4 100644
--- a/crates/ra_ide_api_light/src/test_utils.rs
+++ b/crates/ra_ide_api/src/test_utils.rs
@@ -1,9 +1,9 @@
1use ra_syntax::{SourceFile, TextUnit}; 1use ra_syntax::{SourceFile, TextUnit};
2use ra_text_edit::TextEdit;
2 3
3use crate::LocalEdit;
4pub use test_utils::*; 4pub use test_utils::*;
5 5
6pub fn check_action<F: Fn(&SourceFile, TextUnit) -> Option<LocalEdit>>( 6pub fn check_action<F: Fn(&SourceFile, TextUnit) -> Option<TextEdit>>(
7 before: &str, 7 before: &str,
8 after: &str, 8 after: &str,
9 f: F, 9 f: F,
@@ -11,14 +11,9 @@ pub fn check_action<F: Fn(&SourceFile, TextUnit) -> Option<LocalEdit>>(
11 let (before_cursor_pos, before) = extract_offset(before); 11 let (before_cursor_pos, before) = extract_offset(before);
12 let file = SourceFile::parse(&before); 12 let file = SourceFile::parse(&before);
13 let result = f(&file, before_cursor_pos).expect("code action is not applicable"); 13 let result = f(&file, before_cursor_pos).expect("code action is not applicable");
14 let actual = result.edit.apply(&before); 14 let actual = result.apply(&before);
15 let actual_cursor_pos = match result.cursor_position { 15 let actual_cursor_pos =
16 None => result 16 result.apply_to_offset(before_cursor_pos).expect("cursor position is affected by the edit");
17 .edit
18 .apply_to_offset(before_cursor_pos)
19 .expect("cursor position is affected by the edit"),
20 Some(off) => off,
21 };
22 let actual = add_cursor(&actual, actual_cursor_pos); 17 let actual = add_cursor(&actual, actual_cursor_pos);
23 assert_eq_text!(after, &actual); 18 assert_eq_text!(after, &actual);
24} 19}
diff --git a/crates/ra_ide_api_light/src/typing.rs b/crates/ra_ide_api/src/typing.rs
index 9dd9f1c1d..94b228466 100644
--- a/crates/ra_ide_api_light/src/typing.rs
+++ b/crates/ra_ide_api/src/typing.rs
@@ -5,30 +5,37 @@ use ra_syntax::{
5 ast::{self, AstToken}, 5 ast::{self, AstToken},
6}; 6};
7use ra_fmt::leading_indent; 7use ra_fmt::leading_indent;
8use crate::{LocalEdit, TextEditBuilder}; 8use ra_text_edit::{TextEdit, TextEditBuilder};
9use ra_db::{FilePosition, SourceDatabase};
10use crate::{db::RootDatabase, SourceChange, SourceFileEdit};
9 11
10pub fn on_enter(file: &SourceFile, offset: TextUnit) -> Option<LocalEdit> { 12pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option<SourceChange> {
11 let comment = 13 let file = db.parse(position.file_id);
12 find_leaf_at_offset(file.syntax(), offset).left_biased().and_then(ast::Comment::cast)?; 14 let comment = find_leaf_at_offset(file.syntax(), position.offset)
15 .left_biased()
16 .and_then(ast::Comment::cast)?;
13 17
14 if let ast::CommentFlavor::Multiline = comment.flavor() { 18 if let ast::CommentFlavor::Multiline = comment.flavor() {
15 return None; 19 return None;
16 } 20 }
17 21
18 let prefix = comment.prefix(); 22 let prefix = comment.prefix();
19 if offset < comment.syntax().range().start() + TextUnit::of_str(prefix) + TextUnit::from(1) { 23 if position.offset
24 < comment.syntax().range().start() + TextUnit::of_str(prefix) + TextUnit::from(1)
25 {
20 return None; 26 return None;
21 } 27 }
22 28
23 let indent = node_indent(file, comment.syntax())?; 29 let indent = node_indent(&file, comment.syntax())?;
24 let inserted = format!("\n{}{} ", indent, prefix); 30 let inserted = format!("\n{}{} ", indent, prefix);
25 let cursor_position = offset + TextUnit::of_str(&inserted); 31 let cursor_position = position.offset + TextUnit::of_str(&inserted);
26 let mut edit = TextEditBuilder::default(); 32 let mut edit = TextEditBuilder::default();
27 edit.insert(offset, inserted); 33 edit.insert(position.offset, inserted);
28 Some(LocalEdit { 34 Some(SourceChange {
29 label: "on enter".to_string(), 35 label: "on enter".to_string(),
30 edit: edit.finish(), 36 source_file_edits: vec![SourceFileEdit { edit: edit.finish(), file_id: position.file_id }],
31 cursor_position: Some(cursor_position), 37 file_system_edits: vec![],
38 cursor_position: Some(FilePosition { offset: cursor_position, file_id: position.file_id }),
32 }) 39 })
33} 40}
34 41
@@ -52,7 +59,7 @@ fn node_indent<'a>(file: &'a SourceFile, node: &SyntaxNode) -> Option<&'a str> {
52 Some(&text[pos..]) 59 Some(&text[pos..])
53} 60}
54 61
55pub fn on_eq_typed(file: &SourceFile, eq_offset: TextUnit) -> Option<LocalEdit> { 62pub fn on_eq_typed(file: &SourceFile, eq_offset: TextUnit) -> Option<TextEdit> {
56 assert_eq!(file.syntax().text().char_at(eq_offset), Some('=')); 63 assert_eq!(file.syntax().text().char_at(eq_offset), Some('='));
57 let let_stmt: &ast::LetStmt = find_node_at_offset(file.syntax(), eq_offset)?; 64 let let_stmt: &ast::LetStmt = find_node_at_offset(file.syntax(), eq_offset)?;
58 if let_stmt.has_semi() { 65 if let_stmt.has_semi() {
@@ -72,17 +79,14 @@ pub fn on_eq_typed(file: &SourceFile, eq_offset: TextUnit) -> Option<LocalEdit>
72 let offset = let_stmt.syntax().range().end(); 79 let offset = let_stmt.syntax().range().end();
73 let mut edit = TextEditBuilder::default(); 80 let mut edit = TextEditBuilder::default();
74 edit.insert(offset, ";".to_string()); 81 edit.insert(offset, ";".to_string());
75 Some(LocalEdit { 82 Some(edit.finish())
76 label: "add semicolon".to_string(),
77 edit: edit.finish(),
78 cursor_position: None,
79 })
80} 83}
81 84
82pub fn on_dot_typed(file: &SourceFile, dot_offset: TextUnit) -> Option<LocalEdit> { 85pub(crate) fn on_dot_typed(db: &RootDatabase, position: FilePosition) -> Option<SourceChange> {
83 assert_eq!(file.syntax().text().char_at(dot_offset), Some('.')); 86 let file = db.parse(position.file_id);
87 assert_eq!(file.syntax().text().char_at(position.offset), Some('.'));
84 88
85 let whitespace = find_leaf_at_offset(file.syntax(), dot_offset) 89 let whitespace = find_leaf_at_offset(file.syntax(), position.offset)
86 .left_biased() 90 .left_biased()
87 .and_then(ast::Whitespace::cast)?; 91 .and_then(ast::Whitespace::cast)?;
88 92
@@ -103,22 +107,27 @@ pub fn on_dot_typed(file: &SourceFile, dot_offset: TextUnit) -> Option<LocalEdit
103 } 107 }
104 let mut edit = TextEditBuilder::default(); 108 let mut edit = TextEditBuilder::default();
105 edit.replace( 109 edit.replace(
106 TextRange::from_to(dot_offset - current_indent_len, dot_offset), 110 TextRange::from_to(position.offset - current_indent_len, position.offset),
107 target_indent.into(), 111 target_indent.into(),
108 ); 112 );
109 let res = LocalEdit { 113 let res = SourceChange {
110 label: "reindent dot".to_string(), 114 label: "reindent dot".to_string(),
111 edit: edit.finish(), 115 source_file_edits: vec![SourceFileEdit { edit: edit.finish(), file_id: position.file_id }],
112 cursor_position: Some( 116 file_system_edits: vec![],
113 dot_offset + target_indent_len - current_indent_len + TextUnit::of_char('.'), 117 cursor_position: Some(FilePosition {
114 ), 118 offset: position.offset + target_indent_len - current_indent_len
119 + TextUnit::of_char('.'),
120 file_id: position.file_id,
121 }),
115 }; 122 };
116 Some(res) 123 Some(res)
117} 124}
118 125
119#[cfg(test)] 126#[cfg(test)]
120mod tests { 127mod tests {
121 use crate::test_utils::{add_cursor, assert_eq_text, extract_offset}; 128 use test_utils::{add_cursor, assert_eq_text, extract_offset};
129
130 use crate::mock_analysis::single_file;
122 131
123 use super::*; 132 use super::*;
124 133
@@ -131,7 +140,7 @@ mod tests {
131 let before = edit.finish().apply(&before); 140 let before = edit.finish().apply(&before);
132 let file = SourceFile::parse(&before); 141 let file = SourceFile::parse(&before);
133 if let Some(result) = on_eq_typed(&file, offset) { 142 if let Some(result) = on_eq_typed(&file, offset) {
134 let actual = result.edit.apply(&before); 143 let actual = result.apply(&before);
135 assert_eq_text!(after, &actual); 144 assert_eq_text!(after, &actual);
136 } else { 145 } else {
137 assert_eq_text!(&before, after) 146 assert_eq_text!(&before, after)
@@ -177,9 +186,10 @@ fn foo() {
177 let mut edit = TextEditBuilder::default(); 186 let mut edit = TextEditBuilder::default();
178 edit.insert(offset, ".".to_string()); 187 edit.insert(offset, ".".to_string());
179 let before = edit.finish().apply(&before); 188 let before = edit.finish().apply(&before);
180 let file = SourceFile::parse(&before); 189 let (analysis, file_id) = single_file(&before);
181 if let Some(result) = on_dot_typed(&file, offset) { 190 if let Some(result) = analysis.on_dot_typed(FilePosition { offset, file_id }) {
182 let actual = result.edit.apply(&before); 191 assert_eq!(result.source_file_edits.len(), 1);
192 let actual = result.source_file_edits[0].edit.apply(&before);
183 assert_eq_text!(after, &actual); 193 assert_eq_text!(after, &actual);
184 } else { 194 } else {
185 assert_eq_text!(&before, after) 195 assert_eq_text!(&before, after)
@@ -358,10 +368,12 @@ fn foo() {
358 fn test_on_enter() { 368 fn test_on_enter() {
359 fn apply_on_enter(before: &str) -> Option<String> { 369 fn apply_on_enter(before: &str) -> Option<String> {
360 let (offset, before) = extract_offset(before); 370 let (offset, before) = extract_offset(before);
361 let file = SourceFile::parse(&before); 371 let (analysis, file_id) = single_file(&before);
362 let result = on_enter(&file, offset)?; 372 let result = analysis.on_enter(FilePosition { offset, file_id })?;
363 let actual = result.edit.apply(&before); 373
364 let actual = add_cursor(&actual, result.cursor_position.unwrap()); 374 assert_eq!(result.source_file_edits.len(), 1);
375 let actual = result.source_file_edits[0].edit.apply(&before);
376 let actual = add_cursor(&actual, result.cursor_position.unwrap().offset);
365 Some(actual) 377 Some(actual)
366 } 378 }
367 379
diff --git a/crates/ra_ide_api_light/Cargo.toml b/crates/ra_ide_api_light/Cargo.toml
index a30833dc3..4e69f5325 100644
--- a/crates/ra_ide_api_light/Cargo.toml
+++ b/crates/ra_ide_api_light/Cargo.toml
@@ -17,5 +17,10 @@ ra_fmt = { path = "../ra_fmt" }
17 17
18[dev-dependencies] 18[dev-dependencies]
19test_utils = { path = "../test_utils" } 19test_utils = { path = "../test_utils" }
20proptest = "0.9.0"
21insta = "0.7.0" 20insta = "0.7.0"
21
22[dev-dependencies.proptest]
23version = "0.9.0"
24# Disable `fork` feature to allow compiling on webassembly
25default-features = false
26features = ["std", "bit-set", "break-dead-code"]
diff --git a/crates/ra_ide_api_light/src/lib.rs b/crates/ra_ide_api_light/src/lib.rs
index 4036a598e..df7f144b6 100644
--- a/crates/ra_ide_api_light/src/lib.rs
+++ b/crates/ra_ide_api_light/src/lib.rs
@@ -4,151 +4,9 @@
4//! an edit or some auxiliary info. 4//! an edit or some auxiliary info.
5 5
6mod structure; 6mod structure;
7#[cfg(test)]
8mod test_utils;
9mod join_lines;
10mod typing;
11 7
12use rustc_hash::FxHashSet; 8use ra_syntax::TextRange;
13use ra_text_edit::TextEditBuilder;
14use ra_syntax::{
15 SourceFile, SyntaxNode, TextRange, TextUnit, Direction,
16 algo::find_leaf_at_offset,
17 SyntaxKind::{self, *},
18 ast::{self, AstNode},
19};
20 9
21pub use crate::{ 10pub use crate::{
22 structure::{file_structure, StructureNode}, 11 structure::{file_structure, StructureNode},
23 join_lines::join_lines,
24 typing::{on_enter, on_dot_typed, on_eq_typed},
25}; 12};
26
27#[derive(Debug)]
28pub struct LocalEdit {
29 pub label: String,
30 pub edit: ra_text_edit::TextEdit,
31 pub cursor_position: Option<TextUnit>,
32}
33
34#[derive(Debug)]
35pub struct HighlightedRange {
36 pub range: TextRange,
37 pub tag: &'static str,
38}
39
40#[derive(Debug, Copy, Clone)]
41pub enum Severity {
42 Error,
43 WeakWarning,
44}
45
46#[derive(Debug)]
47pub struct Diagnostic {
48 pub range: TextRange,
49 pub msg: String,
50 pub severity: Severity,
51 pub fix: Option<LocalEdit>,
52}
53
54pub fn matching_brace(file: &SourceFile, offset: TextUnit) -> Option<TextUnit> {
55 const BRACES: &[SyntaxKind] =
56 &[L_CURLY, R_CURLY, L_BRACK, R_BRACK, L_PAREN, R_PAREN, L_ANGLE, R_ANGLE];
57 let (brace_node, brace_idx) = find_leaf_at_offset(file.syntax(), offset)
58 .filter_map(|node| {
59 let idx = BRACES.iter().position(|&brace| brace == node.kind())?;
60 Some((node, idx))
61 })
62 .next()?;
63 let parent = brace_node.parent()?;
64 let matching_kind = BRACES[brace_idx ^ 1];
65 let matching_node = parent.children().find(|node| node.kind() == matching_kind)?;
66 Some(matching_node.range().start())
67}
68
69pub fn highlight(root: &SyntaxNode) -> Vec<HighlightedRange> {
70 // Visited nodes to handle highlighting priorities
71 let mut highlighted = FxHashSet::default();
72 let mut res = Vec::new();
73 for node in root.descendants() {
74 if highlighted.contains(&node) {
75 continue;
76 }
77 let tag = match node.kind() {
78 COMMENT => "comment",
79 STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => "string",
80 ATTR => "attribute",
81 NAME_REF => "text",
82 NAME => "function",
83 INT_NUMBER | FLOAT_NUMBER | CHAR | BYTE => "literal",
84 LIFETIME => "parameter",
85 k if k.is_keyword() => "keyword",
86 _ => {
87 if let Some(macro_call) = ast::MacroCall::cast(node) {
88 if let Some(path) = macro_call.path() {
89 if let Some(segment) = path.segment() {
90 if let Some(name_ref) = segment.name_ref() {
91 highlighted.insert(name_ref.syntax());
92 let range_start = name_ref.syntax().range().start();
93 let mut range_end = name_ref.syntax().range().end();
94 for sibling in path.syntax().siblings(Direction::Next) {
95 match sibling.kind() {
96 EXCL | IDENT => range_end = sibling.range().end(),
97 _ => (),
98 }
99 }
100 res.push(HighlightedRange {
101 range: TextRange::from_to(range_start, range_end),
102 tag: "macro",
103 })
104 }
105 }
106 }
107 }
108 continue;
109 }
110 };
111 res.push(HighlightedRange { range: node.range(), tag })
112 }
113 res
114}
115
116#[cfg(test)]
117mod tests {
118 use ra_syntax::AstNode;
119 use insta::assert_debug_snapshot_matches;
120
121 use crate::test_utils::{add_cursor, assert_eq_text, extract_offset};
122
123 use super::*;
124
125 #[test]
126 fn test_highlighting() {
127 let file = SourceFile::parse(
128 r#"
129// comment
130fn main() {}
131 println!("Hello, {}!", 92);
132"#,
133 );
134 let hls = highlight(file.syntax());
135 assert_debug_snapshot_matches!("highlighting", hls);
136 }
137
138 #[test]
139 fn test_matching_brace() {
140 fn do_check(before: &str, after: &str) {
141 let (pos, before) = extract_offset(before);
142 let file = SourceFile::parse(&before);
143 let new_pos = match matching_brace(&file, pos) {
144 None => pos,
145 Some(pos) => pos,
146 };
147 let actual = add_cursor(&before, new_pos);
148 assert_eq_text!(after, &actual);
149 }
150
151 do_check("struct Foo { a: i32, }<|>", "struct Foo <|>{ a: i32, }");
152 }
153
154}
diff --git a/crates/ra_ide_api_light/src/snapshots/tests__highlighting.snap b/crates/ra_ide_api_light/src/snapshots/tests__highlighting.snap
deleted file mode 100644
index ef306a7a0..000000000
--- a/crates/ra_ide_api_light/src/snapshots/tests__highlighting.snap
+++ /dev/null
@@ -1,32 +0,0 @@
1---
2created: "2019-01-22T14:45:01.959724300+00:00"
3creator: [email protected]
4expression: hls
5source: "crates\\ra_ide_api_light\\src\\lib.rs"
6---
7[
8 HighlightedRange {
9 range: [1; 11),
10 tag: "comment"
11 },
12 HighlightedRange {
13 range: [12; 14),
14 tag: "keyword"
15 },
16 HighlightedRange {
17 range: [15; 19),
18 tag: "function"
19 },
20 HighlightedRange {
21 range: [29; 37),
22 tag: "macro"
23 },
24 HighlightedRange {
25 range: [38; 50),
26 tag: "string"
27 },
28 HighlightedRange {
29 range: [52; 54),
30 tag: "literal"
31 }
32]
diff --git a/crates/ra_parser/src/grammar/items/consts.rs b/crates/ra_parser/src/grammar/items/consts.rs
index e6e6011c6..1f802246f 100644
--- a/crates/ra_parser/src/grammar/items/consts.rs
+++ b/crates/ra_parser/src/grammar/items/consts.rs
@@ -11,7 +11,7 @@ pub(super) fn const_def(p: &mut Parser, m: Marker) {
11fn const_or_static(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) { 11fn const_or_static(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) {
12 assert!(p.at(kw)); 12 assert!(p.at(kw));
13 p.bump(); 13 p.bump();
14 p.eat(MUT_KW); // TODO: validator to forbid const mut 14 p.eat(MUT_KW); // FIXME: validator to forbid const mut
15 name(p); 15 name(p);
16 types::ascription(p); 16 types::ascription(p);
17 if p.eat(EQ) { 17 if p.eat(EQ) {
diff --git a/crates/ra_parser/src/grammar/items/nominal.rs b/crates/ra_parser/src/grammar/items/nominal.rs
index a3579eebd..e93bd76b8 100644
--- a/crates/ra_parser/src/grammar/items/nominal.rs
+++ b/crates/ra_parser/src/grammar/items/nominal.rs
@@ -15,7 +15,7 @@ pub(super) fn struct_def(p: &mut Parser, m: Marker, kind: SyntaxKind) {
15 } 15 }
16 L_CURLY => named_field_def_list(p), 16 L_CURLY => named_field_def_list(p),
17 _ => { 17 _ => {
18 //TODO: special case `(` error message 18 //FIXME: special case `(` error message
19 p.error("expected `;` or `{`"); 19 p.error("expected `;` or `{`");
20 } 20 }
21 } 21 }
diff --git a/crates/ra_parser/src/grammar/items/traits.rs b/crates/ra_parser/src/grammar/items/traits.rs
index d5a8ccd98..f49615f6b 100644
--- a/crates/ra_parser/src/grammar/items/traits.rs
+++ b/crates/ra_parser/src/grammar/items/traits.rs
@@ -49,7 +49,7 @@ pub(super) fn impl_block(p: &mut Parser) {
49 type_params::opt_type_param_list(p); 49 type_params::opt_type_param_list(p);
50 } 50 }
51 51
52 // TODO: never type 52 // FIXME: never type
53 // impl ! {} 53 // impl ! {}
54 54
55 // test impl_block_neg 55 // test impl_block_neg
diff --git a/crates/ra_parser/src/grammar/items/use_item.rs b/crates/ra_parser/src/grammar/items/use_item.rs
index ea2f94604..908493789 100644
--- a/crates/ra_parser/src/grammar/items/use_item.rs
+++ b/crates/ra_parser/src/grammar/items/use_item.rs
@@ -21,7 +21,7 @@ fn use_tree(p: &mut Parser) {
21 // This does not handle cases such as `use some::path::*` 21 // This does not handle cases such as `use some::path::*`
22 // N.B. in Rust 2015 `use *;` imports all from crate root 22 // N.B. in Rust 2015 `use *;` imports all from crate root
23 // however in Rust 2018 `use *;` errors: ('cannot glob-import all possible crates') 23 // however in Rust 2018 `use *;` errors: ('cannot glob-import all possible crates')
24 // TODO: Add this error (if not out of scope) 24 // FIXME: Add this error (if not out of scope)
25 25
26 // test use_star 26 // test use_star
27 // use *; 27 // use *;
@@ -33,7 +33,7 @@ fn use_tree(p: &mut Parser) {
33 // Parse `use ::*;`, which imports all from the crate root in Rust 2015 33 // Parse `use ::*;`, which imports all from the crate root in Rust 2015
34 // This is invalid inside a use_tree_list, (e.g. `use some::path::{::*}`) 34 // This is invalid inside a use_tree_list, (e.g. `use some::path::{::*}`)
35 // but still parses and errors later: ('crate root in paths can only be used in start position') 35 // but still parses and errors later: ('crate root in paths can only be used in start position')
36 // TODO: Add this error (if not out of scope) 36 // FIXME: Add this error (if not out of scope)
37 // In Rust 2018, it is always invalid (see above) 37 // In Rust 2018, it is always invalid (see above)
38 p.bump(); 38 p.bump();
39 p.bump(); 39 p.bump();
diff --git a/crates/ra_parser/src/grammar/types.rs b/crates/ra_parser/src/grammar/types.rs
index adc189a29..fdd4f2c52 100644
--- a/crates/ra_parser/src/grammar/types.rs
+++ b/crates/ra_parser/src/grammar/types.rs
@@ -202,12 +202,15 @@ pub(super) fn for_binder(p: &mut Parser) {
202 202
203// test for_type 203// test for_type
204// type A = for<'a> fn() -> (); 204// type A = for<'a> fn() -> ();
205// fn foo<T>(_t: &T) where for<'a> &'a T: Iterator {}
206// fn bar<T>(_t: &T) where for<'a> &'a mut T: Iterator {}
205pub(super) fn for_type(p: &mut Parser) { 207pub(super) fn for_type(p: &mut Parser) {
206 assert!(p.at(FOR_KW)); 208 assert!(p.at(FOR_KW));
207 let m = p.start(); 209 let m = p.start();
208 for_binder(p); 210 for_binder(p);
209 match p.current() { 211 match p.current() {
210 FN_KW | UNSAFE_KW | EXTERN_KW => fn_pointer_type(p), 212 FN_KW | UNSAFE_KW | EXTERN_KW => fn_pointer_type(p),
213 AMP => reference_type(p),
211 _ if paths::is_path_start(p) => path_type_(p, false), 214 _ if paths::is_path_start(p) => path_type_(p, false),
212 _ => p.error("expected a path"), 215 _ => p.error("expected a path"),
213 } 216 }
diff --git a/crates/ra_parser/src/parser.rs b/crates/ra_parser/src/parser.rs
index 3c326452b..56f8b7126 100644
--- a/crates/ra_parser/src/parser.rs
+++ b/crates/ra_parser/src/parser.rs
@@ -121,7 +121,7 @@ impl<'t> Parser<'t> {
121 /// final tree. 121 /// final tree.
122 pub(crate) fn bump_remap(&mut self, kind: SyntaxKind) { 122 pub(crate) fn bump_remap(&mut self, kind: SyntaxKind) {
123 if self.nth(0) == EOF { 123 if self.nth(0) == EOF {
124 // TODO: panic!? 124 // FIXME: panic!?
125 return; 125 return;
126 } 126 }
127 self.do_bump(kind, 1); 127 self.do_bump(kind, 1);
@@ -135,7 +135,7 @@ impl<'t> Parser<'t> {
135 } 135 }
136 136
137 /// Emit error with the `message` 137 /// Emit error with the `message`
138 /// TODO: this should be much more fancy and support 138 /// FIXME: this should be much more fancy and support
139 /// structured errors with spans and notes, like rustc 139 /// structured errors with spans and notes, like rustc
140 /// does. 140 /// does.
141 pub(crate) fn error<T: Into<String>>(&mut self, message: T) { 141 pub(crate) fn error<T: Into<String>>(&mut self, message: T) {
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs
index 6f46a2d43..3bad4f8d3 100644
--- a/crates/ra_project_model/src/lib.rs
+++ b/crates/ra_project_model/src/lib.rs
@@ -23,7 +23,7 @@ pub use crate::{
23 sysroot::Sysroot, 23 sysroot::Sysroot,
24}; 24};
25 25
26// TODO use proper error enum 26// FIXME use proper error enum
27pub type Result<T> = ::std::result::Result<T, ::failure::Error>; 27pub type Result<T> = ::std::result::Result<T, ::failure::Error>;
28 28
29#[derive(Debug, Clone)] 29#[derive(Debug, Clone)]
diff --git a/crates/ra_syntax/src/validation/char.rs b/crates/ra_syntax/src/validation/char.rs
index 3169ed590..c874e5d08 100644
--- a/crates/ra_syntax/src/validation/char.rs
+++ b/crates/ra_syntax/src/validation/char.rs
@@ -85,7 +85,7 @@ pub(super) fn is_ascii_escape(code: char) -> bool {
85fn validate_ascii_code_escape(text: &str, range: TextRange, errors: &mut Vec<SyntaxError>) { 85fn validate_ascii_code_escape(text: &str, range: TextRange, errors: &mut Vec<SyntaxError>) {
86 // An AsciiCodeEscape has 4 chars, example: `\xDD` 86 // An AsciiCodeEscape has 4 chars, example: `\xDD`
87 if !text.is_ascii() { 87 if !text.is_ascii() {
88 // TODO: Give a more precise error message (say what the invalid character was) 88 // FIXME: Give a more precise error message (say what the invalid character was)
89 errors.push(SyntaxError::new(AsciiCodeEscapeOutOfRange, range)); 89 errors.push(SyntaxError::new(AsciiCodeEscapeOutOfRange, range));
90 } else if text.chars().count() < 4 { 90 } else if text.chars().count() < 4 {
91 errors.push(SyntaxError::new(TooShortAsciiCodeEscape, range)); 91 errors.push(SyntaxError::new(TooShortAsciiCodeEscape, range));
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0081_for_type.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0081_for_type.rs
index 4d6a18c6b..7cde5c532 100644
--- a/crates/ra_syntax/tests/data/parser/inline/ok/0081_for_type.rs
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0081_for_type.rs
@@ -1 +1,3 @@
1type A = for<'a> fn() -> (); 1type A = for<'a> fn() -> ();
2fn foo<T>(_t: &T) where for<'a> &'a T: Iterator {}
3fn bar<T>(_t: &T) where for<'a> &'a mut T: Iterator {}
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0081_for_type.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0081_for_type.txt
index 6e7e6bda1..568f61fb2 100644
--- a/crates/ra_syntax/tests/data/parser/inline/ok/0081_for_type.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0081_for_type.txt
@@ -1,4 +1,4 @@
1SOURCE_FILE@[0; 29) 1SOURCE_FILE@[0; 135)
2 TYPE_ALIAS_DEF@[0; 28) 2 TYPE_ALIAS_DEF@[0; 28)
3 TYPE_KW@[0; 4) 3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5) 4 WHITESPACE@[4; 5)
@@ -29,3 +29,127 @@ SOURCE_FILE@[0; 29)
29 R_PAREN@[26; 27) 29 R_PAREN@[26; 27)
30 SEMI@[27; 28) 30 SEMI@[27; 28)
31 WHITESPACE@[28; 29) 31 WHITESPACE@[28; 29)
32 FN_DEF@[29; 79)
33 FN_KW@[29; 31)
34 WHITESPACE@[31; 32)
35 NAME@[32; 35)
36 IDENT@[32; 35) "foo"
37 TYPE_PARAM_LIST@[35; 38)
38 L_ANGLE@[35; 36)
39 TYPE_PARAM@[36; 37)
40 NAME@[36; 37)
41 IDENT@[36; 37) "T"
42 R_ANGLE@[37; 38)
43 PARAM_LIST@[38; 46)
44 L_PAREN@[38; 39)
45 PARAM@[39; 45)
46 BIND_PAT@[39; 41)
47 NAME@[39; 41)
48 IDENT@[39; 41) "_t"
49 COLON@[41; 42)
50 WHITESPACE@[42; 43)
51 REFERENCE_TYPE@[43; 45)
52 AMP@[43; 44)
53 PATH_TYPE@[44; 45)
54 PATH@[44; 45)
55 PATH_SEGMENT@[44; 45)
56 NAME_REF@[44; 45)
57 IDENT@[44; 45) "T"
58 R_PAREN@[45; 46)
59 WHITESPACE@[46; 47)
60 WHERE_CLAUSE@[47; 76)
61 WHERE_KW@[47; 52)
62 WHITESPACE@[52; 53)
63 WHERE_PRED@[53; 76)
64 FOR_TYPE@[53; 66)
65 FOR_KW@[53; 56)
66 TYPE_PARAM_LIST@[56; 60)
67 L_ANGLE@[56; 57)
68 LIFETIME_PARAM@[57; 59)
69 LIFETIME@[57; 59) "'a"
70 R_ANGLE@[59; 60)
71 WHITESPACE@[60; 61)
72 REFERENCE_TYPE@[61; 66)
73 AMP@[61; 62)
74 LIFETIME@[62; 64) "'a"
75 WHITESPACE@[64; 65)
76 PATH_TYPE@[65; 66)
77 PATH@[65; 66)
78 PATH_SEGMENT@[65; 66)
79 NAME_REF@[65; 66)
80 IDENT@[65; 66) "T"
81 COLON@[66; 67)
82 WHITESPACE@[67; 68)
83 PATH_TYPE@[68; 76)
84 PATH@[68; 76)
85 PATH_SEGMENT@[68; 76)
86 NAME_REF@[68; 76)
87 IDENT@[68; 76) "Iterator"
88 WHITESPACE@[76; 77)
89 BLOCK@[77; 79)
90 L_CURLY@[77; 78)
91 R_CURLY@[78; 79)
92 WHITESPACE@[79; 80)
93 FN_DEF@[80; 134)
94 FN_KW@[80; 82)
95 WHITESPACE@[82; 83)
96 NAME@[83; 86)
97 IDENT@[83; 86) "bar"
98 TYPE_PARAM_LIST@[86; 89)
99 L_ANGLE@[86; 87)
100 TYPE_PARAM@[87; 88)
101 NAME@[87; 88)
102 IDENT@[87; 88) "T"
103 R_ANGLE@[88; 89)
104 PARAM_LIST@[89; 97)
105 L_PAREN@[89; 90)
106 PARAM@[90; 96)
107 BIND_PAT@[90; 92)
108 NAME@[90; 92)
109 IDENT@[90; 92) "_t"
110 COLON@[92; 93)
111 WHITESPACE@[93; 94)
112 REFERENCE_TYPE@[94; 96)
113 AMP@[94; 95)
114 PATH_TYPE@[95; 96)
115 PATH@[95; 96)
116 PATH_SEGMENT@[95; 96)
117 NAME_REF@[95; 96)
118 IDENT@[95; 96) "T"
119 R_PAREN@[96; 97)
120 WHITESPACE@[97; 98)
121 WHERE_CLAUSE@[98; 131)
122 WHERE_KW@[98; 103)
123 WHITESPACE@[103; 104)
124 WHERE_PRED@[104; 131)
125 FOR_TYPE@[104; 121)
126 FOR_KW@[104; 107)
127 TYPE_PARAM_LIST@[107; 111)
128 L_ANGLE@[107; 108)
129 LIFETIME_PARAM@[108; 110)
130 LIFETIME@[108; 110) "'a"
131 R_ANGLE@[110; 111)
132 WHITESPACE@[111; 112)
133 REFERENCE_TYPE@[112; 121)
134 AMP@[112; 113)
135 LIFETIME@[113; 115) "'a"
136 WHITESPACE@[115; 116)
137 MUT_KW@[116; 119)
138 WHITESPACE@[119; 120)
139 PATH_TYPE@[120; 121)
140 PATH@[120; 121)
141 PATH_SEGMENT@[120; 121)
142 NAME_REF@[120; 121)
143 IDENT@[120; 121) "T"
144 COLON@[121; 122)
145 WHITESPACE@[122; 123)
146 PATH_TYPE@[123; 131)
147 PATH@[123; 131)
148 PATH_SEGMENT@[123; 131)
149 NAME_REF@[123; 131)
150 IDENT@[123; 131) "Iterator"
151 WHITESPACE@[131; 132)
152 BLOCK@[132; 134)
153 L_CURLY@[132; 133)
154 R_CURLY@[133; 134)
155 WHITESPACE@[134; 135)
diff --git a/crates/ra_syntax/tests/test.rs b/crates/ra_syntax/tests/test.rs
index 537b01368..276756c85 100644
--- a/crates/ra_syntax/tests/test.rs
+++ b/crates/ra_syntax/tests/test.rs
@@ -61,7 +61,7 @@ fn reparse_fuzz_tests() {
61} 61}
62 62
63/// Test that Rust-analyzer can parse and validate the rust-analyser 63/// Test that Rust-analyzer can parse and validate the rust-analyser
64/// TODO: Use this as a benchmark 64/// FIXME: Use this as a benchmark
65#[test] 65#[test]
66fn self_hosting_parsing() { 66fn self_hosting_parsing() {
67 use std::ffi::OsStr; 67 use std::ffi::OsStr;
diff --git a/crates/ra_text_edit/Cargo.toml b/crates/ra_text_edit/Cargo.toml
index 5769940df..b40026004 100644
--- a/crates/ra_text_edit/Cargo.toml
+++ b/crates/ra_text_edit/Cargo.toml
@@ -7,7 +7,12 @@ publish = false
7 7
8[dependencies] 8[dependencies]
9text_unit = "0.1.6" 9text_unit = "0.1.6"
10proptest = "0.9.0" 10
11[dependencies.proptest]
12version = "0.9.0"
13# Disable `fork` feature to allow compiling on webassembly
14default-features = false
15features = ["std", "bit-set", "break-dead-code"]
11 16
12[dev-dependencies] 17[dev-dependencies]
13test_utils = { path = "../test_utils" } 18test_utils = { path = "../test_utils" }
diff --git a/crates/tools/tests/cli.rs b/crates/tools/tests/cli.rs
index aab52a4aa..6f82ae61d 100644
--- a/crates/tools/tests/cli.rs
+++ b/crates/tools/tests/cli.rs
@@ -1,4 +1,6 @@
1use tools::{generate, gen_tests, run_rustfmt, Verify}; 1use walkdir::WalkDir;
2
3use tools::{generate, gen_tests, run_rustfmt, Verify, project_root};
2 4
3#[test] 5#[test]
4fn generated_grammar_is_fresh() { 6fn generated_grammar_is_fresh() {
@@ -20,3 +22,25 @@ fn check_code_formatting() {
20 panic!("{}. Please format the code by running `cargo format`", error); 22 panic!("{}. Please format the code by running `cargo format`", error);
21 } 23 }
22} 24}
25
26#[test]
27fn no_todo() {
28 WalkDir::new(project_root().join("crates")).into_iter().for_each(|e| {
29 let e = e.unwrap();
30 if e.path().extension().map(|it| it != "rs").unwrap_or(true) {
31 return;
32 }
33 if e.path().ends_with("tests/cli.rs") {
34 return;
35 }
36 let text = std::fs::read_to_string(e.path()).unwrap();
37 if text.contains("TODO") {
38 panic!(
39 "\nTODO markers should not be commited to the master branch,\n\
40 use FIXME instead\n\
41 {}\n",
42 e.path().display(),
43 )
44 }
45 })
46}