Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/diagnostics/unsafe_check.rs')
| -rw-r--r-- | crates/hir-ty/src/diagnostics/unsafe_check.rs | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/crates/hir-ty/src/diagnostics/unsafe_check.rs b/crates/hir-ty/src/diagnostics/unsafe_check.rs index ac849b0762..d2b908839c 100644 --- a/crates/hir-ty/src/diagnostics/unsafe_check.rs +++ b/crates/hir-ty/src/diagnostics/unsafe_check.rs @@ -95,7 +95,26 @@ enum UnsafeDiagnostic { DeprecatedSafe2024 { node: ExprId, inside_unsafe_block: InsideUnsafeBlock }, } -pub fn unsafe_expressions( +pub fn unsafe_operations_for_body( + db: &dyn HirDatabase, + infer: &InferenceResult, + def: DefWithBodyId, + body: &Body, + callback: &mut dyn FnMut(ExprOrPatId), +) { + let mut visitor_callback = |diag| { + if let UnsafeDiagnostic::UnsafeOperation { node, .. } = diag { + callback(node); + } + }; + let mut visitor = UnsafeVisitor::new(db, infer, body, def, &mut visitor_callback); + visitor.walk_expr(body.body_expr); + for ¶m in &body.params { + visitor.walk_pat(param); + } +} + +pub fn unsafe_operations( db: &dyn HirDatabase, infer: &InferenceResult, def: DefWithBodyId, @@ -281,13 +300,6 @@ impl<'a> UnsafeVisitor<'a> { self.on_unsafe_op(current.into(), UnsafetyReason::RawPtrDeref); } } - Expr::Unsafe { .. } => { - let old_inside_unsafe_block = - mem::replace(&mut self.inside_unsafe_block, InsideUnsafeBlock::Yes); - self.body.walk_child_exprs_without_pats(current, |child| self.walk_expr(child)); - self.inside_unsafe_block = old_inside_unsafe_block; - return; - } &Expr::Assignment { target, value: _ } => { let old_inside_assignment = mem::replace(&mut self.inside_assignment, true); self.walk_pats_top(std::iter::once(target), current); @@ -306,6 +318,20 @@ impl<'a> UnsafeVisitor<'a> { } } } + Expr::Unsafe { statements, .. } => { + let old_inside_unsafe_block = + mem::replace(&mut self.inside_unsafe_block, InsideUnsafeBlock::Yes); + self.walk_pats_top( + statements.iter().filter_map(|statement| match statement { + &Statement::Let { pat, .. } => Some(pat), + _ => None, + }), + current, + ); + self.body.walk_child_exprs_without_pats(current, |child| self.walk_expr(child)); + self.inside_unsafe_block = old_inside_unsafe_block; + return; + } Expr::Block { statements, .. } | Expr::Async { statements, .. } => { self.walk_pats_top( statements.iter().filter_map(|statement| match statement { |