Skip to content

fix: don't produce malformed spans for macro-generated items - #17654

Open
dgollahon wants to merge 1 commit into
rust-lang:masterfrom
dgollahon:fix-redundant-pub-crate-ice-14968
Open

fix: don't produce malformed spans for macro-generated items#17654
dgollahon wants to merge 1 commit into
rust-lang:masterfrom
dgollahon:fix-redundant-pub-crate-ice-14968

Conversation

@dgollahon

@dgollahon dgollahon commented Aug 29, 2026

Copy link
Copy Markdown

Fixes #14968

When an item is generated by a macro, its ident's span can come from a
different location than the rest of the item — typically the ident is a
macro argument (so its span points at the call site) while the item's other
tokens come from the macro definition. In that case
item.span.with_hi(ident.span.hi()) combines positions from two unrelated
locations, and since Span::new silently swaps inverted bounds, the result
is a span stretching across arbitrary unrelated code. On the toolchain from
the issue report this crashed the diagnostic emitter; on current toolchains
it renders as garbage, e.g. on master:

warning: pub(crate) function inside private module
  |
 6 |       crate::macros::mac!(some_function_name);
  |  _____--------------------------------------^
  | |     |
  | |     in this macro invocation
 7 | | }
...
12 | |             pub(crate) fn $name() {}
  | |            ^---------- help: consider using: `pub`
  | |____________|

empty_line_after_outer_attr/empty_line_after_doc_comments had the same
pattern for the "the attribute applies to this item" label, reachable when
user-written attributes are passed through a local macro.

The fix only truncates the item span to the ident when the ident's span is
actually contained in it, extracted into a shared
clippy_utils::source::span_up_to_ident helper. I checked the remaining
ident-splice sites (module_style, empty_with_brackets,
no_mangle_with_rust_abi, and several expression-internal ones): they all
guard with from_expansion() checks or operate on same-node spans, so they
can't hit this.

Note on the ICE itself: the panic site from the issue's backtrace
(HumanEmitter::render_source_line) was removed when the human emitter was
replaced by the annotate-snippets renderer. I confirmed empirically (by
building pre-fix Clippy against the debug-assertions "alt" CI toolchain for
the same commit as the pinned nightly) that the ICE no longer triggers on
current rustc — the malformed span is the surviving defect and is what the
UI tests pin.

changelog: [redundant_pub_crate], [empty_line_after_outer_attr], [empty_line_after_doc_comments]: fix nonsensical spans in diagnostics for macro-generated items, which could crash the diagnostic emitter

@rustbot rustbot added the S-waiting-on-community-reviews Status: This is awaiting for positive reviews from the community before a maintainer is assigned. label Aug 29, 2026
@rustbot

rustbot commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the pull request, and welcome!

You should hear from one of our reviewers after this PR gets at least 2 reviews from the community.

Please see the contribution instructions for more information.

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Aug 29, 2026
@rustbot

This comment has been minimized.

When an item is generated by a macro, its ident's span can come from a
different location than the rest of the item — typically the ident is a
macro argument (so its span points at the call site) while the item's other
tokens come from the macro definition. In that case
`item.span.with_hi(ident.span.hi())` combines positions from two unrelated
locations, and since `Span::new` silently swaps inverted bounds, the result
is a span stretching across arbitrary unrelated code. On the toolchain from
the issue report this crashed the diagnostic emitter; on current toolchains
it renders as garbage, e.g. on master:

    warning: pub(crate) function inside private module
      |
     6 |       crate::macros::mac!(some_function_name);
      |  _____--------------------------------------^
      | |     |
      | |     in this macro invocation
     7 | | }
    ...
    12 | |             pub(crate) fn $name() {}
      | |            ^---------- help: consider using: `pub`
      | |____________|

`empty_line_after_outer_attr`/`empty_line_after_doc_comments` had the same
pattern for the "the attribute applies to this item" label, reachable when
user-written attributes are passed through a local macro.

The fix only truncates the item span to the ident when the ident's span is
actually contained in it, extracted into a shared
`clippy_utils::source::span_up_to_ident` helper. The remaining ident-splice
sites (`module_style`, `empty_with_brackets`, `no_mangle_with_rust_abi`,
and several expression-internal ones) all guard with `from_expansion()`
checks or operate on same-node spans, so they can't hit this.

Note on the ICE itself: the panic site from the issue's backtrace
(`HumanEmitter::render_source_line`) was removed when the human emitter was
replaced by the `annotate-snippets` renderer. Confirmed empirically (by
building pre-fix Clippy against the debug-assertions "alt" CI toolchain for
the same commit as the pinned nightly) that the ICE no longer triggers on
current rustc — the malformed span is the surviving defect and is what the
UI tests pin.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@dgollahon
dgollahon force-pushed the fix-redundant-pub-crate-ice-14968 branch from 014b083 to 9702f48 Compare August 29, 2026 22:13
@github-actions

Copy link
Copy Markdown

Lintcheck changes for 9702f48

Lint Added Removed Changed
clippy::redundant_pub_crate 0 5 19

This comment will be updated if you push new changes

@CommanderStorm CommanderStorm left a comment

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.

I looked hard at https://docs.rs/rustc_span/latest/src/rustc_span/lib.rs.html#356-359 but it seems that trim_end was just not implmented.
I would prefer this be added to rustc_span, but if you want to only do one PR I am fine with it

View changes since this review

@CommanderStorm

Copy link
Copy Markdown
Contributor

also given 9702f48 was generated using claude, please review https://forge.rust-lang.org/policies/llm-usage.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-community-reviews Status: This is awaiting for positive reviews from the community before a maintainer is assigned. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties

Projects

None yet

Development

Successfully merging this pull request may close these issues.

proc_macro: attempt to subtract with overflow

3 participants