Prevent duplicating comments and tokens when rewriting trait headers#6834
Prevent duplicating comments and tokens when rewriting trait headers#6834ytmimi wants to merge 12 commits intorust-lang:mainfrom
Conversation
src/header.rs
Outdated
| Self::new("", DUMMY_SP) | ||
| } | ||
|
|
||
| /// Find the `keyword` for the header within the give `span` |
There was a problem hiding this comment.
I'm a bit confused by this doc comment: is this function finding a keyword, or setting/creating one? (extra context: I'm not too familiar with how Spans work, so I may just be completely misunderstanding)
There was a problem hiding this comment.
A span refers to a byte range in the source code, and each AST node has a span that denotes where it begins and ends. So we're actually searching for the keyword within the span and finding out what it's sub-span is.
There was a problem hiding this comment.
With that in mind, do you have any suggestions to make that clearer?
There was a problem hiding this comment.
A span refers to a byte range in the source code, and each AST node has a span that denotes where it begins and ends. So we're actually searching for the keyword within the span and finding out what it's sub-span is.
Thanks! I only just now realised span was added as part of this changeset 🤦
With that in mind, do you have any suggestions to make that clearer?
Maybe the method could be span_at or span_on following the pattern of span_before/span_after?
There was a problem hiding this comment.
span_at Sounds good to me. I'll make that update.
There was a problem hiding this comment.
I think the entire set of method names is not so great. I would support the following set of naming:
subspan- currently named asspansubspan_from- currently named asspan_aftersubspan_until- currently named asspan_before
Appreciate other options as well!
There was a problem hiding this comment.
on second glance, after seems better than from, since from appears to include the given needle. Hmm I will have to think more on this.
There was a problem hiding this comment.
@fee1-dead i agree. I think renaming those methods would be ideal, though I'm not sure that should happen in this PR. I'd say span_before and span_after should probably be renamed to pos_before and pos_after since they return BytePos objects instead of Spans
There was a problem hiding this comment.
I can open up a follow up PR with any renames based on what we decide to move forward with
There was a problem hiding this comment.
renamed span -> subspan
|
I think comments between the literal Because that second comment is now in a gap not covered by this change:
|
src/utils.rs
Outdated
| // FIXME(ytmimi) might want to get rid of `format_auto` since we now have `HeaderPart::auto` | ||
| #[allow(unused)] |
There was a problem hiding this comment.
I would encourage you to remove this in this PR :) of course it will still be stored in git history, but cleanup would be nice!
Will Look into this case |
This comment has been minimized.
This comment has been minimized.
@matthewhughes934 I'm not sure your example currently works with the latest Running your example produces invalid code. pub trait MyTrait /* first */ trait /* second */ MyTrait /* third */ {} |
Okay, the latest commit addresses this case. |
| result = combine_strs_with_missing_comments( | ||
| context, | ||
| &result, | ||
| &generics_str, | ||
| comment_span, | ||
| // infinite_width so we don't put the `ident + generics_str` on the next line | ||
| shape.infinite_width(), | ||
| true, | ||
| )?; |
There was a problem hiding this comment.
In the future I might want to make the headers mechanism to also do this part of the job too.
There was a problem hiding this comment.
I was hoping to add the generics_str code to the HeaderPart vec as well to simplify things, but because format_header always uses shape.infinite_width() generic's weren't getting properly wrapped.
Maybe updating HeaderPart to something like this in the future is something we could consider:
pub(crate) struct HeaderPart<'a> {
kind: HeaderPartKind<'a>,
span: Span,
}
#[derive(Debug)]
enum HeaderPartKind<'a> {
/// snippet of this part without surrounding space
Snippet(Cow<'a, str>),
/// A closure that will be used to dynamically compute the header part
Computed(fn (&RewriteContext<'_>, Shape) -> RewriteResult)
}Then we could modify format_header to dynamically compute any HeaderPartKind::Computed header parts with an appropriate shape offset.
| pub /* first */ trait /* second */ MyTrait /* third */ {} | ||
|
|
There was a problem hiding this comment.
Please also add a test for something like this:
pub
/* a */
trait
/* b */
Foo
/* c */
{}Just to ensure that we don't accidentally format the comments (aligning them etc?).
There was a problem hiding this comment.
So I think after my own testing and looking at the original issue, it looks like pub /* a */ trait had the issue, but it looks like latest rustfmt also chokes on this one:
trait /* a */ X {}which gets reformatted to
trait X /* a */ X {}but in here, it gets re-aligned (thus formatted):
trait
/* b */
FooMy recollection of the discussion at #5847 (comment) is that we don't want to introduce comment formatting for now.
I'm obviously for us being bold and all, and I disagree with postponing these things because I doubt it will get done in a reasonable time. I also don't think rustfmt breakages should be done using "editions", it should just be through a normal upgrade process (remind me some months later to look into whether rustup can pin rustfmt versions, whether via rust-toolchain.toml or something else).
But I just wanted to let you know in case you wanted to be consistent with the original decision (which applied here would require you to preserve the original comment formatting), and note that trait Foo /* a */ {} would be fine because that behavior is pre-existing.
Otherwise, feel free to r=me.
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
Helper method to get the `Span` of a known substring within a span.
Simplify macro header formatting by using the new `HeaderPart::keyword` associated function.
Keep track of the `lo` span when rewriting parts the header so that we can correctly recover comments between the last rewritten part of the trait definition and the body of the trait.
Using `HeaderPart::auto` for formatting instead.
|
Marking as waiting on author per latest comment :) |
Fixes #6160, Fixes #5841
Expand the
HeaderPartstruct to handle some new header parts like,const,unsafe, andautoand refactortraitheader formatting to useHeaderPart.r? @fee1-dead since you originally added
HeaderPart