aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src')
-rw-r--r--crates/hir_ty/src/diagnostics.rs15
-rw-r--r--crates/hir_ty/src/diagnostics/decl_check.rs103
2 files changed, 60 insertions, 58 deletions
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,