Skip to content

Ensure consistent drop for panicking drop in hint::select_unpredictable #145174

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

197g
Copy link
Contributor

@197g 197g commented Aug 9, 2025

There are a few alternatives to the implementation. The principal problem is that the selected value must be owned (in the sense of having a drop flag of sorts) when the unselected value is dropped, such that panic unwind goes through the drop of both. This ownership must then be passed on in return when the drop went smoothly.

The basic way of achieving this is by extracting the selected value first, at the cost of relying on the optimizer a little more for detecting the copy as constructing the return value despite having a place in the body. Unfortunately, that causes LLVM to discard the !unpredictable annotation (for some reason that is beyond my comprehension of LLVM).

Extract from the build log showing an unannotated select being used
2025-08-09T16:51:06.8790764Z            39: define noundef i64 @test_int2(i1 noundef zeroext %p, i64 noundef %a, i64 noundef %b) unnamed_addr #0 personality ptr @rust_eh_personality { 
2025-08-09T16:51:06.8791368Z check:47'0                                  X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: no match found
2025-08-09T16:51:06.8791700Z            40: start: 
2025-08-09T16:51:06.8791858Z check:47'0     ~~~~~~~
2025-08-09T16:51:06.8792043Z            41:  %ret.i = select i1 %p, i64 %a, i64 %b 
2025-08-09T16:51:06.8792293Z check:47'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2025-08-09T16:51:06.8792686Z check:47'1               ?                             possible intended match
2025-08-09T16:51:06.8792946Z            42:  ret i64 %ret.i 
2025-08-09T16:51:06.8793127Z check:47'0     ~~~~~~~~~~~~~~~~

So instead, this PR includes a guard to drop the selected MaybeUnit<T> which is active only for the section where the unselected value is dropped. That leaves the code for selecting the result intact leading to the expected ir. That complicates the 'unselection' process a little bit since we require both values as a result of that intrinsic call. Since the arguments alias, this portion as well as the drop guard uses raw pointers.

Closes: #145148
Prior: #139977

There are a few alternatives to the implementation. The principal
problem is that the selected value must be owned (in the sense of having
any drop flag of sorts) when the unselected value is dropped, such that
panic unwind goes through the drop of both. This ownership must then be
passed on in return when the drop went smoothly. The basic way of
achieving this is by extracting the selected value first, at the cost of
relying on the optimizer a little more for detecting the copy as
constructing the return value despite having a place in the body.
@rustbot
Copy link
Collaborator

rustbot commented Aug 9, 2025

r? @thomcc

rustbot has assigned @thomcc.
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 S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Aug 9, 2025
@197g 197g changed the title Ensure consistent drop for hint::select_unpredictable Ensure consistent drop for panicking drop in hint::select_unpredictable Aug 9, 2025
@rust-log-analyzer

This comment has been minimized.

It seems important for LLVM that we select on the values by-value
instead of reading and have no intermediate store. So make sure the
guards selects both potential drops but defers the return value to the
second selection. Since the two options alias we use raw mutable
pointers instead of mutable references as before.
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. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

hint::select_unpredictable forgets to drop one argument if dropping another panics.
4 participants