Skip to content

lint: Make unsafe_op_in_unsafe_fn trigger in external macros - #165210

Draft
Enselic wants to merge 5 commits into
rust-lang:mainfrom
Enselic:minimal-unsafe_op_in_unsafe_fn-fix
Draft

Enselic wants to merge 5 commits into
rust-lang:mainfrom
Enselic:minimal-unsafe_op_in_unsafe_fn-fix

Conversation

@Enselic

@Enselic Enselic commented Oct 30, 2026 •

Copy link
Copy Markdown
Member

The unsafety does not go away just because the unsafe operations are in an external macro, so make the lint report in external macros.

This PR will eventually close #112504, but a bunch of preparatory commits are required first, that I will prepare separately.

Draft PR Notes

The purpose of the #[allow(unsafe_op_in_unsafe_fn)] hacks in the #[alloc_error_handler] and #[global_allocator] macros are to produce a usable toolchain with minimal changes. They are not meant as long-term fixes.

LLM disclosure

I used an LLM to to help me find the right location for a fix. I wrote the fix (which happens to be trivial) and test code myself. The only LLM-written code is the temporary #[allow(unsafe_op_in_unsafe_fn)] hacks.

The unsafety does not go away just because the unsafe operations are in
an external macro, so make the lint report in external macros.

NOTE: The purpose of the `#[allow(unsafe_op_in_unsafe_fn)]` hacks in the
`#[alloc_error_handler]` and `#[global_allocator]` macros are to produce
a usable toolchain with minimal changes. They are not meant as long-term
fixes.
@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 30, 2026
@rust-log-analyzer

This comment has been minimized.

@rustbot rustbot added A-testsuite Area: The testsuite used to check the correctness of rustc T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) labels Oct 30, 2026
@rust-log-analyzer

This comment has been minimized.

@rustbot rustbot added the T-rust-analyzer Relevant to the rust-analyzer team, which will review and decide on the PR/issue. label Oct 31, 2026
@rust-log-analyzer

This comment has been minimized.

To not fail the test when issue 112504 is fixed.

Alternatively, we could simply enclose in an unsafe block, like this:

    unsafe {
        __unsf();
    }

