diff options
Diffstat (limited to 'crates/ra_hir_ty')
-rw-r--r-- | crates/ra_hir_ty/src/unsafe_validation.rs | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/crates/ra_hir_ty/src/unsafe_validation.rs b/crates/ra_hir_ty/src/unsafe_validation.rs index 430182803..f3ce7112a 100644 --- a/crates/ra_hir_ty/src/unsafe_validation.rs +++ b/crates/ra_hir_ty/src/unsafe_validation.rs | |||
@@ -13,16 +13,9 @@ use crate::{ | |||
13 | 13 | ||
14 | use rustc_hash::FxHashSet; | 14 | use rustc_hash::FxHashSet; |
15 | 15 | ||
16 | pub use hir_def::{ | 16 | use hir_def::{ |
17 | body::{ | 17 | body::Body, |
18 | scope::{ExprScopes, ScopeEntry, ScopeId}, | 18 | expr::{Expr, ExprId, UnaryOp}, |
19 | Body, BodySourceMap, ExprPtr, ExprSource, PatPtr, PatSource, | ||
20 | }, | ||
21 | expr::{ | ||
22 | ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Literal, LogicOp, | ||
23 | MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, UnaryOp, | ||
24 | }, | ||
25 | LocalFieldId, VariantId, | ||
26 | }; | 19 | }; |
27 | 20 | ||
28 | pub struct UnsafeValidator<'a, 'b: 'a> { | 21 | pub struct UnsafeValidator<'a, 'b: 'a> { |
@@ -119,16 +112,27 @@ pub fn unsafe_expressions( | |||
119 | } | 112 | } |
120 | } | 113 | } |
121 | 114 | ||
122 | 'unsafe_exprs: for unsafe_expr in &mut unsafe_exprs { | 115 | for unsafe_expr in &mut unsafe_exprs { |
123 | let mut child = unsafe_expr.expr; | 116 | unsafe_expr.inside_unsafe_block = |
124 | while let Some(parent) = body.parent_map.get(child) { | 117 | is_in_unsafe(&body, body.body_expr, unsafe_expr.expr, false); |
125 | if unsafe_block_exprs.contains(parent) { | ||
126 | unsafe_expr.inside_unsafe_block = true; | ||
127 | continue 'unsafe_exprs; | ||
128 | } | ||
129 | child = *parent; | ||
130 | } | ||
131 | } | 118 | } |
132 | 119 | ||
133 | unsafe_exprs | 120 | unsafe_exprs |
134 | } | 121 | } |
122 | |||
123 | fn is_in_unsafe(body: &Body, current: ExprId, needle: ExprId, within_unsafe: bool) -> bool { | ||
124 | if current == needle { | ||
125 | return within_unsafe; | ||
126 | } | ||
127 | |||
128 | let expr = &body.exprs[current]; | ||
129 | if let &Expr::Unsafe { body: child } = expr { | ||
130 | return is_in_unsafe(body, child, needle, true); | ||
131 | } | ||
132 | |||
133 | let mut found = false; | ||
134 | expr.walk_child_exprs(|child| { | ||
135 | found = found || is_in_unsafe(body, child, needle, within_unsafe); | ||
136 | }); | ||
137 | found | ||
138 | } | ||