Skip to content

fix [large_stack_arrays] linting in vec macro #12624

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 2 commits into from
Apr 27, 2024

Conversation

J-ZhengLi
Copy link
Member

@J-ZhengLi J-ZhengLi commented Apr 3, 2024

fixes: #12586

this PR also adds a wrapper function matching_root_macro_call to clippy_utils::macros, considering how often that same pattern appears in the codebase.

(I'm always very indecisive towards naming, so, if anyone have better idea of how that function should be named, feel free to suggest it)


changelog: fix [large_stack_arrays] linting in vec macro; add matching_root_macro_call to clippy_utils

@rustbot
Copy link
Collaborator

rustbot commented Apr 3, 2024

r? @xFrednet

rustbot has assigned @xFrednet.
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 Apr 3, 2024
@J-ZhengLi
Copy link
Member Author

J-ZhengLi commented Apr 3, 2024

Actually... on a second thought, this could still has FP when the vec! is not the root macro call, such as:

some_macro!(vec![x, x, x, x, x]);

But then if I check the first expanded macro call it will have FP with:

vec![some_macro_that_reduces_x_frequency!(x;5)];

So, what will be the best approach here, do I need to check all the macro calls?

@xFrednet
Copy link
Member

xFrednet commented Apr 4, 2024

But then if I check the first expanded macro call it will have FP with:

vec![some_macro_that_reduces_x_frequency!(x;5)];

So, what will be the best approach here, do I need to check all the macro calls?

We could check if the span of the x expressions comes from a different macro and abort if it does. That sounds like the best solution for me

@J-ZhengLi
Copy link
Member Author

J-ZhengLi commented Apr 4, 2024

We could check if the span of the x expressions comes from a different macro and abort if it does. That sounds like the best solution for me

Ok I see~ should I keep that newly added utils function tho? Since this solution won't need it anymore.

oh wait... you meant check the root macro to see if it's vec, then iterates macro calls again to find any non-vec macro call, is that correct?

@xFrednet
Copy link
Member

xFrednet commented Apr 4, 2024

should I keep that newly added utils function tho?

I like the new function, it makes the code cleaner, so please keep it.

oh wait... you meant check the root macro to see if it's vec, then iterates macro calls again to find any non-vec macro call, is that correct?

I meant to check the span of x to see if it's used directly in the vec![] macro or if it's created and copied from some other macro. I'm always a bit uncertain, how rustc models spans but this information should be available somewhere 🤔

@J-ZhengLi J-ZhengLi marked this pull request as draft April 9, 2024 12:15
@J-ZhengLi J-ZhengLi force-pushed the issue12586 branch 2 times, most recently from 2d1d7b2 to 5824c4c Compare April 10, 2024 07:53
@J-ZhengLi J-ZhengLi marked this pull request as ready for review April 10, 2024 10:18
@J-ZhengLi
Copy link
Member Author

J-ZhengLi commented Apr 10, 2024

vec![some_macro_that_reduces_x_frequency!(x;5)];

well... I though I can write such function-like macro to only produce some tokens, in this case x, x, x, x, x. But seems like I was wrong, it doesn't allows me 🤦‍♂️ , I've tried both using proc_macro and macro_rules!...

So I'm guessing the xs can only be created and copied from some other macro? If true then checking if there's a vec call in macro backtrace should be good right?

@xFrednet
Copy link
Member

There is the quote::quote_spanned macro which allows you to modify the span of tokens. But Clippy usually doesn't handle these cases since they're quite messy. Maybe we have a test macro in Clippy with this?

If true then checking if there's a vec call in macro backtrace should be good right?

I'd say so. We can just run lintcheck and see what it spits out :D

@J-ZhengLi J-ZhengLi marked this pull request as draft April 15, 2024 10:04
@J-ZhengLi J-ZhengLi marked this pull request as ready for review April 16, 2024 07:36
@J-ZhengLi J-ZhengLi force-pushed the issue12586 branch 3 times, most recently from 6630ead to efef920 Compare April 16, 2024 09:38
@J-ZhengLi J-ZhengLi force-pushed the issue12586 branch 3 times, most recently from 027b1b3 to e70c892 Compare April 17, 2024 10:09
Comment on lines +101 to +102
let y = proc_macros::make_it_big!([x; 1]);
//~^ ERROR: allocating a local array larger than 512000 bytes
Copy link
Member Author

Choose a reason for hiding this comment

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

Well... in this test case, the expr being checked is [x; 1], but I guess since the span of 1 was used in quote_spanned(?), for some reason even is_from_proc_macro(cx, expr) fails.

Copy link
Member Author

Choose a reason for hiding this comment

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

oh, runing lintcheck has no differences unfortunately, both gives 4 occurrences lol

Copy link
Member

Choose a reason for hiding this comment

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

I would guess that those occurrences are the result of incorrect quote_spanned usage. Let's get this version merged for now.

Comment on lines +104 to +115
/// Check if the span of `ArrayLen` of a repeat expression is within the expr's span,
/// if not, meaning this repeat expr is definitely from some proc-macro.
///
/// This is a fail-safe to a case where even the `is_from_proc_macro` is unable to determain the
/// correct result.
fn repeat_expr_might_be_expanded<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> bool {
let ExprKind::Repeat(_, ArrayLen::Body(anon_const)) = expr.kind else {
return false;
};
let len_span = cx.tcx.def_span(anon_const.def_id);
!expr.span.contains(len_span)
}
Copy link
Member Author

Choose a reason for hiding this comment

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

therefore I have to use this hacky way to check, but I don't know if this can always work or just coincidentally succeed in my specific test case.

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 this hack is good enough. quote_spanned is sadly pretty bad for rust tools, we just have to hope that users of quote_spanned understand what they're doing

@xFrednet
Copy link
Member

Thank you for the update :D

@bors r+

@bors
Copy link
Contributor

bors commented Apr 27, 2024

📌 Commit 2861729 has been approved by xFrednet

It is now in the queue for this repository.

@bors
Copy link
Contributor

bors commented Apr 27, 2024

⌛ Testing commit 2861729 with merge c6bf954...

@bors
Copy link
Contributor

bors commented Apr 27, 2024

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

@bors bors merged commit c6bf954 into rust-lang:master Apr 27, 2024
5 checks passed
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.

clippy::large_stack_arrays reports vec! literals and provides a useless suggestion
4 participants