Skip to content

Indentation of asssignment comments between lhs and rhs #5501

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

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

davidBar-On
Copy link
Contributor

Backport of suggested R2 changes for handling indentation of comments between assignment rhs and lhs, taken from different R2 PRs/commits. Not all changes were merged into R2, so this is why I didn't add "Backport" to the title.

Test cases are backport of PR #4734 test cases (which are enhancement of PR #4661 test cases).

The PR is based on:

src/comment.rs Outdated
/// that end on that line.
fn is_first_comment_ends_on_first_line(s: &str) -> bool {
if s.starts_with("/*") {
s.lines().next().map_or(false, |l| l.contains("*/"))
Copy link
Contributor

Choose a reason for hiding this comment

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

should we use ends_with instead of contains?

Suggested change
s.lines().next().map_or(false, |l| l.contains("*/"))
s.lines().next().map_or(false, |l| l.ends_with("*/"))

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed (although I am not sure whether the comment was deleted).
The main benefit of the change is that line that ends with /* comment 1*/ /* comment 2 is now properly handled. Therefore I also changed the function name and its description.

While evaluating the suggested change I found two issues that are worth noting:

  1. The following code is not handled properly and therefore is not formatted:
var= /* Block comment 1*/ // Line comment 2
value;

Fixing this is quite complex. Since it is not expected to be used much in practice, I assume that for this PR it is o.k. not to handle this case, but I did add FIXME comment for it.

  1. the following code (now added to the test cases):
var = /* Block comment */
value;

Is formatted into one line:

var = /* Block comment */ value;

However:

var = /* Block comment single line 1 */ 
/* Block comment single line 2*/ value;

is formatted as:

var = /* Block comment single line 1 */ 
    /* Block comment single line 2*/
    value;

I believe this is o.k., but I note that in case the formatted value in the first example should be in the next line.

src/comment.rs Outdated
@@ -225,7 +237,13 @@ pub(crate) fn combine_strs_with_missing_comments(
Cow::from("")
} else {
let one_line_width = last_line_width(prev_str) + first_line_width(&missing_comment) + 1;
if prefer_same_line && one_line_width <= shape.width {
// First comment of a comments block can be in same line if ends in the first line
// (and meets other conditions)
Copy link
Contributor

Choose a reason for hiding this comment

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

can we enumerate what the other conditions are in the comment

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed - removed the "(and meets other conditions)" as it was redundant. Adding the additional details could just be confusing as the "other conditions" are clear from the code.

src/items.rs Outdated
Comment on lines 116 to 121
let base_span = if let Some(ref ty) = self.ty {
mk_sp(ty.span.hi(), self.span.hi())
} else {
mk_sp(self.pat.span.hi(), self.span.hi())
};

let offset = context.snippet(base_span).find_uncommented("=")?;
let base_span_lo = base_span.lo();

let assign_lo = base_span_lo + BytePos(offset as u32);
let comment_start_pos = if let Some(ref ty) = self.ty {
ty.span.hi()
} else {
self.pat.span.hi()
};
let comment_before_assign = context.snippet(mk_sp(comment_start_pos, assign_lo)).trim();

let assign_hi = base_span_lo + BytePos((offset + 1) as u32);
let rhs_span_lo = init.span.lo();
let comment_end_pos = if init.attrs.is_empty() {
rhs_span_lo
} else {
let attr_span_lo = init.attrs.first().unwrap().span.lo();
// for the case using block
// ex. let x = { #![my_attr]do_something(); }
if rhs_span_lo < attr_span_lo {
rhs_span_lo
} else {
attr_span_lo
}
};

if !comment_before_assign.is_empty() {
let new_indent_str = &pat_shape
.block_indent(0)
.to_string_with_newline(context.config);
result = format!("{}{}{}", comment_before_assign, new_indent_str, result);
}

Copy link
Contributor

@ytmimi ytmimi Oct 20, 2022

Choose a reason for hiding this comment

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

Took some time to look into this code. It seems like a lot of what's going on here is to recover comments before the =, e.g. let pat: ty /*comment*/ = or let pat /*comment*/ =. However, this PR and all the test cases you've outlined below only test for comments that come after the = e.g. let pat: ty = /*comment*/ expr.

For that reason I think we should only worry about the post = comments in this PR.

I also propose renaming init to expr since I think it's a little clearer that it's an ast::Expr node, and using init() instead of init_else_opt() since we don't use the _else and currently don't support ast::LocalKind::InitElse(..) variants.

if let Some(expr) = self.kind.init() {
    // Adjust the span after the `pat` and `ty` before searching for the `=`
    let base_span = if let Some(ref ty) = self.ty {
        mk_sp(ty.span.hi(), self.span.hi())
    } else {
        mk_sp(self.pat.span.hi(), self.span.hi())
    };

    let comment_lo = context.snippet_provider.span_after(base_span, "=");
    let comment_span = mk_sp(comment_lo, expr.span.lo());

    let nested_shape = shape.sub_width(1)?;
    result = rewrite_assign_rhs_with_comments(
        context,
        result,
        expr,
        nested_shape,
        &RhsAssignKind::Expr(&expr.kind, expr.span),
        RhsTactics::Default,
        comment_span,
        true,
    )?;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

... a lot of what's going on here is to recover comments before the =

I somehow missed that when I copied the R2 commit changes ☹️. I also checked now R2 and didn't find any test to the assign pre = comments. I therefore assume that maybe that commit was tested properly.

Changed the code per suggestion.

Copy link
Contributor

@ytmimi ytmimi left a comment

Choose a reason for hiding this comment

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

Thanks again for applying all the feedback, and for helping to backport those PRs! I think we're good to go here!

@calebcartwright
Copy link
Member

I haven't had a chance to review this in detail, but from a cursory glance through the discussion and test cases my inclination is that this probably is the direction we want to go in long term.

However, it's got too big a risk of having a high blast radius for me to want to release it in the immediate future. I'd like to see this tested against some larger codebases, both to test/confirm that hypothesis/concern and see how it shakes out against a broader set of code.

Ultimately I think we'd need to version gate this no matter what, especially given the increased rigor around formatting stability given the pivot to style guide editions as the evolution mechanism

@davidBar-On davidBar-On force-pushed the issues-4661-4734-part5480-fromf897e25-Indentation-of-assignment-comments-between-lhs-and-rhs branch from c0c3b3e to d1da537 Compare February 7, 2023 14:45
@davidBar-On
Copy link
Contributor Author

Ultimately I think we'd need to version gate this no matter what ...

Added version gating.
Also rebased and consolidated all commits into one commit.

@ytmimi
Copy link
Contributor

ytmimi commented Feb 23, 2023

@davidBar-On thanks for making the requested changes. when you have a chance can you rebase your feature branch on master

@davidBar-On davidBar-On force-pushed the issues-4661-4734-part5480-fromf897e25-Indentation-of-assignment-comments-between-lhs-and-rhs branch from 1aa6ae0 to 81849b9 Compare February 23, 2023 19:37
@davidBar-On
Copy link
Contributor Author

... can you rebase your feature branch on master

Rebase done.

@ytmimi
Copy link
Contributor

ytmimi commented Feb 23, 2023

@calebcartwright I just ran the Diff Check Job, and with the version gate these changes don't produce any changes 👍🏼

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

Successfully merging this pull request may close these issues.

3 participants