Skip to content

Optimize unit_return_expecting_ord #14905

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 1 commit into from
May 28, 2025

Conversation

blyxyas
Copy link
Member

@blyxyas blyxyas commented May 27, 2025

This lint was previously written very clumsily, not short-circuiting and doing a lot of unnecessary work.

Now it makes sure to do the cheaper functions earlier and in general, is just smarter.
(I specifically focused on minimizing binder instantiation

Sadly, I'm not finding any relevant result in a benchmark. Still with the LLVM coverage instruments, the expensive bits are called lots of less times (The binder instantiation that I care about is reduced from 95k to 10k throughout our test suite).

changelog:[unit_return_expecting_ord]: Optimize the lint

@rustbot
Copy link
Collaborator

rustbot commented May 27, 2025

r? @samueltardieu

rustbot has assigned @samueltardieu.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label May 27, 2025
Copy link
Contributor

@samueltardieu samueltardieu left a comment

Choose a reason for hiding this comment

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

Nice, but you can use interned symbols instead of allocating strings, that can only help (if a little bit) with performances.

fn_mut_trait: DefId,
ord_trait: Option<DefId>,
partial_ord_trait: Option<DefId>,
) -> Vec<(usize, String)> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
) -> Vec<(usize, String)> {
) -> Vec<(usize, Symbol)> {

@@ -102,12 +116,18 @@ fn get_args_to_check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Ve
.iter()
.any(|ord| Some(ord.self_ty()) == return_ty_pred.term.as_type())
{
args_to_check.push((i, "Ord".to_string()));
args_to_check.push((i, String::from("Ord")));
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
args_to_check.push((i, String::from("Ord")));
args_to_check.push((i, sym::Ord));

} else if partial_ord_preds
.iter()
.any(|pord| pord.self_ty() == return_ty_pred.term.expect_type())
{
args_to_check.push((i, "PartialOrd".to_string()));
args_to_check.push((i, String::from("PartialOrd")));
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
args_to_check.push((i, String::from("PartialOrd")));
args_to_check.push((i, sym::PartialOrd));

Copy link
Member Author

Choose a reason for hiding this comment

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

I did it initially and reverted it with some mental gymnastics. I'll re-revert it.

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels May 28, 2025
@blyxyas blyxyas force-pushed the minimize-interning branch from 7d0b957 to 2635ced Compare May 28, 2025 15:40
Copy link
Contributor

@samueltardieu samueltardieu left a comment

Choose a reason for hiding this comment

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

Except for the two nits (no need to call .as_str(), and you can inline the trait_name in format string), this LGTM. If you just fix those two places feel free to r=me.

Comment on lines 189 to 192
format!(
"this closure returns \
the unit type which also implements {}",
trait_name.as_str()
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
format!(
"this closure returns \
the unit type which also implements {}",
trait_name.as_str()
format!(
"this closure returns \
the unit type which also implements {trait_name}"

Comment on lines 201 to 203
format!(
"this closure returns \
the unit type which also implements {}",
trait_name.as_str()
),
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
format!(
"this closure returns \
the unit type which also implements {}",
trait_name.as_str()
),
format!(
"this closure returns \
the unit type which also implements {trait_name}"
),

This lint was previously written very clumsily, not
shortcircuiting and doing a lot of unnecessary work.

Now it makes sure to do the cheaper functions earlier
and in general, just be smarter.
(I specifically focused on minimizing binder instantiation)

Also, avoid allocating unnecessarily
@blyxyas blyxyas force-pushed the minimize-interning branch from 2635ced to 7e590de Compare May 28, 2025 16:00
@blyxyas
Copy link
Member Author

blyxyas commented May 28, 2025

feel free to r=me

Sadly we don't have bors anymore, so PRs can't be merged in behalf of another person 😢

@samueltardieu
Copy link
Contributor

I know, this is an inherited way of saying "feel free to press the merge button on my behalf as I take responsibility for it". But since I'm here I'll do it!

@samueltardieu samueltardieu added this pull request to the merge queue May 28, 2025
Merged via the queue into rust-lang:master with commit b90880d May 28, 2025
11 checks passed
@@ -36,21 +36,26 @@ declare_clippy_lint! {

declare_lint_pass!(UnitReturnExpectingOrd => [UNIT_RETURN_EXPECTING_ORD]);

fn get_trait_predicates_for_trait_id<'tcx>(
// For each
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this comment unfinished?

{
preds.push(trait_pred);
.instantiate_bound_regions_with_erased(pred.kind().rebind(poly_trait_pred));
for (i, tid) in trait_ids.iter().enumerate() {
Copy link
Contributor

Choose a reason for hiding this comment

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

The slice/array approach is a bit hard to understand, you have to look at the callsite to understand it. I see you want to get the operations within the instantiate_bound_regions_with_erased call. I think you could do that by passing in three separate arguments and handling them in sequence here, instead of using a for loop? I think that would be easier to read.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants