Skip to content
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 new unconditional_recursion lint #11938

Merged
merged 4 commits into from
Dec 16, 2023

Conversation

GuillaumeGomez
Copy link
Member

Currently, rustc unconditional_recursion doesn't detect cases like:

enum Foo {
    A,
    B,
}

impl PartialEq for Foo {
    fn eq(&self, other: &Self) -> bool {
        self == other
    }
}

This is because the lint is currently implemented only for one level, and in the above code, self == other will then call impl PartialEq for &T, escaping from the detection. The fix for it seems to be a bit tricky (I started investigating potential solution to add one extra level of recursion here but completely broken at the moment).

I expect that this situation will remain for a while. In the meantime, I think it's acceptable to check it directly into clippy for the time being as a lot of easy cases like this one can be easily checked (next I plan to extend it to cover other traits like ToString).

changelog: Add new unconditional_recursion lint

@rustbot
Copy link
Collaborator

rustbot commented Dec 8, 2023

r? @llogiq

(rustbot has picked a reviewer for you, use r? to override)

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Dec 8, 2023
@GuillaumeGomez GuillaumeGomez force-pushed the unconditional_recursion branch 3 times, most recently from 50a4fa9 to f3e9943 Compare December 9, 2023 14:36
@GuillaumeGomez
Copy link
Member Author

Finally fixed CI. ^^'

@llogiq
Copy link
Contributor

llogiq commented Dec 9, 2023

I think more tests with e.g. other == self and/or various wrapper type combinations would be good to rule out any false positives.

@GuillaumeGomez GuillaumeGomez force-pushed the unconditional_recursion branch from f3e9943 to e75195d Compare December 10, 2023 16:35
@GuillaumeGomez
Copy link
Member Author

I added a lot more tests. Please tell me if you have other ideas for tests to be added.

@bors
Copy link
Contributor

bors commented Dec 11, 2023

☔ The latest upstream changes (presumably #11878) made this pull request unmergeable. Please resolve the merge conflicts.

@GuillaumeGomez GuillaumeGomez force-pushed the unconditional_recursion branch from e75195d to 3da31c5 Compare December 11, 2023 13:54
@GuillaumeGomez
Copy link
Member Author

Fixed merge conflict.

@bors
Copy link
Contributor

bors commented Dec 12, 2023

☔ The latest upstream changes (presumably #11902) made this pull request unmergeable. Please resolve the merge conflicts.

@GuillaumeGomez GuillaumeGomez force-pushed the unconditional_recursion branch from 3da31c5 to 91fd01c Compare December 12, 2023 14:37
@GuillaumeGomez
Copy link
Member Author

Fixed merge conflict.

@llogiq
Copy link
Contributor

llogiq commented Dec 13, 2023

How about the following test case:

Impl PartialEq for Foo {
    fn eq(&self, other: &Self) -> bool {
        Bar(self) == Bar(other)
    }
}

There might also be some macro test cases that prove hairy, e.g. when the impl is supplied by proc macro.

@GuillaumeGomez
Copy link
Member Author

I disabled the lint if the code comes from macro expansion. Maybe I should just disable it from proc-macro expansion?

As for your code example: not detected. But in this case, I can put recursion. I'm just not sure how "deep" we want to make it. Let's start with 3 nested levels and we'll see.

@llogiq
Copy link
Contributor

llogiq commented Dec 16, 2023

No, leaving the example undetected is fine, loop detection would be cool but slow.

And yes, detecting code inside macros would be great if we can pull off the reporting without showing weird macro-expanded code that will only confuse people.

@GuillaumeGomez GuillaumeGomez force-pushed the unconditional_recursion branch from 07b27f5 to 73f189e Compare December 16, 2023 17:19
@GuillaumeGomez GuillaumeGomez force-pushed the unconditional_recursion branch from 73f189e to 6b444f3 Compare December 16, 2023 17:45
@GuillaumeGomez
Copy link
Member Author

I have put back the (proc) macros checks, only excluding the ones generated from rustc. I also disabled a lint in the test to have less noise and added some comments in the code to make it easier to understand what's going on.

@llogiq
Copy link
Contributor

llogiq commented Dec 16, 2023

Thank you!

@bors r+

@bors
Copy link
Contributor

bors commented Dec 16, 2023

📌 Commit 6b444f3 has been approved by llogiq

It is now in the queue for this repository.

@bors
Copy link
Contributor

bors commented Dec 16, 2023

⌛ Testing commit 6b444f3 with merge 9907b90...

@bors
Copy link
Contributor

bors commented Dec 16, 2023

☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test
Approved by: llogiq
Pushing 9907b90 to master...

@bors bors merged commit 9907b90 into rust-lang:master Dec 16, 2023
8 checks passed
@GuillaumeGomez GuillaumeGomez deleted the unconditional_recursion branch December 16, 2023 19:11
@llogiq
Copy link
Contributor

llogiq commented Dec 25, 2023

Thanks, this looks good.

@bors r+

bors added a commit that referenced this pull request Dec 31, 2023
…g, r=llogiq

Extend UNCONDITIONAL_RECURSION to check for ToString implementations

Follow-up of #11938.

r? `@llogiq`

changelog: Extend `UNCONDITIONAL_RECURSION` to check for `ToString` implementations
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.

4 participants