aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/hir/src/code_model.rs10
-rw-r--r--crates/hir/src/db.rs4
-rw-r--r--crates/hir_def/src/db.rs7
-rw-r--r--crates/hir_def/src/item_tree.rs8
-rw-r--r--crates/hir_def/src/item_tree/lower.rs24
-rw-r--r--crates/hir_def/src/lang_item.rs77
-rw-r--r--crates/hir_def/src/nameres/collector.rs34
-rw-r--r--crates/hir_ty/src/diagnostics.rs15
-rw-r--r--crates/hir_ty/src/diagnostics/decl_check.rs103
-rw-r--r--crates/ide_db/src/apply_change.rs1
10 files changed, 128 insertions, 155 deletions
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs
index 9bfcd215a..b1a1bc337 100644
--- a/crates/hir/src/code_model.rs
+++ b/crates/hir/src/code_model.rs
@@ -267,7 +267,12 @@ impl ModuleDef {
267 _ => return, 267 _ => return,
268 }; 268 };
269 269
270 hir_ty::diagnostics::validate_module_item(db, id, sink) 270 let module = match self.module(db) {
271 Some(it) => it,
272 None => return,
273 };
274
275 hir_ty::diagnostics::validate_module_item(db, module.id.krate, id, sink)
271 } 276 }
272} 277}
273 278
@@ -780,8 +785,9 @@ impl Function {
780 } 785 }
781 786
782 pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { 787 pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) {
788 let krate = self.module(db).id.krate;
783 hir_def::diagnostics::validate_body(db.upcast(), self.id.into(), sink); 789 hir_def::diagnostics::validate_body(db.upcast(), self.id.into(), sink);
784 hir_ty::diagnostics::validate_module_item(db, self.id.into(), sink); 790 hir_ty::diagnostics::validate_module_item(db, krate, self.id.into(), sink);
785 hir_ty::diagnostics::validate_body(db, self.id.into(), sink); 791 hir_ty::diagnostics::validate_body(db, self.id.into(), sink);
786 } 792 }
787 793
diff --git a/crates/hir/src/db.rs b/crates/hir/src/db.rs
index 8d949b264..d01e1b33d 100644
--- a/crates/hir/src/db.rs
+++ b/crates/hir/src/db.rs
@@ -6,8 +6,8 @@ pub use hir_def::db::{
6 FunctionDataQuery, GenericParamsQuery, ImplDataQuery, ImportMapQuery, InternConstQuery, 6 FunctionDataQuery, GenericParamsQuery, ImplDataQuery, ImportMapQuery, InternConstQuery,
7 InternDatabase, InternDatabaseStorage, InternEnumQuery, InternFunctionQuery, InternImplQuery, 7 InternDatabase, InternDatabaseStorage, InternEnumQuery, InternFunctionQuery, InternImplQuery,
8 InternStaticQuery, InternStructQuery, InternTraitQuery, InternTypeAliasQuery, InternUnionQuery, 8 InternStaticQuery, InternStructQuery, InternTraitQuery, InternTypeAliasQuery, InternUnionQuery,
9 ItemTreeQuery, LangItemQuery, ModuleLangItemsQuery, StaticDataQuery, StructDataQuery, 9 ItemTreeQuery, LangItemQuery, StaticDataQuery, StructDataQuery, TraitDataQuery,
10 TraitDataQuery, TypeAliasDataQuery, UnionDataQuery, 10 TypeAliasDataQuery, UnionDataQuery,
11}; 11};
12pub use hir_expand::db::{ 12pub use hir_expand::db::{
13 AstDatabase, AstDatabaseStorage, AstIdMapQuery, InternEagerExpansionQuery, InternMacroQuery, 13 AstDatabase, AstDatabaseStorage, AstIdMapQuery, InternEagerExpansionQuery, InternMacroQuery,
diff --git a/crates/hir_def/src/db.rs b/crates/hir_def/src/db.rs
index 7f250da33..d1a459066 100644
--- a/crates/hir_def/src/db.rs
+++ b/crates/hir_def/src/db.rs
@@ -16,8 +16,8 @@ use crate::{
16 lang_item::{LangItemTarget, LangItems}, 16 lang_item::{LangItemTarget, LangItems},
17 nameres::CrateDefMap, 17 nameres::CrateDefMap,
18 AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc, 18 AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc,
19 GenericDefId, ImplId, ImplLoc, ModuleId, StaticId, StaticLoc, StructId, StructLoc, TraitId, 19 GenericDefId, ImplId, ImplLoc, StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc,
20 TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, 20 TypeAliasId, TypeAliasLoc, UnionId, UnionLoc,
21}; 21};
22 22
23#[salsa::query_group(InternDatabaseStorage)] 23#[salsa::query_group(InternDatabaseStorage)]
@@ -95,9 +95,6 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
95 #[salsa::invoke(Attrs::attrs_query)] 95 #[salsa::invoke(Attrs::attrs_query)]
96 fn attrs(&self, def: AttrDefId) -> Attrs; 96 fn attrs(&self, def: AttrDefId) -> Attrs;
97 97
98 #[salsa::invoke(LangItems::module_lang_items_query)]
99 fn module_lang_items(&self, module: ModuleId) -> Option<Arc<LangItems>>;
100
101 #[salsa::invoke(LangItems::crate_lang_items_query)] 98 #[salsa::invoke(LangItems::crate_lang_items_query)]
102 fn crate_lang_items(&self, krate: CrateId) -> Arc<LangItems>; 99 fn crate_lang_items(&self, krate: CrateId) -> Arc<LangItems>;
103 100
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs
index 8cd0b18cc..b8e09e3af 100644
--- a/crates/hir_def/src/item_tree.rs
+++ b/crates/hir_def/src/item_tree.rs
@@ -646,12 +646,6 @@ pub struct MacroCall {
646pub struct MacroRules { 646pub struct MacroRules {
647 /// The name of the declared macro. 647 /// The name of the declared macro.
648 pub name: Name, 648 pub name: Name,
649 /// Has `#[macro_export]`.
650 pub is_export: bool,
651 /// Has `#[macro_export(local_inner_macros)]`.
652 pub is_local_inner: bool,
653 /// Has `#[rustc_builtin_macro]`.
654 pub is_builtin: bool,
655 pub ast_id: FileAstId<ast::MacroRules>, 649 pub ast_id: FileAstId<ast::MacroRules>,
656} 650}
657 651
@@ -660,8 +654,6 @@ pub struct MacroRules {
660pub struct MacroDef { 654pub struct MacroDef {
661 pub name: Name, 655 pub name: Name,
662 pub visibility: RawVisibilityId, 656 pub visibility: RawVisibilityId,
663 /// Has `#[rustc_builtin_macro]`.
664 pub is_builtin: bool,
665 pub ast_id: FileAstId<ast::MacroDef>, 657 pub ast_id: FileAstId<ast::MacroDef>,
666} 658}
667 659
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs
index dd3409762..7de385ee8 100644
--- a/crates/hir_def/src/item_tree/lower.rs
+++ b/crates/hir_def/src/item_tree/lower.rs
@@ -539,39 +539,19 @@ impl Ctx {
539 539
540 fn lower_macro_rules(&mut self, m: &ast::MacroRules) -> Option<FileItemTreeId<MacroRules>> { 540 fn lower_macro_rules(&mut self, m: &ast::MacroRules) -> Option<FileItemTreeId<MacroRules>> {
541 let name = m.name().map(|it| it.as_name())?; 541 let name = m.name().map(|it| it.as_name())?;
542 let attrs = Attrs::new(m, &self.hygiene);
543
544 let ast_id = self.source_ast_id_map.ast_id(m); 542 let ast_id = self.source_ast_id_map.ast_id(m);
545 543
546 // FIXME: cfg_attr 544 let res = MacroRules { name, ast_id };
547 let export_attr = attrs.by_key("macro_export");
548
549 let is_export = export_attr.exists();
550 let is_local_inner = if is_export {
551 export_attr.tt_values().map(|it| &it.token_trees).flatten().any(|it| match it {
552 tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => {
553 ident.text.contains("local_inner_macros")
554 }
555 _ => false,
556 })
557 } else {
558 false
559 };
560
561 let is_builtin = attrs.by_key("rustc_builtin_macro").exists();
562 let res = MacroRules { name, is_export, is_builtin, is_local_inner, ast_id };
563 Some(id(self.data().macro_rules.alloc(res))) 545 Some(id(self.data().macro_rules.alloc(res)))
564 } 546 }
565 547
566 fn lower_macro_def(&mut self, m: &ast::MacroDef) -> Option<FileItemTreeId<MacroDef>> { 548 fn lower_macro_def(&mut self, m: &ast::MacroDef) -> Option<FileItemTreeId<MacroDef>> {
567 let name = m.name().map(|it| it.as_name())?; 549 let name = m.name().map(|it| it.as_name())?;
568 let attrs = Attrs::new(m, &self.hygiene);
569 550
570 let ast_id = self.source_ast_id_map.ast_id(m); 551 let ast_id = self.source_ast_id_map.ast_id(m);
571 let visibility = self.lower_visibility(m); 552 let visibility = self.lower_visibility(m);
572 553
573 let is_builtin = attrs.by_key("rustc_builtin_macro").exists(); 554 let res = MacroDef { name, ast_id, visibility };
574 let res = MacroDef { name, is_builtin, ast_id, visibility };
575 Some(id(self.data().macro_defs.alloc(res))) 555 Some(id(self.data().macro_defs.alloc(res)))
576 } 556 }
577 557
diff --git a/crates/hir_def/src/lang_item.rs b/crates/hir_def/src/lang_item.rs
index 063eadccb..30188b740 100644
--- a/crates/hir_def/src/lang_item.rs
+++ b/crates/hir_def/src/lang_item.rs
@@ -8,8 +8,8 @@ use rustc_hash::FxHashMap;
8use syntax::SmolStr; 8use syntax::SmolStr;
9 9
10use crate::{ 10use crate::{
11 db::DefDatabase, AdtId, AttrDefId, CrateId, EnumId, FunctionId, ImplId, ModuleDefId, ModuleId, 11 db::DefDatabase, AdtId, AttrDefId, CrateId, EnumId, FunctionId, ImplId, ModuleDefId, StaticId,
12 StaticId, StructId, TraitId, 12 StructId, TraitId,
13}; 13};
14 14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -84,27 +84,34 @@ impl LangItems {
84 84
85 let crate_def_map = db.crate_def_map(krate); 85 let crate_def_map = db.crate_def_map(krate);
86 86
87 crate_def_map 87 for (_, module_data) in crate_def_map.modules.iter() {
88 .modules 88 for impl_def in module_data.scope.impls() {
89 .iter() 89 lang_items.collect_lang_item(db, impl_def, LangItemTarget::ImplDefId)
90 .filter_map(|(local_id, _)| db.module_lang_items(ModuleId { krate, local_id })) 90 }
91 .for_each(|it| lang_items.items.extend(it.items.iter().map(|(k, v)| (k.clone(), *v))));
92
93 Arc::new(lang_items)
94 }
95 91
96 pub(crate) fn module_lang_items_query( 92 for def in module_data.scope.declarations() {
97 db: &dyn DefDatabase, 93 match def {
98 module: ModuleId, 94 ModuleDefId::TraitId(trait_) => {
99 ) -> Option<Arc<LangItems>> { 95 lang_items.collect_lang_item(db, trait_, LangItemTarget::TraitId)
100 let _p = profile::span("module_lang_items_query"); 96 }
101 let mut lang_items = LangItems::default(); 97 ModuleDefId::AdtId(AdtId::EnumId(e)) => {
102 lang_items.collect_lang_items(db, module); 98 lang_items.collect_lang_item(db, e, LangItemTarget::EnumId)
103 if lang_items.items.is_empty() { 99 }
104 None 100 ModuleDefId::AdtId(AdtId::StructId(s)) => {
105 } else { 101 lang_items.collect_lang_item(db, s, LangItemTarget::StructId)
106 Some(Arc::new(lang_items)) 102 }
103 ModuleDefId::FunctionId(f) => {
104 lang_items.collect_lang_item(db, f, LangItemTarget::FunctionId)
105 }
106 ModuleDefId::StaticId(s) => {
107 lang_items.collect_lang_item(db, s, LangItemTarget::StaticId)
108 }
109 _ => {}
110 }
111 }
107 } 112 }
113
114 Arc::new(lang_items)
108 } 115 }
109 116
110 /// Salsa query. Look for a lang item, starting from the specified crate and recursively 117 /// Salsa query. Look for a lang item, starting from the specified crate and recursively
@@ -126,34 +133,6 @@ impl LangItems {
126 .find_map(|dep| db.lang_item(dep.crate_id, item.clone())) 133 .find_map(|dep| db.lang_item(dep.crate_id, item.clone()))
127 } 134 }
128 135
129 fn collect_lang_items(&mut self, db: &dyn DefDatabase, module: ModuleId) {
130 // Look for impl targets
131 let def_map = db.crate_def_map(module.krate);
132 let module_data = &def_map[module.local_id];
133 for impl_def in module_data.scope.impls() {
134 self.collect_lang_item(db, impl_def, LangItemTarget::ImplDefId)
135 }
136
137 for def in module_data.scope.declarations() {
138 match def {
139 ModuleDefId::TraitId(trait_) => {
140 self.collect_lang_item(db, trait_, LangItemTarget::TraitId)
141 }
142 ModuleDefId::AdtId(AdtId::EnumId(e)) => {
143 self.collect_lang_item(db, e, LangItemTarget::EnumId)
144 }
145 ModuleDefId::AdtId(AdtId::StructId(s)) => {
146 self.collect_lang_item(db, s, LangItemTarget::StructId)
147 }
148 ModuleDefId::FunctionId(f) => {
149 self.collect_lang_item(db, f, LangItemTarget::FunctionId)
150 }
151 ModuleDefId::StaticId(s) => self.collect_lang_item(db, s, LangItemTarget::StaticId),
152 _ => {}
153 }
154 }
155 }
156
157 fn collect_lang_item<T>( 136 fn collect_lang_item<T>(
158 &mut self, 137 &mut self,
159 db: &dyn DefDatabase, 138 db: &dyn DefDatabase,
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 785895277..1936348fb 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -26,7 +26,8 @@ use crate::{
26 db::DefDatabase, 26 db::DefDatabase,
27 item_scope::{ImportType, PerNsGlobImports}, 27 item_scope::{ImportType, PerNsGlobImports},
28 item_tree::{ 28 item_tree::{
29 self, ItemTree, ItemTreeId, MacroCall, MacroRules, Mod, ModItem, ModKind, StructDefKind, 29 self, FileItemTreeId, ItemTree, ItemTreeId, MacroCall, MacroRules, Mod, ModItem, ModKind,
30 StructDefKind,
30 }, 31 },
31 nameres::{ 32 nameres::{
32 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, 33 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint,
@@ -967,14 +968,15 @@ impl ModCollector<'_, '_> {
967 }) 968 })
968 } 969 }
969 ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac]), 970 ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac]),
970 ModItem::MacroRules(mac) => self.collect_macro_rules(&self.item_tree[mac]), 971 ModItem::MacroRules(id) => self.collect_macro_rules(id),
971 ModItem::MacroDef(id) => { 972 ModItem::MacroDef(id) => {
972 let mac = &self.item_tree[id]; 973 let mac = &self.item_tree[id];
973 let ast_id = InFile::new(self.file_id, mac.ast_id.upcast()); 974 let ast_id = InFile::new(self.file_id, mac.ast_id.upcast());
974 975
975 // "Macro 2.0" is not currently supported by rust-analyzer, but libcore uses it 976 // "Macro 2.0" is not currently supported by rust-analyzer, but libcore uses it
976 // to define builtin macros, so we support at least that part. 977 // to define builtin macros, so we support at least that part.
977 if mac.is_builtin { 978 let attrs = self.item_tree.attrs(ModItem::from(id).into());
979 if attrs.by_key("rustc_builtin_macro").exists() {
978 let krate = self.def_collector.def_map.krate; 980 let krate = self.def_collector.def_map.krate;
979 let macro_id = find_builtin_macro(&mac.name, krate, ast_id) 981 let macro_id = find_builtin_macro(&mac.name, krate, ast_id)
980 .or_else(|| find_builtin_derive(&mac.name, krate, ast_id)); 982 .or_else(|| find_builtin_derive(&mac.name, krate, ast_id));
@@ -1300,18 +1302,34 @@ impl ModCollector<'_, '_> {
1300 self.def_collector.resolve_proc_macro(&macro_name); 1302 self.def_collector.resolve_proc_macro(&macro_name);
1301 } 1303 }
1302 1304
1303 fn collect_macro_rules(&mut self, mac: &MacroRules) { 1305 fn collect_macro_rules(&mut self, id: FileItemTreeId<MacroRules>) {
1306 let mac = &self.item_tree[id];
1307 let attrs = self.item_tree.attrs(ModItem::from(id).into());
1304 let ast_id = InFile::new(self.file_id, mac.ast_id.upcast()); 1308 let ast_id = InFile::new(self.file_id, mac.ast_id.upcast());
1305 1309
1310 let export_attr = attrs.by_key("macro_export");
1311
1312 let is_export = export_attr.exists();
1313 let is_local_inner = if is_export {
1314 export_attr.tt_values().map(|it| &it.token_trees).flatten().any(|it| match it {
1315 tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => {
1316 ident.text.contains("local_inner_macros")
1317 }
1318 _ => false,
1319 })
1320 } else {
1321 false
1322 };
1323
1306 // Case 1: builtin macros 1324 // Case 1: builtin macros
1307 if mac.is_builtin { 1325 if attrs.by_key("rustc_builtin_macro").exists() {
1308 let krate = self.def_collector.def_map.krate; 1326 let krate = self.def_collector.def_map.krate;
1309 if let Some(macro_id) = find_builtin_macro(&mac.name, krate, ast_id) { 1327 if let Some(macro_id) = find_builtin_macro(&mac.name, krate, ast_id) {
1310 self.def_collector.define_macro( 1328 self.def_collector.define_macro(
1311 self.module_id, 1329 self.module_id,
1312 mac.name.clone(), 1330 mac.name.clone(),
1313 macro_id, 1331 macro_id,
1314 mac.is_export, 1332 is_export,
1315 ); 1333 );
1316 return; 1334 return;
1317 } 1335 }
@@ -1322,9 +1340,9 @@ impl ModCollector<'_, '_> {
1322 ast_id: Some(ast_id), 1340 ast_id: Some(ast_id),
1323 krate: self.def_collector.def_map.krate, 1341 krate: self.def_collector.def_map.krate,
1324 kind: MacroDefKind::Declarative, 1342 kind: MacroDefKind::Declarative,
1325 local_inner: mac.is_local_inner, 1343 local_inner: is_local_inner,
1326 }; 1344 };
1327 self.def_collector.define_macro(self.module_id, mac.name.clone(), macro_id, mac.is_export); 1345 self.def_collector.define_macro(self.module_id, mac.name.clone(), macro_id, is_export);
1328 } 1346 }
1329 1347
1330 fn collect_macro_call(&mut self, mac: &MacroCall) { 1348 fn collect_macro_call(&mut self, mac: &MacroCall) {
diff --git a/crates/hir_ty/src/diagnostics.rs b/crates/hir_ty/src/diagnostics.rs
index 1c72f766e..14e18f5a1 100644
--- a/crates/hir_ty/src/diagnostics.rs
+++ b/crates/hir_ty/src/diagnostics.rs
@@ -6,6 +6,7 @@ mod decl_check;
6 6
7use std::{any::Any, fmt}; 7use std::{any::Any, fmt};
8 8
9use base_db::CrateId;
9use hir_def::{DefWithBodyId, ModuleDefId}; 10use hir_def::{DefWithBodyId, ModuleDefId};
10use hir_expand::diagnostics::{Diagnostic, DiagnosticCode, DiagnosticSink}; 11use hir_expand::diagnostics::{Diagnostic, DiagnosticCode, DiagnosticSink};
11use hir_expand::{name::Name, HirFileId, InFile}; 12use hir_expand::{name::Name, HirFileId, InFile};
@@ -18,12 +19,13 @@ pub use crate::diagnostics::expr::{record_literal_missing_fields, record_pattern
18 19
19pub fn validate_module_item( 20pub fn validate_module_item(
20 db: &dyn HirDatabase, 21 db: &dyn HirDatabase,
22 krate: CrateId,
21 owner: ModuleDefId, 23 owner: ModuleDefId,
22 sink: &mut DiagnosticSink<'_>, 24 sink: &mut DiagnosticSink<'_>,
23) { 25) {
24 let _p = profile::span("validate_module_item"); 26 let _p = profile::span("validate_module_item");
25 let mut validator = decl_check::DeclValidator::new(owner, sink); 27 let mut validator = decl_check::DeclValidator::new(db, krate, sink);
26 validator.validate_item(db); 28 validator.validate_item(owner);
27} 29}
28 30
29pub fn validate_body(db: &dyn HirDatabase, owner: DefWithBodyId, sink: &mut DiagnosticSink<'_>) { 31pub fn validate_body(db: &dyn HirDatabase, owner: DefWithBodyId, sink: &mut DiagnosticSink<'_>) {
@@ -407,7 +409,7 @@ mod tests {
407 for (module_id, _) in crate_def_map.modules.iter() { 409 for (module_id, _) in crate_def_map.modules.iter() {
408 for decl in crate_def_map[module_id].scope.declarations() { 410 for decl in crate_def_map[module_id].scope.declarations() {
409 let mut sink = DiagnosticSinkBuilder::new().build(&mut cb); 411 let mut sink = DiagnosticSinkBuilder::new().build(&mut cb);
410 validate_module_item(self, decl, &mut sink); 412 validate_module_item(self, krate, decl, &mut sink);
411 413
412 if let ModuleDefId::FunctionId(f) = decl { 414 if let ModuleDefId::FunctionId(f) = decl {
413 fns.push(f) 415 fns.push(f)
@@ -419,7 +421,12 @@ mod tests {
419 for item in impl_data.items.iter() { 421 for item in impl_data.items.iter() {
420 if let AssocItemId::FunctionId(f) = item { 422 if let AssocItemId::FunctionId(f) = item {
421 let mut sink = DiagnosticSinkBuilder::new().build(&mut cb); 423 let mut sink = DiagnosticSinkBuilder::new().build(&mut cb);
422 validate_module_item(self, ModuleDefId::FunctionId(*f), &mut sink); 424 validate_module_item(
425 self,
426 krate,
427 ModuleDefId::FunctionId(*f),
428 &mut sink,
429 );
423 fns.push(*f) 430 fns.push(*f)
424 } 431 }
425 } 432 }
diff --git a/crates/hir_ty/src/diagnostics/decl_check.rs b/crates/hir_ty/src/diagnostics/decl_check.rs
index 25587e116..eaeb6899f 100644
--- a/crates/hir_ty/src/diagnostics/decl_check.rs
+++ b/crates/hir_ty/src/diagnostics/decl_check.rs
@@ -12,6 +12,7 @@
12 12
13mod case_conv; 13mod case_conv;
14 14
15use base_db::CrateId;
15use hir_def::{ 16use hir_def::{
16 adt::VariantData, 17 adt::VariantData,
17 expr::{Pat, PatId}, 18 expr::{Pat, PatId},
@@ -40,7 +41,8 @@ mod allow {
40} 41}
41 42
42pub(super) struct DeclValidator<'a, 'b: 'a> { 43pub(super) struct DeclValidator<'a, 'b: 'a> {
43 owner: ModuleDefId, 44 db: &'a dyn HirDatabase,
45 krate: CrateId,
44 sink: &'a mut DiagnosticSink<'b>, 46 sink: &'a mut DiagnosticSink<'b>,
45} 47}
46 48
@@ -53,26 +55,27 @@ struct Replacement {
53 55
54impl<'a, 'b> DeclValidator<'a, 'b> { 56impl<'a, 'b> DeclValidator<'a, 'b> {
55 pub(super) fn new( 57 pub(super) fn new(
56 owner: ModuleDefId, 58 db: &'a dyn HirDatabase,
59 krate: CrateId,
57 sink: &'a mut DiagnosticSink<'b>, 60 sink: &'a mut DiagnosticSink<'b>,
58 ) -> DeclValidator<'a, 'b> { 61 ) -> DeclValidator<'a, 'b> {
59 DeclValidator { owner, sink } 62 DeclValidator { db, krate, sink }
60 } 63 }
61 64
62 pub(super) fn validate_item(&mut self, db: &dyn HirDatabase) { 65 pub(super) fn validate_item(&mut self, item: ModuleDefId) {
63 match self.owner { 66 match item {
64 ModuleDefId::FunctionId(func) => self.validate_func(db, func), 67 ModuleDefId::FunctionId(func) => self.validate_func(func),
65 ModuleDefId::AdtId(adt) => self.validate_adt(db, adt), 68 ModuleDefId::AdtId(adt) => self.validate_adt(adt),
66 ModuleDefId::ConstId(const_id) => self.validate_const(db, const_id), 69 ModuleDefId::ConstId(const_id) => self.validate_const(const_id),
67 ModuleDefId::StaticId(static_id) => self.validate_static(db, static_id), 70 ModuleDefId::StaticId(static_id) => self.validate_static(static_id),
68 _ => return, 71 _ => return,
69 } 72 }
70 } 73 }
71 74
72 fn validate_adt(&mut self, db: &dyn HirDatabase, adt: AdtId) { 75 fn validate_adt(&mut self, adt: AdtId) {
73 match adt { 76 match adt {
74 AdtId::StructId(struct_id) => self.validate_struct(db, struct_id), 77 AdtId::StructId(struct_id) => self.validate_struct(struct_id),
75 AdtId::EnumId(enum_id) => self.validate_enum(db, enum_id), 78 AdtId::EnumId(enum_id) => self.validate_enum(enum_id),
76 AdtId::UnionId(_) => { 79 AdtId::UnionId(_) => {
77 // Unions aren't yet supported by this validator. 80 // Unions aren't yet supported by this validator.
78 } 81 }
@@ -82,27 +85,27 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
82 /// Checks whether not following the convention is allowed for this item. 85 /// Checks whether not following the convention is allowed for this item.
83 /// 86 ///
84 /// Currently this method doesn't check parent attributes. 87 /// Currently this method doesn't check parent attributes.
85 fn allowed(&self, db: &dyn HirDatabase, id: AttrDefId, allow_name: &str) -> bool { 88 fn allowed(&self, id: AttrDefId, allow_name: &str) -> bool {
86 db.attrs(id).by_key("allow").tt_values().any(|tt| tt.to_string().contains(allow_name)) 89 self.db.attrs(id).by_key("allow").tt_values().any(|tt| tt.to_string().contains(allow_name))
87 } 90 }
88 91
89 fn validate_func(&mut self, db: &dyn HirDatabase, func: FunctionId) { 92 fn validate_func(&mut self, func: FunctionId) {
90 let data = db.function_data(func); 93 let data = self.db.function_data(func);
91 if data.is_extern { 94 if data.is_extern {
92 mark::hit!(extern_func_incorrect_case_ignored); 95 mark::hit!(extern_func_incorrect_case_ignored);
93 return; 96 return;
94 } 97 }
95 98
96 let body = db.body(func.into()); 99 let body = self.db.body(func.into());
97 100
98 // Recursively validate inner scope items, such as static variables and constants. 101 // Recursively validate inner scope items, such as static variables and constants.
99 for (item_id, _) in body.item_scope.values() { 102 for (item_id, _) in body.item_scope.values() {
100 let mut validator = DeclValidator::new(item_id, self.sink); 103 let mut validator = DeclValidator::new(self.db, self.krate, self.sink);
101 validator.validate_item(db); 104 validator.validate_item(item_id);
102 } 105 }
103 106
104 // Check whether non-snake case identifiers are allowed for this function. 107 // Check whether non-snake case identifiers are allowed for this function.
105 if self.allowed(db, func.into(), allow::NON_SNAKE_CASE) { 108 if self.allowed(func.into(), allow::NON_SNAKE_CASE) {
106 return; 109 return;
107 } 110 }
108 111
@@ -169,11 +172,10 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
169 // If there is at least one element to spawn a warning on, go to the source map and generate a warning. 172 // If there is at least one element to spawn a warning on, go to the source map and generate a warning.
170 self.create_incorrect_case_diagnostic_for_func( 173 self.create_incorrect_case_diagnostic_for_func(
171 func, 174 func,
172 db,
173 fn_name_replacement, 175 fn_name_replacement,
174 fn_param_replacements, 176 fn_param_replacements,
175 ); 177 );
176 self.create_incorrect_case_diagnostic_for_variables(func, db, pats_replacements); 178 self.create_incorrect_case_diagnostic_for_variables(func, pats_replacements);
177 } 179 }
178 180
179 /// Given the information about incorrect names in the function declaration, looks up into the source code 181 /// Given the information about incorrect names in the function declaration, looks up into the source code
@@ -181,7 +183,6 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
181 fn create_incorrect_case_diagnostic_for_func( 183 fn create_incorrect_case_diagnostic_for_func(
182 &mut self, 184 &mut self,
183 func: FunctionId, 185 func: FunctionId,
184 db: &dyn HirDatabase,
185 fn_name_replacement: Option<Replacement>, 186 fn_name_replacement: Option<Replacement>,
186 fn_param_replacements: Vec<Replacement>, 187 fn_param_replacements: Vec<Replacement>,
187 ) { 188 ) {
@@ -190,8 +191,8 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
190 return; 191 return;
191 } 192 }
192 193
193 let fn_loc = func.lookup(db.upcast()); 194 let fn_loc = func.lookup(self.db.upcast());
194 let fn_src = fn_loc.source(db.upcast()); 195 let fn_src = fn_loc.source(self.db.upcast());
195 196
196 // Diagnostic for function name. 197 // Diagnostic for function name.
197 if let Some(replacement) = fn_name_replacement { 198 if let Some(replacement) = fn_name_replacement {
@@ -282,7 +283,6 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
282 fn create_incorrect_case_diagnostic_for_variables( 283 fn create_incorrect_case_diagnostic_for_variables(
283 &mut self, 284 &mut self,
284 func: FunctionId, 285 func: FunctionId,
285 db: &dyn HirDatabase,
286 pats_replacements: Vec<(PatId, Replacement)>, 286 pats_replacements: Vec<(PatId, Replacement)>,
287 ) { 287 ) {
288 // XXX: only look at source_map if we do have missing fields 288 // XXX: only look at source_map if we do have missing fields
@@ -290,12 +290,12 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
290 return; 290 return;
291 } 291 }
292 292
293 let (_, source_map) = db.body_with_source_map(func.into()); 293 let (_, source_map) = self.db.body_with_source_map(func.into());
294 294
295 for (id, replacement) in pats_replacements { 295 for (id, replacement) in pats_replacements {
296 if let Ok(source_ptr) = source_map.pat_syntax(id) { 296 if let Ok(source_ptr) = source_map.pat_syntax(id) {
297 if let Some(expr) = source_ptr.value.as_ref().left() { 297 if let Some(expr) = source_ptr.value.as_ref().left() {
298 let root = source_ptr.file_syntax(db.upcast()); 298 let root = source_ptr.file_syntax(self.db.upcast());
299 if let ast::Pat::IdentPat(ident_pat) = expr.to_node(&root) { 299 if let ast::Pat::IdentPat(ident_pat) = expr.to_node(&root) {
300 let parent = match ident_pat.syntax().parent() { 300 let parent = match ident_pat.syntax().parent() {
301 Some(parent) => parent, 301 Some(parent) => parent,
@@ -333,12 +333,11 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
333 } 333 }
334 } 334 }
335 335
336 fn validate_struct(&mut self, db: &dyn HirDatabase, struct_id: StructId) { 336 fn validate_struct(&mut self, struct_id: StructId) {
337 let data = db.struct_data(struct_id); 337 let data = self.db.struct_data(struct_id);
338 338
339 let non_camel_case_allowed = 339 let non_camel_case_allowed = self.allowed(struct_id.into(), allow::NON_CAMEL_CASE_TYPES);
340 self.allowed(db, struct_id.into(), allow::NON_CAMEL_CASE_TYPES); 340 let non_snake_case_allowed = self.allowed(struct_id.into(), allow::NON_SNAKE_CASE);
341 let non_snake_case_allowed = self.allowed(db, struct_id.into(), allow::NON_SNAKE_CASE);
342 341
343 // Check the structure name. 342 // Check the structure name.
344 let struct_name = data.name.to_string(); 343 let struct_name = data.name.to_string();
@@ -379,7 +378,6 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
379 // If there is at least one element to spawn a warning on, go to the source map and generate a warning. 378 // If there is at least one element to spawn a warning on, go to the source map and generate a warning.
380 self.create_incorrect_case_diagnostic_for_struct( 379 self.create_incorrect_case_diagnostic_for_struct(
381 struct_id, 380 struct_id,
382 db,
383 struct_name_replacement, 381 struct_name_replacement,
384 struct_fields_replacements, 382 struct_fields_replacements,
385 ); 383 );
@@ -390,7 +388,6 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
390 fn create_incorrect_case_diagnostic_for_struct( 388 fn create_incorrect_case_diagnostic_for_struct(
391 &mut self, 389 &mut self,
392 struct_id: StructId, 390 struct_id: StructId,
393 db: &dyn HirDatabase,
394 struct_name_replacement: Option<Replacement>, 391 struct_name_replacement: Option<Replacement>,
395 struct_fields_replacements: Vec<Replacement>, 392 struct_fields_replacements: Vec<Replacement>,
396 ) { 393 ) {
@@ -399,8 +396,8 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
399 return; 396 return;
400 } 397 }
401 398
402 let struct_loc = struct_id.lookup(db.upcast()); 399 let struct_loc = struct_id.lookup(self.db.upcast());
403 let struct_src = struct_loc.source(db.upcast()); 400 let struct_src = struct_loc.source(self.db.upcast());
404 401
405 if let Some(replacement) = struct_name_replacement { 402 if let Some(replacement) = struct_name_replacement {
406 let ast_ptr = match struct_src.value.name() { 403 let ast_ptr = match struct_src.value.name() {
@@ -473,11 +470,11 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
473 } 470 }
474 } 471 }
475 472
476 fn validate_enum(&mut self, db: &dyn HirDatabase, enum_id: EnumId) { 473 fn validate_enum(&mut self, enum_id: EnumId) {
477 let data = db.enum_data(enum_id); 474 let data = self.db.enum_data(enum_id);
478 475
479 // Check whether non-camel case names are allowed for this enum. 476 // Check whether non-camel case names are allowed for this enum.
480 if self.allowed(db, enum_id.into(), allow::NON_CAMEL_CASE_TYPES) { 477 if self.allowed(enum_id.into(), allow::NON_CAMEL_CASE_TYPES) {
481 return; 478 return;
482 } 479 }
483 480
@@ -512,7 +509,6 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
512 // If there is at least one element to spawn a warning on, go to the source map and generate a warning. 509 // If there is at least one element to spawn a warning on, go to the source map and generate a warning.
513 self.create_incorrect_case_diagnostic_for_enum( 510 self.create_incorrect_case_diagnostic_for_enum(
514 enum_id, 511 enum_id,
515 db,
516 enum_name_replacement, 512 enum_name_replacement,
517 enum_fields_replacements, 513 enum_fields_replacements,
518 ) 514 )
@@ -523,7 +519,6 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
523 fn create_incorrect_case_diagnostic_for_enum( 519 fn create_incorrect_case_diagnostic_for_enum(
524 &mut self, 520 &mut self,
525 enum_id: EnumId, 521 enum_id: EnumId,
526 db: &dyn HirDatabase,
527 enum_name_replacement: Option<Replacement>, 522 enum_name_replacement: Option<Replacement>,
528 enum_variants_replacements: Vec<Replacement>, 523 enum_variants_replacements: Vec<Replacement>,
529 ) { 524 ) {
@@ -532,8 +527,8 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
532 return; 527 return;
533 } 528 }
534 529
535 let enum_loc = enum_id.lookup(db.upcast()); 530 let enum_loc = enum_id.lookup(self.db.upcast());
536 let enum_src = enum_loc.source(db.upcast()); 531 let enum_src = enum_loc.source(self.db.upcast());
537 532
538 if let Some(replacement) = enum_name_replacement { 533 if let Some(replacement) = enum_name_replacement {
539 let ast_ptr = match enum_src.value.name() { 534 let ast_ptr = match enum_src.value.name() {
@@ -608,10 +603,10 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
608 } 603 }
609 } 604 }
610 605
611 fn validate_const(&mut self, db: &dyn HirDatabase, const_id: ConstId) { 606 fn validate_const(&mut self, const_id: ConstId) {
612 let data = db.const_data(const_id); 607 let data = self.db.const_data(const_id);
613 608
614 if self.allowed(db, const_id.into(), allow::NON_UPPER_CASE_GLOBAL) { 609 if self.allowed(const_id.into(), allow::NON_UPPER_CASE_GLOBAL) {
615 return; 610 return;
616 } 611 }
617 612
@@ -632,8 +627,8 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
632 return; 627 return;
633 }; 628 };
634 629
635 let const_loc = const_id.lookup(db.upcast()); 630 let const_loc = const_id.lookup(self.db.upcast());
636 let const_src = const_loc.source(db.upcast()); 631 let const_src = const_loc.source(self.db.upcast());
637 632
638 let ast_ptr = match const_src.value.name() { 633 let ast_ptr = match const_src.value.name() {
639 Some(name) => name, 634 Some(name) => name,
@@ -652,14 +647,14 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
652 self.sink.push(diagnostic); 647 self.sink.push(diagnostic);
653 } 648 }
654 649
655 fn validate_static(&mut self, db: &dyn HirDatabase, static_id: StaticId) { 650 fn validate_static(&mut self, static_id: StaticId) {
656 let data = db.static_data(static_id); 651 let data = self.db.static_data(static_id);
657 if data.is_extern { 652 if data.is_extern {
658 mark::hit!(extern_static_incorrect_case_ignored); 653 mark::hit!(extern_static_incorrect_case_ignored);
659 return; 654 return;
660 } 655 }
661 656
662 if self.allowed(db, static_id.into(), allow::NON_UPPER_CASE_GLOBAL) { 657 if self.allowed(static_id.into(), allow::NON_UPPER_CASE_GLOBAL) {
663 return; 658 return;
664 } 659 }
665 660
@@ -680,8 +675,8 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
680 return; 675 return;
681 }; 676 };
682 677
683 let static_loc = static_id.lookup(db.upcast()); 678 let static_loc = static_id.lookup(self.db.upcast());
684 let static_src = static_loc.source(db.upcast()); 679 let static_src = static_loc.source(self.db.upcast());
685 680
686 let ast_ptr = match static_src.value.name() { 681 let ast_ptr = match static_src.value.name() {
687 Some(name) => name, 682 Some(name) => name,
diff --git a/crates/ide_db/src/apply_change.rs b/crates/ide_db/src/apply_change.rs
index e2251f2b7..71c19ed13 100644
--- a/crates/ide_db/src/apply_change.rs
+++ b/crates/ide_db/src/apply_change.rs
@@ -163,7 +163,6 @@ impl RootDatabase {
163 hir::db::ExprScopesQuery 163 hir::db::ExprScopesQuery
164 hir::db::GenericParamsQuery 164 hir::db::GenericParamsQuery
165 hir::db::AttrsQuery 165 hir::db::AttrsQuery
166 hir::db::ModuleLangItemsQuery
167 hir::db::CrateLangItemsQuery 166 hir::db::CrateLangItemsQuery
168 hir::db::LangItemQuery 167 hir::db::LangItemQuery
169 hir::db::ImportMapQuery 168 hir::db::ImportMapQuery