Skip to main content

wowlab_tidy/languages/rust/rules/performance/
box_leak.rs

1use 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});