empty_struct_with_brackets: do not lint macro code

Do not attempt to fetch a snippet from expansion. Without this change,
the inside of macros could[*] be shown as the source of the problem.

[*] Due to the way the source code is processed and reparsed in this
macro, the declarative macro has to be located outside the current
source file for the bug to appear. Otherwise, the macro call itself
will be (mis)identified as a potential `struct` field definition and the
lint will not trigger.
This commit is contained in:
Samuel Tardieu 2025-04-15 23:51:22 +02:00
parent 9663da39d2
commit 4de5b2757d
3 changed files with 17 additions and 0 deletions

View file

@ -75,6 +75,7 @@ declare_lint_pass!(EmptyWithBrackets => [EMPTY_STRUCTS_WITH_BRACKETS, EMPTY_ENUM
impl EarlyLintPass for EmptyWithBrackets {
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
if let ItemKind::Struct(ident, var_data, _) = &item.kind
&& !item.span.from_expansion()
&& has_brackets(var_data)
&& let span_after_ident = item.span.with_lo(ident.span.hi())
&& has_no_fields(cx, var_data, span_after_ident)

View file

@ -23,4 +23,12 @@ struct MyTupleStruct(usize, String); // should not trigger lint
struct MySingleTupleStruct(usize); // should not trigger lint
struct MyUnitLikeStruct; // should not trigger lint
macro_rules! empty_struct {
($s:ident) => {
struct $s {}
};
}
empty_struct!(FromMacro);
fn main() {}

View file

@ -23,4 +23,12 @@ struct MyTupleStruct(usize, String); // should not trigger lint
struct MySingleTupleStruct(usize); // should not trigger lint
struct MyUnitLikeStruct; // should not trigger lint
macro_rules! empty_struct {
($s:ident) => {
struct $s {}
};
}
empty_struct!(FromMacro);
fn main() {}