Skip to content

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

Merged
merged 5 commits into from
May 17, 2022

Conversation

yonip23
Copy link
Contributor

@yonip23 yonip23 commented May 10, 2022

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]

@rust-highfive
Copy link

r? @Manishearth

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label May 10, 2022
}
}

fn emit_lint(cx: &LateContext<'_>, symbol: Symbol, macro_call: &MacroCall) {
struct LintSuggestion {
Copy link
Contributor Author

@yonip23 yonip23 May 10, 2022

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

Copy link
Member

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? 🙃

Copy link
Contributor Author

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 🙂

Copy link
Member

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 🙃

Copy link
Contributor Author

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

Copy link
Contributor Author

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?

Copy link
Member

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?

Copy link
Contributor Author

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 🙂

Copy link
Contributor Author

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)

Copy link
Member

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 🙃

@xFrednet
Copy link
Member

xFrednet commented May 10, 2022

I'm not letting you guys rest for a minute

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

Copy link
Member

@xFrednet xFrednet left a 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 🙃

Comment on lines 114 to 116
let reference_initialization_end =
elem_snippet.find(&reference_initialization).unwrap() + reference_initialization.len();
elem_snippet.replace_range(reference_initialization_end.., "..");
Copy link
Member

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(..)");
}

Copy link
Contributor Author

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 🤣

Copy link
Contributor Author

@yonip23 yonip23 May 11, 2022

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 {
Copy link
Member

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 🙃

@yonip23
Copy link
Contributor Author

yonip23 commented May 11, 2022

I think the only comment I didn't fix was the {indent} one - lmk wdyt

@xFrednet
Copy link
Member

Looks good to me, thank you for the update and diagnostic improvement. I like the new diagnostic message :)

@bors r+

@bors
Copy link
Contributor

bors commented May 17, 2022

📌 Commit ed3744b has been approved by xFrednet

@bors
Copy link
Contributor

bors commented May 17, 2022

⌛ Testing commit ed3744b with merge d901079...

@bors
Copy link
Contributor

bors commented May 17, 2022

☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test
Approved by: xFrednet
Pushing d901079 to master...

@bors bors merged commit d901079 into rust-lang:master May 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants