-
Notifications
You must be signed in to change notification settings - Fork 1.6k
add suggestions to rc_clone_in_vec_init #8814
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
add suggestions to rc_clone_in_vec_init #8814
Conversation
r? @Manishearth (rust-highfive has picked a reviewer for you, use r? to override) |
} | ||
} | ||
|
||
fn emit_lint(cx: &LateContext<'_>, symbol: Symbol, macro_call: &MacroCall) { | ||
struct LintSuggestion { |
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'm wondering whether this can be extracted to a util somewhere
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 think in most cases it's better to use span_lint_and_then
and pass the DiagnosticBuilder
around. That's also a bit more efficient when it comes to performance. The DiagnosticBuilder
will store the suggestions internally. Is there a reason why you want to use this intermediate struct to store the suggestions? 🙃
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.
Just so I can construct the suggestions separately from where I'm emitting the lint, so that the span_lint_and_then
code will be clean from logistics.
In terms of performance, since I'm passing a & mut Diagnostic
the performance overhead is basically only the Vec<LintSuggestion>
creation - which I thought is a small price to pay for readability.
Lmk if there's some other design you'd prefer 🙂
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.
The idea in rustc is actually to create the suggestion inside the closure. Clippy does it a bit differently to have a simpler interface, but if we use span_lint_and_then
we usually try to also create the suggestion inside. Extracting the specific string creation to single functions like this is nice, but I wouldn't store them in another struct. Also, since the Span
and Applicability
is always the same.
In terms of performance
This comment was more about the internal implementation in rustc. If lints are allowed, they won't be emitted, rustc then never calls the closure. That's what I was referring to. That is super nit picky though, it only came to mind since I've worked on that recently. I sometimes go a bit overboard with my reviews, this side node is an example for this 😅. So please ignore the performance comment 🙃
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'm willing to go as deep into this rabbit hole as you are 🙂
np, I'll change the design a bit so that everything is being passed to emit_lint
and it'll construct the suggestion by calling another function inside the clousure
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.
Question is, how important are performance here? Is vec allocation going to cost too much here?
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.
Not really, this is more about the style, I don't really see the reason for having the struct just to pass them to the DiagnosticBuilder
afterwards. What about passing in the DiagnosticBuilder
into the function as an argument?
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.
that's basically what I offered, just don't know what is DiagnosticBuilder
exactly 🙈
the closure receives a &mut Diagnostic
.
I'm offering to pass it into construct_lint_suggestions
such that this function will span the suggestions instead of returning them as a vec.
I don't really see the reason for having the struct just to pass them to the DiagnosticBuilder afterwards.
Imo passing named data between scopes is arguably justifying a struct.
None the less, I'll change it as you wish of course 🙂
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 ended up basically taking your suggestion from here: #8814 (comment)
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.
Imo passing named data between scopes is arguably justifying a struct.
That's totally correct. In this case, I just felt a bit weird, since I would say that the DiagnosticBuilder
is exactly for this. Sorry for not explaining what the builder is, it's just the argument received from the span_lint_and_then
argument. This implementation looks good to me on a quick glance, I'll try to do a full review soon 🙃
There ain't no rest for the wicked 🎶 🎶 😂 Thank you for the ping. I'm happy to see the follow-up PR. I'll put it on my todo list. FYI, you can also request a specific reviewer with 🙃 r? @xFrednet |
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.
The lint suggestions looks fantastic, I left some comments regarding the implementation 🙃
let reference_initialization_end = | ||
elem_snippet.find(&reference_initialization).unwrap() + reference_initialization.len(); | ||
elem_snippet.replace_range(reference_initialization_end.., ".."); |
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.
Nice explanatory comment 🙃
Why do you use replace_range
? Wouldn't it be simpler to reassign elem_snippet
like this?
if elem_snippet.contains('\n') {
elem_snippet = format!("{symbol_name}::new(..)");
}
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.
lol I played around with the snippet trimming, tried some variations until i came up with this monstrosity 🤣
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.
ah, actually now that im looking at it, if you had std::rc::Rc::new...
in the original code, the suggestion should also start the same way, and not just Rc::new(..)
I'll change the code to be more straight forward though
} | ||
} | ||
|
||
fn emit_lint(cx: &LateContext<'_>, symbol: Symbol, macro_call: &MacroCall) { | ||
struct LintSuggestion { |
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.
The idea in rustc is actually to create the suggestion inside the closure. Clippy does it a bit differently to have a simpler interface, but if we use span_lint_and_then
we usually try to also create the suggestion inside. Extracting the specific string creation to single functions like this is nice, but I wouldn't store them in another struct. Also, since the Span
and Applicability
is always the same.
In terms of performance
This comment was more about the internal implementation in rustc. If lints are allowed, they won't be emitted, rustc then never calls the closure. That's what I was referring to. That is super nit picky though, it only came to mind since I've worked on that recently. I sometimes go a bit overboard with my reviews, this side node is an example for this 😅. So please ignore the performance comment 🙃
I think the only comment I didn't fix was the |
Looks good to me, thank you for the update and diagnostic improvement. I like the new diagnostic message :) @bors r+ |
📌 Commit ed3744b has been approved by |
☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test |
A followup to #8769
I also switch the order of the 2 suggestions, since the loop initialization one is probably the common case.
@xFrednet I'm not letting you guys rest for a minute 😅
changelog: add suggestions to [
rc_clone_in_vec_init
]