-
Notifications
You must be signed in to change notification settings - Fork 893
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixed first comment and last comment not reordering issue #4504
base: rustfmt-2.0.0-rc.2
Are you sure you want to change the base?
Conversation
Thanks @whizsid! Note CI is failing and we're blocked on rust-lang/rust#78549 |
Blocking issues should be resolved. When you get a chance can you rebase on master to grab the latest and get CI passing? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks so much @whizsid! Minor change requested and a few nits/cleanup suggestions but looking pretty good!
src/formatting/lists.rs
Outdated
if !first | ||
&& (!inner_item.is_empty() | ||
|| item.post_comment.is_some() | ||
|| item.pre_comment.is_some()) | ||
&& !result.is_empty() => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This guard is starting to get pretty gnarly. Could you refactor it a bit to improve readability? We don't have any other subsequent Vertical
arms, so I suppose some of these checks could be moved into the body (since it's a noop if conditions aren't met).
For example i think to keep this in the guard we'd want to potentially shift this to some locals like
let item_has_comments = item.post_comment.is_some() || item.pre_comment.is_some();
// or
let non_empty_or_comments = !inner_item.is_empty() || item.post_comment.is_some() || item.pre_comment.is_some();
Otherwise I think it'd probably be much more readable to reduce the guard conditions and use these checks in the body to determine whether to push.
Also could we just do a single result.push(newline_str)
now since that's declared above (vs. result.push('\n'); result.push(indent_str);
)
if !inner_item.is_empty() | ||
&& (!formatting.align_comments | ||
|| (last | ||
&& item_max_width.is_some() | ||
&& !separate | ||
&& !formatting.separator.is_empty())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this one was already pretty busy but the extra condition and subsequent indentation is a bit of an eye sore. I guess it'd be okay but I also wouldn't mind seeing some minor refactoring of this existing code too
src/formatting/lists.rs
Outdated
self.inner.peek().is_none(), | ||
); | ||
let comment_end = | ||
if next_item.is_none() && last_line_contains_single_line_comment(post_snippet) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what condition is the comment check for? a small example snippet would be helpful, my mental runtime is failing me 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@calebcartwright The trailing comment of last item is not capturing for the item list. So I put this condition to take the trailing comment if it in the same line.
Without this condition:-
use c; // cpost
use b; // bpost
use a; // Trailing comment of last item
formatting to
use a;
use b; // bpost
use c; // cpost // Trailing comment of last item
src/formatting/lists.rs
Outdated
@@ -397,7 +405,9 @@ where | |||
item_max_width = None; | |||
} | |||
|
|||
if separate && sep_place.is_front() && !first { | |||
if inner_item.is_empty() && item.pre_comment.is_some() && item.post_comment.is_some() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is okay on its own, though along the same lines as the above comment I think declaring a local like item_has_comments
and reusing could simplify some of these conditionals
src/formatting/syntux/session.rs
Outdated
pub(crate) fn line_bounds(&self, pos: BytePos) -> (BytePos, BytePos) { | ||
let line = self.parse_sess.source_map().lookup_line(pos).ok(); | ||
|
||
match line { | ||
Some(line_info) => line_info.sf.line_bounds(line_info.line), | ||
None => (BytePos::from_usize(0), BytePos::from_usize(0)), | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm, I don't think we'll want to silently map a source map lookup error to hi/lo 0
like this. It doesn't really seem a likely condition but I have a nagging suspicion it could eventually be hit which would cause some weird formatting behavior.
Probably best to set the return type to an option containing tuple, and then call explicitly unwrap from the caller to panic and fail loudly in that hypothetical case
tests/source/issue-4027.rs
Outdated
@@ -0,0 +1,30 @@ | |||
mod a; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Love the thoroughness of the tests ❤️ Would you mind either:
- Creating a new file like
reorder_imports_comments.rs
with separated blocks (with their own comment headers) and the exact snippets from Rustfmt puts single-line comment after wrong import when reordering imports #4027 and Comments on use statements incorrectly rearranged when use statements are rearranged #3720, and then any additional scenarios can go below - Creating separate files for those two issues with the exact snippets provided, and then any additional scenarios can go in new files
It's really helpful for long term maintenance to structure the tests in such a way that issue-specific fixes/tests can be tied back directly
@calebcartwright I adjusted my PR. can you review again? |
Thanks for the updates! This PR has been sitting out here for a while though, would you please rebase on |
src/formatting/lists.rs
Outdated
@@ -482,19 +481,88 @@ where | |||
let width = formatting.shape.width.checked_sub(overhead).unwrap_or(1); | |||
let offset = formatting.shape.indent + overhead; | |||
|
|||
let comment_shape = Shape::legacy(width, offset); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@calebcartwright I rebased with the master branch at the earlier commit. Accidentally I worked in the same commit that resolving the conflicts. L485-L565 lines from the last conflicted commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cheers. That's not too surprising given the age, though I'll need to squash anyway give the merge commit.
I should finally have a bit of bandwidth in the next day or two to get back to the PR queue so will hopefully be able to review soon.
For future reference/PRs though it'd be helpful if to just do a clean rebase of your topic branch on the upstream branch from this repo and avoid merge commits 👍 Thanks again for all your work!
While there's a few nits I do think the approach seems reasonable, and the resulting formatting is certainly better than what it exists today (some of these snippets get horribly butchered today). I'd like to add a couple more test cases before merging though, just to be extra cautious. Could you add a couple snippets to cover the following:
After those tests are added, should be good to merge |
Fixes #4027 .