Skip to content

Respect file-lines range per predicate in where clauses#6874

Open
Souradip121 wants to merge 6 commits intorust-lang:mainfrom
Souradip121:fix-file-lines-where-clause
Open

Respect file-lines range per predicate in where clauses#6874
Souradip121 wants to merge 6 commits intorust-lang:mainfrom
Souradip121:fix-file-lines-where-clause

Conversation

@Souradip121
Copy link
Copy Markdown

@Souradip121 Souradip121 commented Apr 21, 2026

Solves #6872

Summary

  • rewrite_bounds_on_where_clause (Block/RFC indent path) and the Visual-indent path in rewrite_where_clause both unconditionally rewrote every predicate, causing the entire where clause to be reformatted even when only a subset of predicate lines were selected via --file-lines
  • Fixed by checking out_of_file_lines_range! per predicate inside the itemize_list closure — predicates outside the selected range now fall back to their original source text, predicates inside are formatted normally
  • Follows the same pattern already used in src/expr.rs, src/stmt.rs, and src/visitor.rs
  • Adds tests/source/file-lines-where-clause.rs + tests/target/file-lines-where-clause.rs to cover the partial-formatting case

Test Plan

  • cargo test passes
  • New test file-lines-where-clause verifies that only the predicate on the selected line is reformatted; out-of-range predicates retain their original text
  • Existing file-lines-* tests continue to pass (no regression in full-range formatting)
  • Idempotency check passes (formatting the output a second time is a no-op)

Previously rewrite_bounds_on_where_clause and the Visual-indent path in
rewrite_where_clause reformatted every predicate unconditionally, causing
the entire where clause to change even when only one predicate's lines
were selected via --file-lines.

Now each predicate is checked against the file-lines range before
rewriting. Predicates outside the range fall back to their original
source text; predicates inside the range are formatted normally.

Fixes rust-lang#6872
@rustbot rustbot added the S-waiting-on-review Status: awaiting review from the assignee but also interested parties. label Apr 21, 2026
Comment thread src/items.rs Outdated
Comment on lines +3139 to +3145
|pred| {
if out_of_file_lines_range!(context, pred.span()) {
Ok(context.snippet(pred.span()).to_owned())
} else {
pred.rewrite_result(context, shape)
}
},
Copy link
Copy Markdown
Contributor

@ytmimi ytmimi Apr 21, 2026

Choose a reason for hiding this comment

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

Instead of doing this check here, I'm wondering if we could move this logic to the Iterator impl for ListItems. It will likely require us to pass the whole RewriteContext to itemize_list instead of just the snippet_provider, but that should be fine.

Moving this check there means that we wouldn't need to duplicateif out_of_file_lines_range! every time we use itemize_list, and it means that you'd actually fix things for other code paths that use this pattern.

View changes since the review

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Alright, made a commit, kindly check.

@ytmimi ytmimi self-assigned this Apr 21, 2026
Thread &RewriteContext through itemize_list instead of just
&SnippetProvider, then check out_of_file_lines_range! once per item
inside Iterator::next(). This covers all call sites automatically
rather than requiring per-closure handling at each call site.

Revert the per-predicate closures in rewrite_where_clause back to
simple one-liners now that the iterator handles it centrally.
@randomPoison
Copy link
Copy Markdown
Contributor

This PR does not fully address #6872. This only seems to address inline spacing within a single predicate (i.e. the spacing between the type param and the bound T: Clone), such that we can rewrite a single predicate without affecting the inline spacing of other predicates. But unselected predicates still get re-indented, and the where keyword still gets moved around even when not selected.

Comment thread tests/source/file-lines-where-clause.rs Outdated
where
T: Clone + Debug,
U: Copy,
V: Default,
Copy link
Copy Markdown
Contributor

@randomPoison randomPoison Apr 21, 2026

Choose a reason for hiding this comment

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

A minor note: The way this test is written it's a bit hard to see what exactly is changing between the source file and target file, since only a single space is changing. I'd suggest changing the input file so that the bad formatting is more obvious, such that it's easier to tell at a glance what the test covers:

fn foo<T, U, V>()
where
    T     :     Clone      +     Debug,
    U    :       Copy,
    V   :        Default,

Would then become

fn foo<T, U, V>()
where
    T: Clone + Debug,
    U    :       Copy,
    V   :        Default,

View changes since the review

@Souradip121
Copy link
Copy Markdown
Author

Thanks for the catch, just updated the test per your suggestion, the diff reads much clearer now. Also pushed a bailout so the whole where clause stays untouched when none of its lines are in the selected range, which fixes the where-keyword-moves issue for that case. The partial case (some predicates in range, others out, and the where line itself out) needs line-level source splicing and is more invasive also happy to tackle that as a follow-up, or fold it in here if you'd prefer.

Comment thread src/items.rs Outdated
return Ok(String::new());
}

if !context.config.file_lines().is_all() && out_of_file_lines_range!(context, where_span) {

This comment was marked as resolved.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Okayy, just created a commit applying it.

@randomPoison
Copy link
Copy Markdown
Contributor

The partial case (some predicates in range, others out, and the where line itself out) needs line-level source splicing and is more invasive also happy to tackle that as a follow-up, or fold it in here if you'd prefer.

I think that'd be reasonable to split out into its own PR. Now that this PR is generalized to handle all lists, I think this makes sense to land on its own first, since this will also help other issues like #6868.

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

Labels

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.

4 participants