Skip to content

New lint: relative_path_in_macro_definition #14472

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
y86-dev opened this issue Mar 25, 2025 · 1 comment
Open

New lint: relative_path_in_macro_definition #14472

y86-dev opened this issue Mar 25, 2025 · 1 comment
Labels
A-lint Area: New lints

Comments

@y86-dev
Copy link

y86-dev commented Mar 25, 2025

What it does

Check for relative paths (such as core::ops::BitOr) being used in macros.

When writing declarative macros, one should always refer to items using their absolute path (paths starting with :: or using $crate or be keywords such as Self). That is because users might declare a module with the same name as the first component of the path and thus change the meaning of the macro.

Advantage

This change prevents macros from changing their meaning depending on the context:

macro_rules! derive_bit_or {
   ($t:ident) => {
        impl core::ops::BitOr for $t {
            type Output = Self;
            fn bitor(self, rhs: Self) -> Self {
                Self(self.0 | rhs.0)
            }
        }
    }
}

mod bar {
    struct Bar(u32);
    derive_bit_or!(Bar);
    mod core {}
}

This code fails to compile, because the path core::ops::BitOr is relative and thus the custom core module defined in mod bar is used instead of the core crate.

Drawbacks

Increase verbosity and thus decrease readability of declarative macros.

Example

macro_rules! derive_bit_or {
   ($t:ident) => {
        impl core::ops::BitOr for $t {
            type Output = Self;
            fn bitor(self, rhs: Self) -> Self {
                Self(self.0 | rhs.0)
            }
        }
    }
}

Could be written as:

macro_rules! derive_bit_or {
   ($t:ident) => {
        impl ::core::ops::BitOr for $t {
            type Output = Self;
            fn bitor(self, rhs: Self) -> Self {
                Self(self.0 | rhs.0)
            }
        }
    }
}
@y86-dev y86-dev added the A-lint Area: New lints label Mar 25, 2025
@y86-dev y86-dev changed the title New lint: relative_path_in_macro New lint: relative_path_in_macro_definition Mar 25, 2025
@KunWuChan
Copy link

I'll try to work on this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lint Area: New lints
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants