fix: uninlined_format_args for #[clippy::format_args] macros that adapt arguments Fixes uninlined_format_args not firing for #[clippy::format_args] macros that wrap their arguments before forwarding to format_args! (e.g. wrapping x in Adapter(&x)).#16877
Open
Souradip121 wants to merge 3 commits intorust-lang:masterfrom
Open
fix: uninlined_format_args for #[clippy::format_args] macros that adapt arguments Fixes uninlined_format_args not firing for #[clippy::format_args] macros that wrap their arguments before forwarding to format_args! (e.g. wrapping x in Adapter(&x)).#16877Souradip121 wants to merge 3 commits intorust-lang:masterfrom
uninlined_format_args for #[clippy::format_args] macros that adapt arguments Fixes uninlined_format_args not firing for #[clippy::format_args] macros that wrap their arguments before forwarding to format_args! (e.g. wrapping x in Adapter(&x)).#16877Souradip121 wants to merge 3 commits intorust-lang:masterfrom
Conversation
Collaborator
|
rustbot has assigned @samueltardieu. Use Why was this reviewer chosen?The reviewer was selected based on:
|
Member
|
Out of rotation |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #16833
What was broken
The lint silently did nothing. Two separate bugs caused this:
Bug 1 —
has_span_from_proc_macrofalse positive (format_args_collector.rs)FormatArgsCollectoruseshas_span_from_proc_macroto decide whether to store aFormatArgsnode. It checks the "between" spans — gaps between the format string andeach argument — to detect proc-macro-set spans.
For adapted macros,
walk_chain(Adapter(&(x)).span, call_site_ctxt)resolves to theentire outer macro call span, which starts before the format string literal. This
makes
start.between(end)produce an inverted span. The original code passed thisinverted span to
check_source_text, which returnedfalse, causinghas_span_from_proc_macroto returntrue— wrongly treating theFormatArgsasproc-macro-generated and refusing to store it. Without storage, the late lint pass never
sees it and never fires.
Fix: Skip the
check_source_textcall when the between-span is inverted(
sp.lo() < start.hi()), treating it as valid. The guard is scoped to!args.span.from_expansion()so that macros likeconcat!(whose format string ISfrom expansion) are unaffected.
Bug 2 —
check_one_argonly handled bare path arguments (format_args.rs)The existing code required the format argument to be a bare
ExprKind::Path(e.g.x).For adapted macros,
format_args!receivesAdapter(&(x))— anExprKind::Call— sothe pattern match failed and no suggestion was produced.
Fix: Added
find_callsite_simple_path, a helper that recurses through macro-bodywrappers (
Call,AddrOf,Paren,Unary,Cast) to find the single call-sitevariable that
$argwas substituted with. ReturnsNoneif the call-site expressionis not a simple path (e.g.
x + 1), preventing false positives. The argument removalspan is computed using the call-site variable span, anchored to the end of the previous
item.
After the fix
Non-adapted macros are unaffected
Existing
#[clippy::format_args]tests (usr_println!etc.) continue to passunchanged.
changelog: [
uninlined_format_args]: Now correctly fires for#[clippy::format_args]macros that adapt their arguments (e.g. wrap them in a newtype) before forwarding toformat_args!.