diff options
author | Paul Daniel Faria <[email protected]> | 2020-05-28 14:30:19 +0100 |
---|---|---|
committer | Paul Daniel Faria <[email protected]> | 2020-06-27 15:13:14 +0100 |
commit | f678e0d837e472dc2f1421f89f794d33f3ade55c (patch) | |
tree | 0b8501bce63bc5b340f67fe770dbbcb41ecee2e4 /crates/ra_hir_ty/src/unsafe_validation.rs | |
parent | 6c1682396c9894da07af74b43c2443e9bde89be4 (diff) |
Add HighlightTag::Operator, use it for unsafe deref. Move unsafe validation to its own file
Diffstat (limited to 'crates/ra_hir_ty/src/unsafe_validation.rs')
-rw-r--r-- | crates/ra_hir_ty/src/unsafe_validation.rs | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/crates/ra_hir_ty/src/unsafe_validation.rs b/crates/ra_hir_ty/src/unsafe_validation.rs new file mode 100644 index 000000000..55dbe23fa --- /dev/null +++ b/crates/ra_hir_ty/src/unsafe_validation.rs | |||
@@ -0,0 +1,63 @@ | |||
1 | //! Provides validations for unsafe code. Currently checks if unsafe functions are missing | ||
2 | //! unsafe blocks. | ||
3 | |||
4 | use std::sync::Arc; | ||
5 | |||
6 | use hir_def::FunctionId; | ||
7 | use hir_expand::diagnostics::DiagnosticSink; | ||
8 | |||
9 | use crate::{ | ||
10 | db::HirDatabase, diagnostics::MissingUnsafe, expr::unsafe_expressions, InferenceResult, | ||
11 | }; | ||
12 | |||
13 | pub use hir_def::{ | ||
14 | body::{ | ||
15 | scope::{ExprScopes, ScopeEntry, ScopeId}, | ||
16 | Body, BodySourceMap, ExprPtr, ExprSource, PatPtr, PatSource, | ||
17 | }, | ||
18 | expr::{ | ||
19 | ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Literal, LogicOp, | ||
20 | MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, UnaryOp, | ||
21 | }, | ||
22 | LocalFieldId, VariantId, | ||
23 | }; | ||
24 | |||
25 | pub struct UnsafeValidator<'a, 'b: 'a> { | ||
26 | func: FunctionId, | ||
27 | infer: Arc<InferenceResult>, | ||
28 | sink: &'a mut DiagnosticSink<'b>, | ||
29 | } | ||
30 | |||
31 | impl<'a, 'b> UnsafeValidator<'a, 'b> { | ||
32 | pub fn new( | ||
33 | func: FunctionId, | ||
34 | infer: Arc<InferenceResult>, | ||
35 | sink: &'a mut DiagnosticSink<'b>, | ||
36 | ) -> UnsafeValidator<'a, 'b> { | ||
37 | UnsafeValidator { func, infer, sink } | ||
38 | } | ||
39 | |||
40 | pub fn validate_body(&mut self, db: &dyn HirDatabase) { | ||
41 | let def = self.func.into(); | ||
42 | let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def); | ||
43 | let func_data = db.function_data(self.func); | ||
44 | if func_data.is_unsafe | ||
45 | || unsafe_expressions | ||
46 | .iter() | ||
47 | .filter(|unsafe_expr| !unsafe_expr.inside_unsafe_block) | ||
48 | .count() | ||
49 | == 0 | ||
50 | { | ||
51 | return; | ||
52 | } | ||
53 | |||
54 | let (_, body_source) = db.body_with_source_map(def); | ||
55 | for unsafe_expr in unsafe_expressions { | ||
56 | if !unsafe_expr.inside_unsafe_block { | ||
57 | if let Ok(in_file) = body_source.as_ref().expr_syntax(unsafe_expr.expr) { | ||
58 | self.sink.push(MissingUnsafe { file: in_file.file_id, expr: in_file.value }) | ||
59 | } | ||
60 | } | ||
61 | } | ||
62 | } | ||
63 | } | ||