Skip to content

Make semicolon_in_expressions_from_macros a hard error#159218

Open
joshtriplett wants to merge 4 commits into
rust-lang:mainfrom
joshtriplett:mbe-no-semi
Open

Make semicolon_in_expressions_from_macros a hard error#159218
joshtriplett wants to merge 4 commits into
rust-lang:mainfrom
joshtriplett:mbe-no-semi

Conversation

@joshtriplett

Copy link
Copy Markdown
Member

See #79813, which has tracked the evolution of this issue:

  • We added it as an allow-by-default lint in December 2020.
  • We made it warn-by-default in July 2021.
  • We made it a future-incompat warn-in-deps in October 2022.
  • We made it deny-by-default in July 2025.

Now, finally, let it become a hard error. Remove fields and parameters only tracked in order to detect the expression context and report the lint. Macro expansion now simply includes the semicolon to expand, without attempting to skip over it, and lets that produce an error.

This will allow subsequent simplifications of macro handling. I have PRs in progress for that.


I recommend reviewing the last commit separately. The first three commits reorganize/drop some tests in preparation, to make the last commit simpler and make it easier to see the relevant test changes. In particular, the first three commits remove a couple of tests that depend specifically on the existence of the lint and don't make sense without it, move some tests that still make sense from tests/ui/lints/ to tests/ui/macros/, and switch one test (of buffered lints) to use a different buffered lint for testing.

Lang nominated for the purposes of confirming that we're ready to take this last step. The concrete change, though, is a compiler change as usual.

r? petrochenkov

