-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Count unsafe operations and macro calls once towards the innermost unsafe block #16117
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
base: master
Are you sure you want to change the base?
Conversation
|
Lintcheck changes for 181cb9c
This comment will be updated if you push new changes |
|
The actual issue is nested unsafe f1() {}
unsafe f2() {}
fn f3() {
unsafe {
f1();
unsafe { f2(); }
}
}This only has one unsafe operation in each block, just one of them happens to be nested in another. We should still be considering a macro call to be a single thing. A macro expanding to multiple unsafe calls without an unsafe block shouldn't trigger the lint. |
Also, macro calls are counted as at most one unsafe operation.
e7ee98d to
181cb9c
Compare
|
Done. |
| _ if expr.span.from_expansion() => { | ||
| let mut inner_collector = Self { | ||
| tcx: self.tcx, | ||
| typeck_results: self.typeck_results, | ||
| unsafe_ops: vec![], | ||
| }; | ||
| walk_expr(&mut inner_collector, expr); | ||
| if !inner_collector.unsafe_ops.is_empty() { | ||
| let span = expr.span.source_callsite(); | ||
| self.unsafe_ops | ||
| .push(("macro call expanded to unsafe operation here", span)); | ||
| } | ||
| return; | ||
| }, |
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.
This doesn't handle macro arguments properly.
print!("{}, {}", foo(), foo());This has two unsafe operations added by the user, but this would currently be detected as one.
What you'll need to do is extend the visitor store what context the unsafe block is in. When detecting an unsafe operation in a different context walk the call chain up to the block's context and use the immediate callee's context as the source of the unsafe call with each callee counting for at most one unsafe operation.
If you can't walk to the block's context from the unsafe op then it's a macro argument. Not really sure the best way to count that.
when finding an unsafe operation, walk up the call chain to the unsafe block currently being checked.
| note: macro call expanded to unsafe operation here | ||
| --> tests/ui/multiple_unsafe_ops_per_block.rs:328:17 | ||
| | | ||
| LL | let _ = format!("{}", foo()); | ||
| | ^^^^^^^^^^^^^^^^^^^^ |
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.
You can also see the effect here with the macro being blamed for the foo call even though it's unrelated.
changelog: [
multiple_unsafe_ops_per_block]: count unsafe operations only towards the innermost unsafe blockFixes #16116
r? Jarcho