Skip to content

Large fallout from semicolon_in_expressions_from_non_local_macros #162872

Open

Description

@RalfJung

The semicolon_in_expressions_from_macros lint has existed since forever; see #159218 for details. The lint was slowly ramped up over the course of more than 4 years. However, it only ever warned about macros defined in the crate they are used.

The following changes were made during the 1.99 development window:

  • The old lint was extended to also fire if crate A uses a macro from crate B that has the semicolon problem (deny-by-default, report-in-deps).
  • This caused a lot of errors so the cross-crate case was split into a separate lint, semicolon_in_expressions_from_non_local_macros (warn-by-default, report-in-deps).
  • After beta branched off, that new lint was downgraded to warn-by-default, no-report-in-deps. ([beta] make semicolon_in_expressions_from_non_local_macros not report-in-deps #162765, landed via manual rollup)

This means that in Rust 1.99, we will have a new lint semicolon_in_expressions_from_non_local_macros that also fires if crate A uses a macro from crate B that has the semicolon problem. This lint is warn-by-default and does not show up in deps. In current nightly, which will become Rust 1.100, the lint is marked as report-in-deps (while remaining warn-by-default). That is a rather quick ramp-up for a lint that is triggered widely across the ecosystem:

Additionally, the reports one gets for this lint from dependencies are quite confusing, by nature of this being about macros: if the lint triggers in crate A when using macro M, then the actual issue is in crate B that defined the macro. A user just sees "the version of nix you are using will stop compiling in the future", but what they don't know and cannot easily find out is that they actually have to update cfg_aliases to make this warning disappear.

So, given all that... maybe we should slow down a little, and not ramp up the lint for the non-local case from "nothing" in 1.98 to "report in deps" in 1.100, over a mere two releases? It is anyway rather odd that the lint is warn-by-default but also report-in-deps; if we think it is too invasive to make it deny-by-default then maybe it is too early to make it report-in-deps. I think what happened is that people didn't realize that for 4 years we only linted for the local case, and when they realized they wanted to quickly add the non-local case to not slow down the cleanup that is blocked on this FCW... but I don't think that's a good enough reason to rush semicolon_in_expressions_from_non_local_macros as much as we are currently rushing it, given the fallout this is causing.

A crater run turning both lints into hard errors has been queued, to figure out the overall effect on the ecosystem.

@rust-lang/lang so given what we now know about the fallout of semicolon_in_expressions_from_non_local_macros, how would you like to proceed?

  1. Keep it as report-in-deps for Rust 1.100,
  2. or slow down and make it not-report-in-deps for now, let it bake for a bit, and then eventually bump it to deny + report-in-deps?

If we do nothing, then in 8 weeks Rust 1.100 will be released with the first option.

Activity

  1. added
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Sep 16, 2026
  2. added
    C-discussionCategory: Discussion or questions that doesn't represent real issues.
    I-lang-nominatedNominated for discussion during a lang team meeting.
    and removed
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Sep 17, 2026
  3. added
    P-lang-drag-1Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang
    I-lang-radarItems that are on lang's radar and will need eventual work or consideration.
    P-lang-drag-0Lang team prioritization drag level 0.https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang.
    and removed
    P-lang-drag-1Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang
    on Sep 17, 2026
  4. steffahn commented on Sep 25, 2026

    @steffahn
    Member

    It is anyway rather odd that the lint is warn-by-default but also report-in-deps; if we think it is too invasive to make it deny-by-default then maybe it is too early to make it report-in-deps.

    Usually lints becoming deny-on-default before (or at least not after) being report-in-deps makes sense; it makes that we work on getting the message to the right place first; the crate that causes the error and needs to update. Whereas in a dependency, all you can do is report upstream; or (as a secondary function) it notifies dependents to make sure that they update their dependencies (and/or their lockfiles) in order to actually receive an already existing updated version.

    semicolon_in_expressions_from_non_local_macros is a bit untypical though in that it will only affect dependencies (of the crate defining the macro) even when the actual problem is (often) in the macro definition itself. So as it's not necessarily something that's fixable by the depending (and linted-against) crate directly.

    This means it's reasonable to do report-in-deps without (or before) making things deny-by-default. Adding report-in-deps then serves to increase the chance that word of the problems actually makes it upstream to all affected crates.

    IMHO, a slower ramp-up sounds like a good idea though! It leave some more time for people to resolve some of those cases where visibility only through reporting in direct users of the macro (and not also their dependents) is already suffiently noisy. It doesn't help anyone to drive more people than necessary to report such issues upstream - we all know how exhausting / pressuring that could end up being; let's not risk crate authors or maintainers could be seen as responsible for what ultimately was our oversight (for not linting against this case earlier).

    [Perhaps it would have even made sense to leave it allow-by-default for some duration, and first identify some key affected crates in the ecosystem ourselves through crater; before turning on the warning which effectively delegates the reporting responsibility for the remaining cases to the respective dependent crates.]

  5. RalfJung commented on Sep 25, 2026

    @RalfJung
    MemberAuthor

    The crater run came back with the largest number of regressions I have ever seen in a crater run: more than 45k. This dwarves even the massive fallout from #162478 by almost a factor of 2.

    I don't know what to do long-term, but short term I think we should remove the report-in-deps, and backport that to the beta that branched today.

  6. xtqqczze commented on Sep 25, 2026

    @xtqqczze
    Contributor

    Does the semicolon_in_expressions_from_non_local_macros lint work transitively? For example, if crate A depends on crate B, which uses a macro from crate C that has the semicolon problem, will the lint also fire for crate A?

  7. asquared31415 commented on Sep 25, 2026

    @asquared31415
    Contributor

    Yes, and that's one of the big problems. The lint fires when the expansion happens, and the origin of the macro might be from a crate that's not even listed in the error message. The typical example was that anyone using the nix crate would get a FCW that "nix will be rejected in future versions of rustc", when the problem was actually that cfg_aliases needed to be upgraded (and nix could in fact be left alone in this case).

  8. xtqqczze commented on Sep 25, 2026

    @xtqqczze
    Contributor

    the origin of the macro might be from a crate that's not even listed in the error message

    Is there no note like this?

       = note: this error originates in the macro `$crate::cfg_aliases` which comes from the expansion of the macro `cfg_aliases` (in Nightly builds, run with -Z macro-backtrace for more info)
  9. steffahn commented on Sep 25, 2026

    @steffahn
    Member

    If the crater fallout is extraordinarily large, maybe a last-minute beta patch into 1.100 1.99, lowering the level to allow-by-default, is still worth for consideration?

    This could allow us more time for targeted approaches to the most relevant root cause crates in the ecosystem without putting unnecessary pressure on them from already activating lints emitted to their direct users in stable Rust.

    Do we happen to have any numbers on how many crates are still going to see this warning, without report-in-deps?

  10. RalfJung commented on Sep 26, 2026

    @RalfJung
    MemberAuthor

    Is there no note like this?

    No, there is not.

    If the crater fallout is extraordinarily large, maybe a last-minute beta patch into 1.100, lowering the level to allow-by-default, is still worth for consideration?

    It is warn-by-default in 1.99. I think given that it's no-report-in-deps that's fine.

    Do we happen to have any numbers on how many crates are still going to see this warning, without report-in-deps?

    I don't know how we could get such numbers.

  11. theemathas commented on Sep 26, 2026

    @theemathas
    Contributor

    I don't know how we could get such numbers.

    Running a crater with +rustflags=-Dsemicolon_in_expressions_from_non_local_macros should do that. See https://github.com/rust-lang/crater/blob/master/docs/bot-usage.md

  12. RalfJung commented on Sep 26, 2026

    @RalfJung
    MemberAuthor

    Do we happen to have any numbers on how many crates are still going to see this warning, without report-in-deps?

    I guess we can look at the "root regressions" section of the crater report. Unfortunately the report shows very confusing numbers but I think there are 1500 regressions directly in the root crate.
    (That's for making both of the semicolon_in_expression lints into a hard error.)

    Running a crater with +rustflags=-Dsemicolon_in_expressions_from_non_local_macros should do that. See https://github.com/rust-lang/crater/blob/master/docs/bot-usage.md

    That doesn't account for allow(...) though.

  13. removed
    I-lang-nominatedNominated for discussion during a lang team meeting.
    P-lang-drag-0Lang team prioritization drag level 0.https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang.
    on Sep 30, 2026
  14. added a commit that references this issue on Oct 5, 2026
  15. added 2 commits that reference this issue on Oct 5, 2026
  16. added 2 commits that reference this issue on Oct 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-discussionCategory: Discussion or questions that doesn't represent real issues.I-lang-radarItems that are on lang's radar and will need eventual work or consideration.L-semicolon_in_expressions_from_non_local_macrosLint: semicolon_in_expressions_from_non_local_macrosT-langRelevant to the language team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions