Skip to content

fix(fmt): break chain after overlong named call argument#15825

Open
decofe wants to merge 5 commits into
foundry-rs:masterfrom
decofe:centaur/break-chain-after-multiline-argument-1784539000
Open

fix(fmt): break chain after overlong named call argument#15825
decofe wants to merge 5 commits into
foundry-rs:masterfrom
decofe:centaur/break-chain-after-multiline-argument-1784539000

Conversation

@decofe

@decofe decofe commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

When a call-chain link takes an overlong named-argument call as a positional argument, place the following chain link on its own line.

The break is limited to arguments whose canonical formatted width exceeds the configured line length; a short nested named call remains inline. This avoids the unconditional hardbreak() behavior previously included in #15824.

Checks:

  • cargo +nightly fmt --all -- --check
  • git diff --check

Prompted by: @DaniPopes

DaniPopes
DaniPopes previously approved these changes Jul 20, 2026
Comment thread crates/fmt/src/state/sol.rs Outdated
Comment thread crates/fmt/src/state/sol.rs Outdated
@decofe
decofe force-pushed the centaur/break-chain-after-multiline-argument-1784539000 branch from 7aedf4d to aa6a82f Compare July 20, 2026 15:29
…nt-1784539000

# Conflicts:
#	crates/fmt/src/state/sol.rs
let ast::ExprKind::Call(callee, args) = &expr.kind else { return None };
let ast::CallArgsKind::Named(args) = &args.kind else { return None };
let args_size = args.iter().try_fold(0usize, |size, arg| {
Some(size + arg.name.as_str().len() + 2 + self.estimate_call_chain_size(arg.value)?)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

At line_length = 120, overlong named calls with boolean or arithmetic values leave the following chain link attached as ).update(), while calls with the same callee and named-argument names but identifier values place .update() on a new line. estimate_call_chain_size returns None for boolean literals and binary expressions, so estimate_named_call_size cannot detect that these calls are overlong. Could these value kinds participate in the width check as well?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 9bf59ea: boolean literals and binary expressions now participate in the flat-width estimate, with regression cases for both argument value kinds.

innerFactory().anExtremelyLongMethodNameThatForcesTheNestedCalleeToWrap({
firstExtremelyLongArgumentName: true
})
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This snapshot currently fails: the formatter emits ).update();. This nested call is only 111 characters, so it does not trigger the > 120 rule.

self.estimate_call_chain_size(lhs)?
+ op.to_string().len()
+ self.estimate_call_chain_size(rhs)?
+ 2,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This always counts two operator spaces, but pow_no_space = true emits ** without spaces.

+ args_size
+ args.len().saturating_sub(1) * 2
+ 4,
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should we include configured brace spacing in the estimate?

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

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

4 participants