Skip to content

Commit edb4326

Browse files
authored
Merge pull request #18609 from ChayimFriedman2/unsafe-coverage
feat: Extend reported unsafe operations
2 parents 99c9a99 + 327b8c9 commit edb4326

File tree

7 files changed

+499
-113
lines changed

7 files changed

+499
-113
lines changed

crates/hir-def/src/body.rs

Lines changed: 131 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,8 @@ impl Body {
408408
f(else_branch);
409409
}
410410
}
411-
Expr::Let { expr, .. } => {
411+
Expr::Let { expr, pat } => {
412+
self.walk_exprs_in_pat(*pat, &mut f);
412413
f(*expr);
413414
}
414415
Expr::Block { statements, tail, .. }
@@ -444,7 +445,10 @@ impl Body {
444445
}
445446
Expr::Match { expr, arms } => {
446447
f(*expr);
447-
arms.iter().map(|arm| arm.expr).for_each(f);
448+
arms.iter().for_each(|arm| {
449+
f(arm.expr);
450+
self.walk_exprs_in_pat(arm.pat, &mut f);
451+
});
448452
}
449453
Expr::Break { expr, .. }
450454
| Expr::Return { expr }
@@ -505,6 +509,131 @@ impl Body {
505509
}
506510
}
507511

512+
pub fn walk_child_exprs_without_pats(&self, expr_id: ExprId, mut f: impl FnMut(ExprId)) {
513+
let expr = &self[expr_id];
514+
match expr {
515+
Expr::Continue { .. }
516+
| Expr::Const(_)
517+
| Expr::Missing
518+
| Expr::Path(_)
519+
| Expr::OffsetOf(_)
520+
| Expr::Literal(_)
521+
| Expr::Underscore => {}
522+
Expr::InlineAsm(it) => it.operands.iter().for_each(|(_, op)| match op {
523+
AsmOperand::In { expr, .. }
524+
| AsmOperand::Out { expr: Some(expr), .. }
525+
| AsmOperand::InOut { expr, .. } => f(*expr),
526+
AsmOperand::SplitInOut { in_expr, out_expr, .. } => {
527+
f(*in_expr);
528+
if let Some(out_expr) = out_expr {
529+
f(*out_expr);
530+
}
531+
}
532+
AsmOperand::Out { expr: None, .. }
533+
| AsmOperand::Const(_)
534+
| AsmOperand::Label(_)
535+
| AsmOperand::Sym(_) => (),
536+
}),
537+
Expr::If { condition, then_branch, else_branch } => {
538+
f(*condition);
539+
f(*then_branch);
540+
if let &Some(else_branch) = else_branch {
541+
f(else_branch);
542+
}
543+
}
544+
Expr::Let { expr, .. } => {
545+
f(*expr);
546+
}
547+
Expr::Block { statements, tail, .. }
548+
| Expr::Unsafe { statements, tail, .. }
549+
| Expr::Async { statements, tail, .. } => {
550+
for stmt in statements.iter() {
551+
match stmt {
552+
Statement::Let { initializer, else_branch, .. } => {
553+
if let &Some(expr) = initializer {
554+
f(expr);
555+
}
556+
if let &Some(expr) = else_branch {
557+
f(expr);
558+
}
559+
}
560+
Statement::Expr { expr: expression, .. } => f(*expression),
561+
Statement::Item(_) => (),
562+
}
563+
}
564+
if let &Some(expr) = tail {
565+
f(expr);
566+
}
567+
}
568+
Expr::Loop { body, .. } => f(*body),
569+
Expr::Call { callee, args, .. } => {
570+
f(*callee);
571+
args.iter().copied().for_each(f);
572+
}
573+
Expr::MethodCall { receiver, args, .. } => {
574+
f(*receiver);
575+
args.iter().copied().for_each(f);
576+
}
577+
Expr::Match { expr, arms } => {
578+
f(*expr);
579+
arms.iter().map(|arm| arm.expr).for_each(f);
580+
}
581+
Expr::Break { expr, .. }
582+
| Expr::Return { expr }
583+
| Expr::Yield { expr }
584+
| Expr::Yeet { expr } => {
585+
if let &Some(expr) = expr {
586+
f(expr);
587+
}
588+
}
589+
Expr::Become { expr } => f(*expr),
590+
Expr::RecordLit { fields, spread, .. } => {
591+
for field in fields.iter() {
592+
f(field.expr);
593+
}
594+
if let &Some(expr) = spread {
595+
f(expr);
596+
}
597+
}
598+
Expr::Closure { body, .. } => {
599+
f(*body);
600+
}
601+
Expr::BinaryOp { lhs, rhs, .. } => {
602+
f(*lhs);
603+
f(*rhs);
604+
}
605+
Expr::Range { lhs, rhs, .. } => {
606+
if let &Some(lhs) = rhs {
607+
f(lhs);
608+
}
609+
if let &Some(rhs) = lhs {
610+
f(rhs);
611+
}
612+
}
613+
Expr::Index { base, index, .. } => {
614+
f(*base);
615+
f(*index);
616+
}
617+
Expr::Field { expr, .. }
618+
| Expr::Await { expr }
619+
| Expr::Cast { expr, .. }
620+
| Expr::Ref { expr, .. }
621+
| Expr::UnaryOp { expr, .. }
622+
| Expr::Box { expr } => {
623+
f(*expr);
624+
}
625+
Expr::Tuple { exprs, .. } => exprs.iter().copied().for_each(f),
626+
Expr::Array(a) => match a {
627+
Array::ElementList { elements, .. } => elements.iter().copied().for_each(f),
628+
Array::Repeat { initializer, repeat } => {
629+
f(*initializer);
630+
f(*repeat)
631+
}
632+
},
633+
&Expr::Assignment { target: _, value } => f(value),
634+
}
635+
}
636+
508637
pub fn walk_exprs_in_pat(&self, pat_id: PatId, f: &mut impl FnMut(ExprId)) {
509638
self.walk_pats(pat_id, &mut |pat| {
510639
if let Pat::Expr(expr) | Pat::ConstBlock(expr) = self[pat] {

crates/hir-ty/src/diagnostics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ pub use crate::diagnostics::{
99
expr::{
1010
record_literal_missing_fields, record_pattern_missing_fields, BodyValidationDiagnostic,
1111
},
12-
unsafe_check::{missing_unsafe, unsafe_expressions, UnsafeExpr},
12+
unsafe_check::{missing_unsafe, unsafe_expressions, InsideUnsafeBlock, UnsafetyReason},
1313
};

0 commit comments

Comments
 (0)