Skip to main content

wowlab_tidy/languages/rust/rules/correctness/
static_mut.rs

1use crate::{Example, FileCtx, Violation, infra::parse, violation};
2
3#[rustfmt::skip]
4const EXAMPLES: &[Example] = &[
5    Example {
6        label: "static mut declaration",
7        code: "static mut X: i32 = 0;",
8        pass: false,
9    },
10    Example {
11        label: "static Mutex",
12        code: "static X: Mutex<i32> = Mutex::new(0);",
13        pass: true,
14    },
15    Example {
16        label: "comment with static mut",
17        code: "// static mut X: i32 = 0;",
18        pass: true,
19    },
20    Example {
21        label: "static mut in string literal",
22        code: r#"let msg = "static mut is dangerous";"#,
23        pass: true,
24    },
25];
26
27crate::line_rule!(
28    static_mut,
29    "Ban `static mut` declarations — use `AtomicT`, `Mutex`, or `OnceLock`.",
30    "static mut is unsound in multithreaded code and deprecated. Use AtomicT, Mutex, or OnceLock instead.",
31    High,
32);
33
34fn check_static_mut(ctx: &FileCtx<'_>) -> Vec<Violation> {
35    let mut out = Vec::new();
36
37    for (i, line) in ctx.lines.iter().enumerate() {
38        let lineno = i + 1;
39        let trimmed = line.trim();
40
41        if parse::is_comment(trimmed) {
42            continue;
43        }
44
45        if crate::infra::helpers::contains_outside_strings(line, "static mut ") {
46            out.push(violation(
47                ctx.rel,
48                lineno,
49                "`static mut` is UB-prone (use AtomicT, Mutex, or OnceLock)",
50            ));
51        }
52    }
53
54    out
55}
56
57crate::tidy_test!(check_static_mut, {
58    crate::example_tests!(EXAMPLES, check_static_mut);
59});