…i/lint` to `tests/ui/macros`

Subsequent commits will change this lint into an error, so the tests no
longer belong under `lint`. Make the rename a separate commit to make
the subsequent changes easier to diff.

The test for the lint itself (which validates behavior when allowing the
lint) is removed entirely.
… lint for testing

issue-84195-lint-anon-const tests that we properly handle buffered
lints. However, `semicolon_in_expressions_from_macros` is going away in
favor of a hard error. So, switch to a different buffered lint,
`unused_attributes`.
…nds on `semicolon_in_expressions_from_macros`)

This regression test depends on specific quirky behavior of
`semicolon_in_expressions_from_macros` (in which it got emitted despite
an `allow`). Since that lint will become a hard error, the test would
require substantial porting, and it's not obvious if it still applies.
(Obvious alternative lints do not have this same issue of showing
despite an `allow`.)
See rust-lang#79813, which has tracked
the evolution of this issue:
- We added it as an allow-by-default lint in December 2020.
- We made it warn-by-default in July 2021.
- We made it a future-incompat warn-in-deps in October 2022.
- We made it deny-by-default in July 2025.

Now, finally, let it become a hard error. Remove fields and parameters
only tracked in order to detect the expression context and report the
lint. Macro expansion now simply includes the semicolon to expand, without
attempting to skip over it, and lets that produce an error.

This will allow subsequent simplifications of macro handling.
@joshtriplett joshtriplett added A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) T-lang Relevant to the language team T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. I-lang-nominated Nominated for discussion during a lang team meeting. L-semicolon_in_expressions_from_macros Lint: semicolon_in_expressions_from_macros labels Jul 13, 2026
@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jul 13, 2026
@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job aarch64-gnu-llvm-21-1 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
[RUSTC-TIMING] unicode_security test:false 1.068
   Compiling wasm-encoder v0.219.2
[RUSTC-TIMING] wasm_encoder test:false 2.922
   Compiling nix v0.30.1
error: macro expansion ignores `;` and any tokens following
   --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cfg_aliases-0.2.1/src/lib.rs:287:29
    |
287 |           ] $($current)* $tok);
    |                               ^
    |
   ::: /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nix-0.30.1/build.rs:4:5
    |
  4 | /     cfg_aliases! {
  5 | |         android: { target_os = "android" },
  6 | |         dragonfly: { target_os = "dragonfly" },
  7 | |         ios: { target_os = "ios" },
...   |
 27 | |         solarish: { any(illumos, solaris) },
 28 | |     }
    | |_____- caused by the macro expansion here
    |
    = note: the usage of `cfg_aliases!` is likely invalid in expression context
help: you might be missing a semicolon here
    |
323 |         $crate::cfg_aliases!(@parser_clause any [] [$($tokens)+]);
    |                                                                  +

error: macro expansion ignores `;` and any tokens following
   --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cfg_aliases-0.2.1/src/lib.rs:268:11
    |
268 |           ]);
    |             ^
    |
   ::: /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nix-0.30.1/build.rs:4:5
    |
  4 | /     cfg_aliases! {
  5 | |         android: { target_os = "android" },
  6 | |         dragonfly: { target_os = "dragonfly" },
  7 | |         ios: { target_os = "ios" },
...   |
 27 | |         solarish: { any(illumos, solaris) },
 28 | |     }
    | |_____- caused by the macro expansion here
    |
    = note: the usage of `cfg_aliases!` is likely invalid in expression context

error: macro expansion ignores `;` and any tokens following
   --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cfg_aliases-0.2.1/src/lib.rs:287:29
    |
287 |           ] $($current)* $tok);
    |                               ^
    |
   ::: /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nix-0.30.1/build.rs:4:5
    |
  4 | /     cfg_aliases! {
  5 | |         android: { target_os = "android" },
  6 | |         dragonfly: { target_os = "dragonfly" },
  7 | |         ios: { target_os = "ios" },
...   |
 27 | |         solarish: { any(illumos, solaris) },
 28 | |     }
    | |_____- caused by the macro expansion here
    |
    = note: the usage of `cfg_aliases!` is likely invalid in expression context

error: macro expansion ignores `;` and any tokens following
   --> /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cfg_aliases-0.2.1/src/lib.rs:305:10
    |
305 |           );
    |            ^
    |
   ::: /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nix-0.30.1/build.rs:4:5
    |
  4 | /     cfg_aliases! {
  5 | |         android: { target_os = "android" },
  6 | |         dragonfly: { target_os = "dragonfly" },
  7 | |         ios: { target_os = "ios" },
...   |
 27 | |         solarish: { any(illumos, solaris) },
 28 | |     }
    | |_____- caused by the macro expansion here
    |
    = note: the usage of `cfg_aliases!` is likely invalid in expression context

@@ -0,0 +1,14 @@
// Ensure that trailing semicolons cause errors

@cyrgani cyrgani Jul 13, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test still has warn- in the name

View changes since the review

@joshtriplett

Copy link
Copy Markdown
Member Author

AFAICT, the issue in the combination of nix and cfg_aliases here has not previously been caught by the FCW, because we always filtered out invocations of non-local macros. I'm working on fixing that now.

@joshtriplett

Copy link
Copy Markdown
Member Author

I've submitted a separate PR to make the lint apply to non-local macros like the one in cfg_aliases as used in nix. Note that the test in cfg_aliases that would otherwise have caught this also suppresses the lint, because integration tests are separate crates.

#159222

@petrochenkov

Copy link
Copy Markdown
Contributor

Blocked on #159222.
@rustbot blocked

@rustbot rustbot added S-blocked Status: Blocked on something else such as an RFC or other implementation work. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 13, 2026
@joshtriplett

Copy link
Copy Markdown
Member Author

And, likely, blocked on seeing how widespread the issue with non-local macros is.

@traviscross traviscross added I-lang-radar Items that are on lang's radar and will need eventual work or consideration. P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang and removed I-lang-nominated Nominated for discussion during a lang team meeting. P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang labels Jul 14, 2026
@rust-bors

rust-bors Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

☔ The latest upstream changes (presumably #159336) made this pull request unmergeable. Please resolve the merge conflicts by rebasing.

@mati865

mati865 commented Jul 16, 2026

Copy link
Copy Markdown
Member

Do we track non-local macros fallout somewhere? There are popular crates like katharostech/cfg_aliases#15 (over 100M downloads last 90 days) which is used by wgpu, nix, and so on.

ojeda pushed a commit to Rust-for-Linux/linux that referenced this pull request Jul 16, 2026
These macros are used like expressions, so they should not emit a
semicolon. This is being turned into a hard error in a future release of
Rust.

    error: trailing semicolon in macro used in expression position
      --> drivers/gpu/nova-core/firmware/fsp.rs:79:34
       |
    79 |                 .inspect_err(|_| dev_err!(dev, "FMC firmware missing '{}' section\n", name))
       |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
       |
       = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
       = note: for more information, see issue #79813 <rust-lang/rust#79813>
       = note: this error originates in the macro `dev_err` (in Nightly builds, run with -Z macro-backtrace for more info)

[ I was doubly surprised since upstream made it a deny-by-default lint
  a year ago for Rust 1.91.0, and yet we didn't see it; plus I hadn't
  seen this in my CI even yesterday.

  It turns out this just landed into today's nightly (nightly-2026-07-16,
  using upstream commit d0babd8b6):

    Link: rust-lang/rust#159222

  which says:

    "The `semicolon_in_expressions_from_macros` lint previously
     suppressed warnings about non-local macros. This masks
     a lint that will subsequently become a hard error."

  So that explains it. And this is the PR that will make it a hard error
  at some point in the future:

    Link: rust-lang/rust#159218

  Thus starting with Rust 1.99.0 (expected 2026-10-01), we will be
  seeing the deny-by-default lint above, so clean it up already.

    - Miguel ]

Cc: stable@vger.kernel.org # Needed in 6.18.y and later.
Link: rust-lang/rust#79813
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Link: rust-lang/rust#159218
Link: rust-lang/rust#159222
Link: https://patch.msgid.link/20260716-device-trail-semicolon-v1-1-f48e9dcfae15@google.com
[ Fixed typo. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
ojeda pushed a commit to Rust-for-Linux/linux that referenced this pull request Jul 16, 2026
These macros are used like expressions, so they should not emit a
semicolon. This is being turned into a hard error in a future release of
Rust.

    error: trailing semicolon in macro used in expression position
      --> drivers/gpu/nova-core/firmware/fsp.rs:79:34
       |
    79 |                 .inspect_err(|_| dev_err!(dev, "FMC firmware missing '{}' section\n", name))
       |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
       |
       = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
       = note: for more information, see issue #79813 <rust-lang/rust#79813>
       = note: this error originates in the macro `dev_err` (in Nightly builds, run with -Z macro-backtrace for more info)

[ I was doubly surprised since upstream made it a deny-by-default lint
  a year ago for Rust 1.91.0, and yet we didn't see it; plus I hadn't
  seen this in my CI even yesterday.

  It turns out this just landed into today's nightly (nightly-2026-07-16,
  using upstream commit d0babd8b6):

    Link: rust-lang/rust#159222

  which says:

    "The `semicolon_in_expressions_from_macros` lint previously
     suppressed warnings about non-local macros. This masks
     a lint that will subsequently become a hard error."

  So that explains it. And this is the PR that will make it a hard error
  at some point in the future:

    Link: rust-lang/rust#159218

  Thus starting with Rust 1.99.0 (expected 2026-10-01), we will be
  seeing the deny-by-default lint above, so clean it up already.

    - Miguel ]

Cc: stable@vger.kernel.org # Needed in 6.18.y and later.
Link: rust-lang/rust#79813
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Acked-by: Danilo Krummrich <dakr@kernel.org>
Link: rust-lang/rust#159218
Link: rust-lang/rust#159222
Link: https://patch.msgid.link/20260716-device-trail-semicolon-v1-1-f48e9dcfae15@google.com
[ Fixed typo. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) I-lang-radar Items that are on lang's radar and will need eventual work or consideration. L-semicolon_in_expressions_from_macros Lint: semicolon_in_expressions_from_macros S-blocked Status: Blocked on something else such as an RFC or other implementation work. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants