aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/code_model.rs5
-rw-r--r--crates/ra_hir/src/diagnostics.rs50
2 files changed, 54 insertions, 1 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index a379b9f49..131180a63 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -36,6 +36,7 @@ use rustc_hash::FxHashSet;
36 36
37use crate::{ 37use crate::{
38 db::{DefDatabase, HirDatabase}, 38 db::{DefDatabase, HirDatabase},
39 diagnostics::UnsafeValidator,
39 has_source::HasSource, 40 has_source::HasSource,
40 CallableDef, HirDisplay, InFile, Name, 41 CallableDef, HirDisplay, InFile, Name,
41}; 42};
@@ -677,7 +678,9 @@ impl Function {
677 let _p = profile("Function::diagnostics"); 678 let _p = profile("Function::diagnostics");
678 let infer = db.infer(self.id.into()); 679 let infer = db.infer(self.id.into());
679 infer.add_diagnostics(db, self.id, sink); 680 infer.add_diagnostics(db, self.id, sink);
680 let mut validator = ExprValidator::new(self.id, infer, sink); 681 let mut validator = ExprValidator::new(self.id, infer.clone(), sink);
682 validator.validate_body(db);
683 let mut validator = UnsafeValidator::new(&self, infer, sink);
681 validator.validate_body(db); 684 validator.validate_body(db);
682 } 685 }
683} 686}
diff --git a/crates/ra_hir/src/diagnostics.rs b/crates/ra_hir/src/diagnostics.rs
index c82883d0c..562f3fe5c 100644
--- a/crates/ra_hir/src/diagnostics.rs
+++ b/crates/ra_hir/src/diagnostics.rs
@@ -2,3 +2,53 @@
2pub use hir_def::diagnostics::UnresolvedModule; 2pub use hir_def::diagnostics::UnresolvedModule;
3pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink}; 3pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink};
4pub use hir_ty::diagnostics::{MissingFields, MissingMatchArms, MissingOkInTailExpr, NoSuchField}; 4pub use hir_ty::diagnostics::{MissingFields, MissingMatchArms, MissingOkInTailExpr, NoSuchField};
5
6use std::sync::Arc;
7
8use crate::code_model::Function;
9use crate::db::HirDatabase;
10use crate::has_source::HasSource;
11use hir_ty::{
12 diagnostics::{MissingUnsafe, UnnecessaryUnsafe},
13 expr::unsafe_expressions,
14 InferenceResult,
15};
16use ra_syntax::AstPtr;
17
18pub struct UnsafeValidator<'a, 'b: 'a> {
19 func: &'a Function,
20 infer: Arc<InferenceResult>,
21 sink: &'a mut DiagnosticSink<'b>,
22}
23
24impl<'a, 'b> UnsafeValidator<'a, 'b> {
25 pub fn new(
26 func: &'a Function,
27 infer: Arc<InferenceResult>,
28 sink: &'a mut DiagnosticSink<'b>,
29 ) -> UnsafeValidator<'a, 'b> {
30 UnsafeValidator { func, infer, sink }
31 }
32
33 pub fn validate_body(&mut self, db: &dyn HirDatabase) {
34 let def = self.func.id.into();
35 let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def);
36 let func_data = db.function_data(self.func.id);
37 let unnecessary = func_data.is_unsafe && unsafe_expressions.len() == 0;
38 let missing = !func_data.is_unsafe && unsafe_expressions.len() > 0;
39 if !(unnecessary || missing) {
40 return;
41 }
42
43 let in_file = self.func.source(db);
44 let file = in_file.file_id;
45 let fn_def = AstPtr::new(&in_file.value);
46 let fn_name = func_data.name.clone().into();
47
48 if unnecessary {
49 self.sink.push(UnnecessaryUnsafe { file, fn_def, fn_name })
50 } else {
51 self.sink.push(MissingUnsafe { file, fn_def, fn_name })
52 }
53 }
54}