diff options
author | Aleksey Kladov <[email protected]> | 2020-07-14 09:28:55 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2020-07-14 09:28:55 +0100 |
commit | 19450534cf308eff30ea7de1a40ab77dca4e6014 (patch) | |
tree | c2becab63418e6ffd88af4bfdd1b129b305cff6d | |
parent | 1fdbf81181356854b692fe0407bac75aba6ea942 (diff) |
Cleanup hir diagnostics API
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 9 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/diagnostics.rs | 15 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/diagnostics/expr.rs | 28 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/diagnostics/unsafe_check.rs | 23 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/test_db.rs | 12 |
6 files changed, 49 insertions, 48 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index dbda25d1d..42c9ca189 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -24,7 +24,6 @@ use hir_expand::{ | |||
24 | }; | 24 | }; |
25 | use hir_ty::{ | 25 | use hir_ty::{ |
26 | autoderef, | 26 | autoderef, |
27 | diagnostics::{expr::ExprValidator, unsafe_check::UnsafeValidator}, | ||
28 | display::{HirDisplayError, HirFormatter}, | 27 | display::{HirDisplayError, HirFormatter}, |
29 | method_resolution, ApplicationTy, Canonical, GenericPredicate, InEnvironment, Substs, | 28 | method_resolution, ApplicationTy, Canonical, GenericPredicate, InEnvironment, Substs, |
30 | TraitEnvironment, Ty, TyDefId, TypeCtor, | 29 | TraitEnvironment, Ty, TyDefId, TypeCtor, |
@@ -678,13 +677,7 @@ impl Function { | |||
678 | } | 677 | } |
679 | 678 | ||
680 | pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { | 679 | pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { |
681 | let _p = profile("Function::diagnostics"); | 680 | hir_ty::diagnostics::validate_body(db, self.id.into(), sink) |
682 | let infer = db.infer(self.id.into()); | ||
683 | infer.add_diagnostics(db, self.id, sink); | ||
684 | let mut validator = ExprValidator::new(self.id, infer.clone(), sink); | ||
685 | validator.validate_body(db); | ||
686 | let mut validator = UnsafeValidator::new(self.id, infer, sink); | ||
687 | validator.validate_body(db); | ||
688 | } | 681 | } |
689 | } | 682 | } |
690 | 683 | ||
diff --git a/crates/ra_hir_ty/src/diagnostics.rs b/crates/ra_hir_ty/src/diagnostics.rs index 07c7729b3..d9c2b1214 100644 --- a/crates/ra_hir_ty/src/diagnostics.rs +++ b/crates/ra_hir_ty/src/diagnostics.rs | |||
@@ -6,12 +6,25 @@ pub mod unsafe_check; | |||
6 | use std::any::Any; | 6 | use std::any::Any; |
7 | 7 | ||
8 | use hir_expand::{db::AstDatabase, name::Name, HirFileId, InFile}; | 8 | use hir_expand::{db::AstDatabase, name::Name, HirFileId, InFile}; |
9 | use ra_prof::profile; | ||
9 | use ra_syntax::{ast, AstNode, AstPtr, SyntaxNodePtr}; | 10 | use ra_syntax::{ast, AstNode, AstPtr, SyntaxNodePtr}; |
10 | use stdx::format_to; | 11 | use stdx::format_to; |
11 | 12 | ||
12 | pub use hir_def::{diagnostics::UnresolvedModule, expr::MatchArm, path::Path}; | 13 | pub use hir_def::{diagnostics::UnresolvedModule, expr::MatchArm, path::Path, DefWithBodyId}; |
13 | pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink}; | 14 | pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink}; |
14 | 15 | ||
16 | use crate::db::HirDatabase; | ||
17 | |||
18 | pub fn validate_body(db: &dyn HirDatabase, owner: DefWithBodyId, sink: &mut DiagnosticSink<'_>) { | ||
19 | let _p = profile("validate_body"); | ||
20 | let infer = db.infer(owner); | ||
21 | infer.add_diagnostics(db, owner, sink); | ||
22 | let mut validator = expr::ExprValidator::new(owner, infer.clone(), sink); | ||
23 | validator.validate_body(db); | ||
24 | let mut validator = unsafe_check::UnsafeValidator::new(owner, infer, sink); | ||
25 | validator.validate_body(db); | ||
26 | } | ||
27 | |||
15 | #[derive(Debug)] | 28 | #[derive(Debug)] |
16 | pub struct NoSuchField { | 29 | pub struct NoSuchField { |
17 | pub file: HirFileId, | 30 | pub file: HirFileId, |
diff --git a/crates/ra_hir_ty/src/diagnostics/expr.rs b/crates/ra_hir_ty/src/diagnostics/expr.rs index 51c97f801..239be779f 100644 --- a/crates/ra_hir_ty/src/diagnostics/expr.rs +++ b/crates/ra_hir_ty/src/diagnostics/expr.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use hir_def::{path::path, resolver::HasResolver, AdtId, FunctionId}; | 5 | use hir_def::{path::path, resolver::HasResolver, AdtId, DefWithBodyId}; |
6 | use hir_expand::diagnostics::DiagnosticSink; | 6 | use hir_expand::diagnostics::DiagnosticSink; |
7 | use ra_syntax::{ast, AstPtr}; | 7 | use ra_syntax::{ast, AstPtr}; |
8 | use rustc_hash::FxHashSet; | 8 | use rustc_hash::FxHashSet; |
@@ -30,23 +30,23 @@ pub use hir_def::{ | |||
30 | LocalFieldId, Lookup, VariantId, | 30 | LocalFieldId, Lookup, VariantId, |
31 | }; | 31 | }; |
32 | 32 | ||
33 | pub struct ExprValidator<'a, 'b: 'a> { | 33 | pub(super) struct ExprValidator<'a, 'b: 'a> { |
34 | func: FunctionId, | 34 | owner: DefWithBodyId, |
35 | infer: Arc<InferenceResult>, | 35 | infer: Arc<InferenceResult>, |
36 | sink: &'a mut DiagnosticSink<'b>, | 36 | sink: &'a mut DiagnosticSink<'b>, |
37 | } | 37 | } |
38 | 38 | ||
39 | impl<'a, 'b> ExprValidator<'a, 'b> { | 39 | impl<'a, 'b> ExprValidator<'a, 'b> { |
40 | pub fn new( | 40 | pub(super) fn new( |
41 | func: FunctionId, | 41 | owner: DefWithBodyId, |
42 | infer: Arc<InferenceResult>, | 42 | infer: Arc<InferenceResult>, |
43 | sink: &'a mut DiagnosticSink<'b>, | 43 | sink: &'a mut DiagnosticSink<'b>, |
44 | ) -> ExprValidator<'a, 'b> { | 44 | ) -> ExprValidator<'a, 'b> { |
45 | ExprValidator { func, infer, sink } | 45 | ExprValidator { owner, infer, sink } |
46 | } | 46 | } |
47 | 47 | ||
48 | pub fn validate_body(&mut self, db: &dyn HirDatabase) { | 48 | pub(super) fn validate_body(&mut self, db: &dyn HirDatabase) { |
49 | let body = db.body(self.func.into()); | 49 | let body = db.body(self.owner.into()); |
50 | 50 | ||
51 | for (id, expr) in body.exprs.iter() { | 51 | for (id, expr) in body.exprs.iter() { |
52 | if let Some((variant_def, missed_fields, true)) = | 52 | if let Some((variant_def, missed_fields, true)) = |
@@ -96,7 +96,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
96 | missed_fields: Vec<LocalFieldId>, | 96 | missed_fields: Vec<LocalFieldId>, |
97 | ) { | 97 | ) { |
98 | // XXX: only look at source_map if we do have missing fields | 98 | // XXX: only look at source_map if we do have missing fields |
99 | let (_, source_map) = db.body_with_source_map(self.func.into()); | 99 | let (_, source_map) = db.body_with_source_map(self.owner.into()); |
100 | 100 | ||
101 | if let Ok(source_ptr) = source_map.expr_syntax(id) { | 101 | if let Ok(source_ptr) = source_map.expr_syntax(id) { |
102 | let root = source_ptr.file_syntax(db.upcast()); | 102 | let root = source_ptr.file_syntax(db.upcast()); |
@@ -125,7 +125,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
125 | missed_fields: Vec<LocalFieldId>, | 125 | missed_fields: Vec<LocalFieldId>, |
126 | ) { | 126 | ) { |
127 | // XXX: only look at source_map if we do have missing fields | 127 | // XXX: only look at source_map if we do have missing fields |
128 | let (_, source_map) = db.body_with_source_map(self.func.into()); | 128 | let (_, source_map) = db.body_with_source_map(self.owner.into()); |
129 | 129 | ||
130 | if let Ok(source_ptr) = source_map.pat_syntax(id) { | 130 | if let Ok(source_ptr) = source_map.pat_syntax(id) { |
131 | if let Some(expr) = source_ptr.value.as_ref().left() { | 131 | if let Some(expr) = source_ptr.value.as_ref().left() { |
@@ -181,7 +181,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
181 | let mut arg_count = args.len(); | 181 | let mut arg_count = args.len(); |
182 | 182 | ||
183 | if arg_count != param_count { | 183 | if arg_count != param_count { |
184 | let (_, source_map) = db.body_with_source_map(self.func.into()); | 184 | let (_, source_map) = db.body_with_source_map(self.owner.into()); |
185 | if let Ok(source_ptr) = source_map.expr_syntax(call_id) { | 185 | if let Ok(source_ptr) = source_map.expr_syntax(call_id) { |
186 | if is_method_call { | 186 | if is_method_call { |
187 | param_count -= 1; | 187 | param_count -= 1; |
@@ -208,7 +208,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
208 | infer: Arc<InferenceResult>, | 208 | infer: Arc<InferenceResult>, |
209 | ) { | 209 | ) { |
210 | let (body, source_map): (Arc<Body>, Arc<BodySourceMap>) = | 210 | let (body, source_map): (Arc<Body>, Arc<BodySourceMap>) = |
211 | db.body_with_source_map(self.func.into()); | 211 | db.body_with_source_map(self.owner.into()); |
212 | 212 | ||
213 | let match_expr_ty = match infer.type_of_expr.get(match_expr) { | 213 | let match_expr_ty = match infer.type_of_expr.get(match_expr) { |
214 | Some(ty) => ty, | 214 | Some(ty) => ty, |
@@ -289,7 +289,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
289 | 289 | ||
290 | let core_result_path = path![core::result::Result]; | 290 | let core_result_path = path![core::result::Result]; |
291 | 291 | ||
292 | let resolver = self.func.resolver(db.upcast()); | 292 | let resolver = self.owner.resolver(db.upcast()); |
293 | let core_result_enum = match resolver.resolve_known_enum(db.upcast(), &core_result_path) { | 293 | let core_result_enum = match resolver.resolve_known_enum(db.upcast(), &core_result_path) { |
294 | Some(it) => it, | 294 | Some(it) => it, |
295 | _ => return, | 295 | _ => return, |
@@ -304,7 +304,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
304 | }; | 304 | }; |
305 | 305 | ||
306 | if params.len() == 2 && params[0] == mismatch.actual { | 306 | if params.len() == 2 && params[0] == mismatch.actual { |
307 | let (_, source_map) = db.body_with_source_map(self.func.into()); | 307 | let (_, source_map) = db.body_with_source_map(self.owner.into()); |
308 | 308 | ||
309 | if let Ok(source_ptr) = source_map.expr_syntax(id) { | 309 | if let Ok(source_ptr) = source_map.expr_syntax(id) { |
310 | self.sink | 310 | self.sink |
diff --git a/crates/ra_hir_ty/src/diagnostics/unsafe_check.rs b/crates/ra_hir_ty/src/diagnostics/unsafe_check.rs index c512c4f8e..b8ff95ee1 100644 --- a/crates/ra_hir_ty/src/diagnostics/unsafe_check.rs +++ b/crates/ra_hir_ty/src/diagnostics/unsafe_check.rs | |||
@@ -6,7 +6,7 @@ use std::sync::Arc; | |||
6 | use hir_def::{ | 6 | use hir_def::{ |
7 | body::Body, | 7 | body::Body, |
8 | expr::{Expr, ExprId, UnaryOp}, | 8 | expr::{Expr, ExprId, UnaryOp}, |
9 | DefWithBodyId, FunctionId, | 9 | DefWithBodyId, |
10 | }; | 10 | }; |
11 | use hir_expand::diagnostics::DiagnosticSink; | 11 | use hir_expand::diagnostics::DiagnosticSink; |
12 | 12 | ||
@@ -15,26 +15,29 @@ use crate::{ | |||
15 | InferenceResult, Ty, TypeCtor, | 15 | InferenceResult, Ty, TypeCtor, |
16 | }; | 16 | }; |
17 | 17 | ||
18 | pub struct UnsafeValidator<'a, 'b: 'a> { | 18 | pub(super) struct UnsafeValidator<'a, 'b: 'a> { |
19 | func: FunctionId, | 19 | owner: DefWithBodyId, |
20 | infer: Arc<InferenceResult>, | 20 | infer: Arc<InferenceResult>, |
21 | sink: &'a mut DiagnosticSink<'b>, | 21 | sink: &'a mut DiagnosticSink<'b>, |
22 | } | 22 | } |
23 | 23 | ||
24 | impl<'a, 'b> UnsafeValidator<'a, 'b> { | 24 | impl<'a, 'b> UnsafeValidator<'a, 'b> { |
25 | pub fn new( | 25 | pub(super) fn new( |
26 | func: FunctionId, | 26 | owner: DefWithBodyId, |
27 | infer: Arc<InferenceResult>, | 27 | infer: Arc<InferenceResult>, |
28 | sink: &'a mut DiagnosticSink<'b>, | 28 | sink: &'a mut DiagnosticSink<'b>, |
29 | ) -> UnsafeValidator<'a, 'b> { | 29 | ) -> UnsafeValidator<'a, 'b> { |
30 | UnsafeValidator { func, infer, sink } | 30 | UnsafeValidator { owner, infer, sink } |
31 | } | 31 | } |
32 | 32 | ||
33 | pub fn validate_body(&mut self, db: &dyn HirDatabase) { | 33 | pub(super) fn validate_body(&mut self, db: &dyn HirDatabase) { |
34 | let def = self.func.into(); | 34 | let def = self.owner.into(); |
35 | let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def); | 35 | let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def); |
36 | let func_data = db.function_data(self.func); | 36 | let is_unsafe = match self.owner { |
37 | if func_data.is_unsafe | 37 | DefWithBodyId::FunctionId(it) => db.function_data(it).is_unsafe, |
38 | DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_) => false, | ||
39 | }; | ||
40 | if is_unsafe | ||
38 | || unsafe_expressions | 41 | || unsafe_expressions |
39 | .iter() | 42 | .iter() |
40 | .filter(|unsafe_expr| !unsafe_expr.inside_unsafe_block) | 43 | .filter(|unsafe_expr| !unsafe_expr.inside_unsafe_block) |
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs index 2ce4f65cc..28f32a0a4 100644 --- a/crates/ra_hir_ty/src/infer.rs +++ b/crates/ra_hir_ty/src/infer.rs | |||
@@ -168,7 +168,7 @@ impl InferenceResult { | |||
168 | pub fn add_diagnostics( | 168 | pub fn add_diagnostics( |
169 | &self, | 169 | &self, |
170 | db: &dyn HirDatabase, | 170 | db: &dyn HirDatabase, |
171 | owner: FunctionId, | 171 | owner: DefWithBodyId, |
172 | sink: &mut DiagnosticSink, | 172 | sink: &mut DiagnosticSink, |
173 | ) { | 173 | ) { |
174 | self.diagnostics.iter().for_each(|it| it.add_to(db, owner, sink)) | 174 | self.diagnostics.iter().for_each(|it| it.add_to(db, owner, sink)) |
@@ -760,7 +760,7 @@ impl std::ops::BitOrAssign for Diverges { | |||
760 | } | 760 | } |
761 | 761 | ||
762 | mod diagnostics { | 762 | mod diagnostics { |
763 | use hir_def::{expr::ExprId, FunctionId}; | 763 | use hir_def::{expr::ExprId, DefWithBodyId}; |
764 | use hir_expand::diagnostics::DiagnosticSink; | 764 | use hir_expand::diagnostics::DiagnosticSink; |
765 | 765 | ||
766 | use crate::{ | 766 | use crate::{ |
@@ -778,17 +778,17 @@ mod diagnostics { | |||
778 | pub(super) fn add_to( | 778 | pub(super) fn add_to( |
779 | &self, | 779 | &self, |
780 | db: &dyn HirDatabase, | 780 | db: &dyn HirDatabase, |
781 | owner: FunctionId, | 781 | owner: DefWithBodyId, |
782 | sink: &mut DiagnosticSink, | 782 | sink: &mut DiagnosticSink, |
783 | ) { | 783 | ) { |
784 | match self { | 784 | match self { |
785 | InferenceDiagnostic::NoSuchField { expr, field } => { | 785 | InferenceDiagnostic::NoSuchField { expr, field } => { |
786 | let (_, source_map) = db.body_with_source_map(owner.into()); | 786 | let (_, source_map) = db.body_with_source_map(owner); |
787 | let field = source_map.field_syntax(*expr, *field); | 787 | let field = source_map.field_syntax(*expr, *field); |
788 | sink.push(NoSuchField { file: field.file_id, field: field.value }) | 788 | sink.push(NoSuchField { file: field.file_id, field: field.value }) |
789 | } | 789 | } |
790 | InferenceDiagnostic::BreakOutsideOfLoop { expr } => { | 790 | InferenceDiagnostic::BreakOutsideOfLoop { expr } => { |
791 | let (_, source_map) = db.body_with_source_map(owner.into()); | 791 | let (_, source_map) = db.body_with_source_map(owner); |
792 | let ptr = source_map | 792 | let ptr = source_map |
793 | .expr_syntax(*expr) | 793 | .expr_syntax(*expr) |
794 | .expect("break outside of loop in synthetic syntax"); | 794 | .expect("break outside of loop in synthetic syntax"); |
diff --git a/crates/ra_hir_ty/src/test_db.rs b/crates/ra_hir_ty/src/test_db.rs index 519f43c4e..daf2b909e 100644 --- a/crates/ra_hir_ty/src/test_db.rs +++ b/crates/ra_hir_ty/src/test_db.rs | |||
@@ -13,10 +13,7 @@ use rustc_hash::{FxHashMap, FxHashSet}; | |||
13 | use stdx::format_to; | 13 | use stdx::format_to; |
14 | use test_utils::extract_annotations; | 14 | use test_utils::extract_annotations; |
15 | 15 | ||
16 | use crate::{ | 16 | use crate::diagnostics::{validate_body, Diagnostic}; |
17 | db::HirDatabase, | ||
18 | diagnostics::{expr::ExprValidator, unsafe_check::UnsafeValidator, Diagnostic}, | ||
19 | }; | ||
20 | 17 | ||
21 | #[salsa::database( | 18 | #[salsa::database( |
22 | ra_db::SourceDatabaseExtStorage, | 19 | ra_db::SourceDatabaseExtStorage, |
@@ -118,13 +115,8 @@ impl TestDB { | |||
118 | } | 115 | } |
119 | 116 | ||
120 | for f in fns { | 117 | for f in fns { |
121 | let infer = self.infer(f.into()); | ||
122 | let mut sink = DiagnosticSink::new(&mut cb); | 118 | let mut sink = DiagnosticSink::new(&mut cb); |
123 | infer.add_diagnostics(self, f, &mut sink); | 119 | validate_body(self, f.into(), &mut sink); |
124 | let mut validator = ExprValidator::new(f, infer.clone(), &mut sink); | ||
125 | validator.validate_body(self); | ||
126 | let mut validator = UnsafeValidator::new(f, infer, &mut sink); | ||
127 | validator.validate_body(self); | ||
128 | } | 120 | } |
129 | } | 121 | } |
130 | } | 122 | } |