New lint: `relative_path_in_macro_definition`

Open
#14,472 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
35/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Stale
Tech stack
rust
Domain
tooling

Research direction

The issue names no source files, tests, or entry points. Start with the Rust macro examples and the stated path categories; done means the new lint detects relative paths in declarative macros while allowing absolute paths, $crate, and keywords such as Self.

Written by the indexing model from the issue text.

Description

A-lint G-Rust-for-Linux
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)
            }
        }
    }
}
Dominant language
Rust
Stars
13.5k
Forks
2.2k
Avg merge
2d 10h
Merged PRs (30d)
32

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from rust-lang/rust-clippy

All issues in rust-lang/rust-clippy

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.