wowlab_tidy/languages/rust/rules/performance/
box_leak.rs1use crate::{Example, FileCtx, Violation, infra::parse, violation};
2
3#[rustfmt::skip]
4const EXAMPLES: &[Example] = &[
5 Example {
6 label: "Box::leak without comment",
7 code: "let x = Box::leak(Box::new(42));",
8 pass: false,
9 },
10 Example {
11 label: "Box::leak with SAFETY comment",
12 code: "// SAFETY: static lifetime needed for FFI\nlet x = Box::leak(Box::new(42));",
13 pass: true,
14 },
15 Example {
16 label: "Box::leak with LEAK comment",
17 code: "// LEAK: intentional for process lifetime\nlet x = Box::leak(Box::new(42));",
18 pass: true,
19 },
20 Example {
21 label: "comment line not flagged",
22 code: "// Box::leak example",
23 pass: true,
24 },
25 Example {
26 label: "normal code",
27 code: "let x = Box::new(42);",
28 pass: true,
29 },
30];
31
32crate::line_rule!(
33 box_leak,
34 "Require `SAFETY` or `LEAK` comment on `Box::leak()` calls.",
35 "Box::leak intentionally creates a memory leak. A justification comment proves it was deliberate, not accidental.",
36 High,
37);
38
39const PATTERNS: &[&str] = &["Box::leak"];
40
41fn check_box_leak(ctx: &FileCtx<'_>) -> Vec<Violation> {
42 let mut out = Vec::new();
43
44 for (i, line) in ctx.lines.iter().enumerate() {
45 let lineno = i + 1;
46 let trimmed = line.trim();
47
48 if parse::is_comment(trimmed) || parse::matches(trimmed, "/*") {
49 continue;
50 }
51
52 for pattern in PATTERNS {
53 if !trimmed.contains(pattern) {
54 continue;
55 }
56
57 let has_justification = i
58 .checked_sub(1)
59 .and_then(|previous| ctx.lines.get(previous))
60 .is_some_and(|previous| previous.contains("SAFETY") || previous.contains("LEAK"));
61
62 if !has_justification {
63 out.push(violation(
64 ctx.rel,
65 lineno,
66 format!(
67 "{pattern}() without a comment — add // SAFETY: or // LEAK: explaining why"
68 ),
69 ));
70 }
71 }
72 }
73
74 out
75}
76
77crate::tidy_test!(check_box_leak, {
78 crate::example_tests!(EXAMPLES, check_box_leak);
79});