-
Notifications
You must be signed in to change notification settings - Fork 889
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
Handle block comment before Traits in derive attribute (issue 4984) #5002
Conversation
Are we sure the issue is specific to derive attributes? Seems to me that the actual issue/root cause is somewhere upstream in the call stack, and we should try to fix the underlying issue instead of working around the side effects that issue causes. e.g. what happens with: #[foo(/*Debug, */Clone)]
struct Foo; |
@calebcartwright On Looking at the Lines 379 to 494 in cb144c3
I also totally agree that the problem should be fixed higher up in the call stack. I had trouble figuring out where a good place to fix the issue would be though. From my understanding this is what's happening:
Taking a look at the Iterator implementation for lists::ListItems, which is where we construct each Lines 730 to 738 in cb144c3
Given the following: #[derive(/*Debug, */Clone)]
struct Foo; The Lines 591 to 596 in cb144c3
Let me know if all that makes sense. Again, I wasn't really sure where the fix should go, but I thought it made the most sense to implement the fix in |
Ah okay, thanks for confirming!
Yeah it sounds like the starting point of the span is at the start of the attribute instead of the paren |
I removed the old fix where I just stripped |
src/attr.rs
Outdated
attr.span.lo(), | ||
// We update derive attribute spans to start after the opening '(' | ||
// This helps us focus parsing to just what's inside #[derive(...)] | ||
attr.span.lo() + BytePos("#[derive(".len() as u32), |
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.
Excellent, this is precisely what I had in mind! This type of offset derivation is so common that we actually have a lot of utilities that make this easy to do, and account for various edge cases and complexities (whitespace, comments, etc.) so we'll want to apply the same idea here, but utilize the helper instead. We can also just look for the opening paren in this case, so that we don't have to worry about anything weird but technically valid like #[ derive (
type scenaro
e.g. (disclaimer, typed inline so may need to be tweaked and/or have the SpanUtils imported from source_map)
attr.span.lo() + BytePos("#[derive(".len() as u32), | |
context.snippet_provider.span_after(attr.span, "("), |
Fixes 4984 When parsing derive attributes we're only concerned about the traits and comments listed between the opening and closing parentheses. Derive attribute spans currently start at the '#'. Span starts here | v #[derive(...)] After this update the derive spans start after the opening '('. Span starts here | V #[derive(...)]
Thanks for pointing out the helper method and for the heads up on bringing SpanUtils into scope! I went ahead and made the change. I think your hunch about the other issues having a similar cause is probably right. I should have some time to take a crack at it later this week! |
LGTM thanks! |
Resolves #4984
When a block comment comes before the traits of a derive attribute
the string "#[derive(" is included as part of the the pre snippet, and as
a result gets duplicated.
For example:
Now the string "#[derive(" is trimmed from the start of the pre snippet
before looking for the pre comment.