but instead allowing `unsafe_op_in_unsafe_fn` keeps the reproducer as
similar as possible to the original reproducer.
@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job test-pr-check-1 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
#15 2.701 Building wheels for collected packages: reuse
#15 2.702   Building wheel for reuse (pyproject.toml): started
#15 2.875   Building wheel for reuse (pyproject.toml): finished with status 'done'
#15 2.876   Created wheel for reuse: filename=reuse-4.0.3-cp310-cp310-linux_x86_64.whl size=132855 sha256=78b18759d7868af836e6c653035275b9564ead1e102ae69b3b788a82f243d193
#15 2.876   Stored in directory: /tmp/pip-ephem-wheel-cache-8djwsuzu/wheels/3d/8d/0a/e0fc6aba4494b28a967ab5eaf951c121d9c677958714e34532
#15 2.878 Successfully built reuse
#15 2.879 Installing collected packages: boolean-py, binaryornot, tomlkit, reuse, python-debian, markupsafe, license-expression, Jinja2, chardet, attrs
#15 3.194 Successfully installed Jinja2-3.1.6 attrs-23.2.0 binaryornot-0.4.4 boolean-py-4.0 chardet-5.2.0 license-expression-30.3.0 markupsafe-2.1.5 python-debian-0.1.49 reuse-4.0.3 tomlkit-0.13.0
#15 3.195 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
#15 DONE 3.3s
---
     |   in this expansion of `$crate::crossbeam_channel_internal!` (#8)
     |   in this expansion of `$crate::crossbeam_channel_internal!` (#9)
     |   in this expansion of `$crate::crossbeam_channel_internal!` (#10)
...
  30 | /         $crate::crossbeam_channel_internal!(
  31 | |             @case
  32 | |             ($($head)*)
  33 | |             ()
  34 | |             ()
  35 | |         )
     | |_________- in this macro invocation (#6)
...
 105 | /         $crate::crossbeam_channel_internal!(
 106 | |             @list
 107 | |             ($($tail)*)
 108 | |             ($($head)* $case ($($args)*) $(-> $res)* => { $body },)
 109 | |         )
     | |         -
     | |_________|
     | |_________in this macro invocation (#4)
     |           in this macro invocation (#5)
---
 359 |               $default
 360 | |         )
     | |_________- in this macro invocation (#9)
...
 369 | /         $crate::crossbeam_channel_internal!(
 370 | |             @case
 371 | |             ($($tail)*)
 372 | |             ($($cases)* recv($r) -> $res => $body,)
 373 | |             $default
 374 | |         )
     | |         -
     | |_________|
     | |_________in this macro invocation (#7)
     |           in this macro invocation (#8)
...
 693 | /         $crate::crossbeam_channel_internal!(
 694 |               @add
 695 |               _sel
 696 |               ($($cases)*)
...
 732 |               ()
 733 | |         )
     | |_________- in this macro invocation (#10)
...
---
     |
    ::: src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs:540:5
     |
 540 | /     select! {
 541 | |         recv(receiver) -> msg => Ok(msg.ok()),
 542 | |         recv(after(timeout)) -> _ => Err(Timeout),
 543 | |     }
     | |_____- in this macro invocation (#1)
     |
     = note: consult the function's documentation for information on how to avoid undefined behavior
note: an unsafe function restricts its caller, but its body is safe by default
---
     |   in this expansion of `$crate::crossbeam_channel_internal!` (#8)
     |   in this expansion of `$crate::crossbeam_channel_internal!` (#9)
     |   in this expansion of `$crate::crossbeam_channel_internal!` (#10)
...
  30 | /         $crate::crossbeam_channel_internal!(
  31 | |             @case
  32 | |             ($($head)*)
  33 | |             ()
  34 | |             ()
  35 | |         )
     | |_________- in this macro invocation (#6)
...
 105 | /         $crate::crossbeam_channel_internal!(
 106 | |             @list
 107 | |             ($($tail)*)
 108 | |             ($($head)* $case ($($args)*) $(-> $res)* => { $body },)
 109 | |         )
     | |         -
     | |_________|
     | |_________in this macro invocation (#4)
     |           in this macro invocation (#5)
---
 359 |               $default
 360 | |         )
     | |_________- in this macro invocation (#9)
...
 369 | /         $crate::crossbeam_channel_internal!(
 370 | |             @case
 371 | |             ($($tail)*)
 372 | |             ($($cases)* recv($r) -> $res => $body,)
 373 | |             $default
 374 | |         )
     | |         -
     | |_________|
     | |_________in this macro invocation (#7)
     |           in this macro invocation (#8)
...
 693 | /         $crate::crossbeam_channel_internal!(
 694 |               @add
 695 |               _sel
 696 |               ($($cases)*)
...
 732 |               ()
 733 | |         )
     | |_________- in this macro invocation (#10)
...
---
     |
    ::: src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs:540:5
     |
 540 | /     select! {
 541 | |         recv(receiver) -> msg => Ok(msg.ok()),
 542 | |         recv(after(timeout)) -> _ => Err(Timeout),
 543 | |     }
     | |_____- in this macro invocation (#1)
     = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
     = note: requested on the command line with `-W unsafe-op-in-unsafe-fn`

---
     |   in this expansion of `$crate::crossbeam_channel_internal!` (#9)
     |   in this expansion of `$crate::crossbeam_channel_internal!` (#10)
     |   in this expansion of `$crate::crossbeam_channel_internal!` (#11)
...
  30 | /         $crate::crossbeam_channel_internal!(
  31 | |             @case
  32 | |             ($($head)*)
  33 | |             ()
  34 | |             ()
  35 | |         )
     | |_________- in this macro invocation (#6)
...
 105 | /         $crate::crossbeam_channel_internal!(
 106 | |             @list
 107 | |             ($($tail)*)
 108 | |             ($($head)* $case ($($args)*) $(-> $res)* => { $body },)
 109 | |         )
     | |         -
     | |_________|
     | |_________in this macro invocation (#4)
     |           in this macro invocation (#5)
---
 359 |               $default
 360 | |         )
     | |_________- in this macro invocation (#9)
...
 369 | /         $crate::crossbeam_channel_internal!(
 370 | |             @case
 371 | |             ($($tail)*)
 372 | |             ($($cases)* recv($r) -> $res => $body,)
 373 | |             $default
 374 | |         )
     | |         -
     | |_________|
     | |_________in this macro invocation (#7)
     |           in this macro invocation (#8)
...
 693 | /         $crate::crossbeam_channel_internal!(
 694 |               @add
 695 |               _sel
 696 |               ($($cases)*)
...
 732 |               ()
 733 | |         )
     | |_________- in this macro invocation (#10)
...
 851 | |                         ::std::mem::transmute(x)
     | |                         ^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
...    |
 857 | /                 $crate::crossbeam_channel_internal!(
 858 |                       @add
 859 |                       $sel
 860 |                       ($($tail)*)
...
 863 |                       ($($cases)* [$i] recv($var) -> $res => $body,)
 864 | |                 )
     | |_________________- in this macro invocation (#11)
...
 976 | /         $crate::crossbeam_channel_internal!(
 977 |               @list
---
     |
    ::: src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs:540:5
     |
 540 | /     select! {
 541 | |         recv(receiver) -> msg => Ok(msg.ok()),
 542 | |         recv(after(timeout)) -> _ => Err(Timeout),
 543 | |     }
     | |_____- in this macro invocation (#1)
     |
     = note: consult the function's documentation for information on how to avoid undefined behavior
note: an unsafe function restricts its caller, but its body is safe by default
---
     |   in this expansion of `$crate::crossbeam_channel_internal!` (#9)
     |   in this expansion of `$crate::crossbeam_channel_internal!` (#10)
     |   in this expansion of `$crate::crossbeam_channel_internal!` (#11)
...
  30 | /         $crate::crossbeam_channel_internal!(
  31 | |             @case
  32 | |             ($($head)*)
  33 | |             ()
  34 | |             ()
  35 | |         )
     | |_________- in this macro invocation (#6)
...
 105 | /         $crate::crossbeam_channel_internal!(
 106 | |             @list
 107 | |             ($($tail)*)
 108 | |             ($($head)* $case ($($args)*) $(-> $res)* => { $body },)
 109 | |         )
     | |         -
     | |_________|
     | |_________in this macro invocation (#4)
     |           in this macro invocation (#5)
---
 359 |               $default
 360 | |         )
     | |_________- in this macro invocation (#9)
...
 369 | /         $crate::crossbeam_channel_internal!(
 370 | |             @case
 371 | |             ($($tail)*)
 372 | |             ($($cases)* recv($r) -> $res => $body,)
 373 | |             $default
 374 | |         )
     | |         -
     | |_________|
     | |_________in this macro invocation (#7)
     |           in this macro invocation (#8)
...
 693 | /         $crate::crossbeam_channel_internal!(
 694 |               @add
 695 |               _sel
 696 |               ($($cases)*)
...
 732 |               ()
 733 | |         )
     | |_________- in this macro invocation (#10)
...
 850 | |                     unsafe fn unbind<'a, T>(x: &T) -> &'a T {
     | |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...    |
 857 | /                 $crate::crossbeam_channel_internal!(
 858 |                       @add
 859 |                       $sel
 860 |                       ($($tail)*)
...
 863 |                       ($($cases)* [$i] recv($var) -> $res => $body,)
 864 | |                 )
     | |_________________- in this macro invocation (#11)
...
 976 | /         $crate::crossbeam_channel_internal!(
 977 |               @list
---
     |
    ::: src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs:540:5
     |
 540 | /     select! {
 541 | |         recv(receiver) -> msg => Ok(msg.ok()),
 542 | |         recv(after(timeout)) -> _ => Err(Timeout),
 543 | |     }
     | |_____- in this macro invocation (#1)
     = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>

[RUSTC-TIMING] project_model test:true 2.722
[RUSTC-TIMING] rust_analyzer test:false 0.347
For more information about this error, try `rustc --explain E0133`.
[RUSTC-TIMING] slow_tests test:true 0.885
error: `rust-analyzer` (test "slow-tests") generated 2 warnings
error: warnings are denied by `build.warnings` configuration
warning: build failed, waiting for other jobs to finish...
[RUSTC-TIMING] proc_macro_api test:true 2.051
[RUSTC-TIMING] hir_def test:true 9.061
[RUSTC-TIMING] hir_ty test:true 14.630

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-testsuite Area: The testsuite used to check the correctness of rustc S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rust-analyzer Relevant to the rust-analyzer team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

unsafe_op_in_unsafe_fn not triggered for raw pointer dereferencing inside addr_of/addr_of_mut

3 participants