Skip to content

keyword-idents is incompatible with macros #133709

Open
@ehuss

Description

@ehuss

The keyword_idents lint has incorrect suggestions in macro_rules macros (there are potentially separate concerns for the definition versus invocation). It suggests changing a new keyword to the raw identifier, but this is a semantic change (see #49520).

LHS Definition

Consider:

// edition 2021
#![warn(keyword_idents)]
#[macro_export]
macro_rules! m {
    (gen) => {};
}

This suggests changing it to a raw identifier:

@@ -1,5 +1,5 @@
 #![warn(keyword_idents)]
 #[macro_export]
 macro_rules! m {
-    (gen) => {};
+    (r#gen) => {};
 }

However, this is a semantic change because macro_rules does not treat an equivalence between raw and normal identifiers (or keywords). Thus, another crate using this macro:

// any edition
m!(gen);

will fail with the error "no rules expected gen", or "no rules expected reserved keyword gen" in 2024.

Invocation

Perhaps more difficult to resolve is the rewrites for an invocation.

Let's say we have a crate (any edition), with something like:

// crate a, any edition
#[macro_export]
macro_rules! other_macro {
    (gen) => {};
}

and then I am trying to migrate my crate to 2024:

// edition 2021
#![warn(keyword_idents)]
a::other_macro!(gen);

This will suggest to change it to a::other_macro!(r#gen), which is incorrect because that does not match any matchers.

I say this is more difficult, because there are some situations where changing the invocation is the correct thing to do. Consider:

// crate a, any edition
#[macro_export]
macro_rules! other_macro {
    ($e:stmt) => {};
}

and trying to migrate another crate to 2024:

// edition 2021
#![warn(keyword_idents)]
a::other_macro!(let gen = 1);

this gives the correct suggestion to rewrite it to a::other_macro!(let r#gen = 1);, which would fail to compile if it wasn't changed.

Possible solutions

There are different angles to tackle this problem:

  • Changing the suggestions provided by keyword_idents.
  • Changing the behavior of macros.

The latter seems like a bigger can of worms.

For the former, some rough thoughts:

  • Don't suggest changes on the LHS of a macro_rules matcher. This is clearly a semantics change.
  • Detect the situations where changing an invocation is incorrect, and avoid those suggestions. No idea how feasible that is.

Meta

rustc 1.85.0-nightly (7442931d4 2024-11-30)
binary: rustc
commit-hash: 7442931d49b199ad0a1cc0f8ca54e327b5139b66
commit-date: 2024-11-30
host: aarch64-apple-darwin
release: 1.85.0-nightly
LLVM version: 19.1.4

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-edition-2024Area: The 2024 editionA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.A-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)A-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`C-bugCategory: This is a bug.D-editionDiagnostics: An error or lint that should account for edition differences.D-invalid-suggestionDiagnostics: A structured suggestion resulting in incorrect code.I-edition-triagedIssue: This issue has been reviewed and triaged by the Edition team.L-keyword_identsLint group: keyword_identsL-keyword_idents_2024Lint: keyword_idents_2024T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions