Skip to main content

xtask/tasks/fmt/lints/
repr_packed.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Checks that `#[repr(packed)]` is not used without `C` — it should be
5//! `#[repr(C, packed)]`.
6
7use super::Lint;
8use super::LintCtx;
9use super::Lintable;
10use toml_edit::DocumentMut;
11
12pub struct ReprPacked;
13
14impl Lint for ReprPacked {
15    fn new(_ctx: &LintCtx) -> Self {
16        ReprPacked
17    }
18
19    fn enter_workspace(&mut self, _content: &Lintable<DocumentMut>) {}
20    fn enter_crate(&mut self, _content: &Lintable<DocumentMut>) {}
21
22    fn visit_file(&mut self, content: &mut Lintable<String>) {
23        // Collect byte offsets of `repr(packed` on lines where the attribute
24        // is the sole content, so we skip occurrences in comments or strings.
25
26        let mut offsets: Vec<usize> = Vec::new();
27        let mut pos = 0;
28        for line in content.lines() {
29            let trimmed = line.trim();
30            if trimmed == "#[repr(packed)]"
31                || (trimmed.starts_with("#[repr(packed(")
32                    && trimmed.ends_with(")]")
33                    && !trimmed.contains("C"))
34            {
35                let repr_off = line.find("repr(packed").unwrap();
36                offsets.push(pos + repr_off);
37            }
38            pos += line.len() + 1; // +1 for the newline
39        }
40
41        if offsets.is_empty() {
42            return;
43        }
44
45        // Process offsets in reverse order so that replacements don't
46        // invalidate later positions.
47        for &off in offsets.iter().rev() {
48            content.fix(
49                "`#[repr(packed)]` should be `#[repr(C, packed)]`",
50                |content| {
51                    content.insert_str(off + "repr(".len(), "C, ");
52                },
53            );
54        }
55    }
56
57    fn exit_crate(&mut self, _content: &mut Lintable<DocumentMut>) {}
58    fn exit_workspace(&mut self, _content: &mut Lintable<DocumentMut>) {}
59}