-
-
Notifications
You must be signed in to change notification settings - Fork 14.4k
Avoid miri error in slice::sort under Stacked Borrows
#151756
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: main
Are you sure you want to change the base?
Conversation
|
rustbot has assigned @Mark-Simulacrum. Use |
|
I suspect you meant to link to an issue, but currently link to the PR updating the sorting algorithm? |
|
The issue in question is #151728 |
|
I think this could also fix the issue by |
|
Can this cause sorting in miri to result in a different order from the order outside miri? (Especially with misbehaving PartialOrd impls, or with equal but distinct elements.) |
|
Yeah I think MaybeUninit should work just fine (or MaybeDangling if that already exists?). I would really prefer to avoid adding |
|
I would really like to avoid the Testing it out the error persists if I do: // SAFETY: We only access the temporary copy for Freeze types, otherwise
// self-modifications via `is_less` would not be observed and this would
// be unsound. Our temporary copy does not escape this scope.
let pivot_copy = unsafe { MaybeUninit::new(ptr::read(&v[pivot_pos])) };
// SAFETY: We created the value with `MaybeUninit::new` so it is guaranteed init.
let pivot_ref =
(!has_direct_interior_mutability::<T>()).then_some(unsafe { &*pivot_copy.as_ptr() }); |
|
it's really really unfortunate if Miri has different behavior than not-Miri, no matter how broken the code. |
|
Maybe just the let pivot_copy = unsafe { ptr::read((&raw const v[pivot_pos]).cast::<MaybeUninit<T>>()) }; |
00e6809 to
b658896
Compare
|
Nice, that does it. |
This comment has been minimized.
This comment has been minimized.
b658896 to
1a7f396
Compare
Temporarily creating a child box that then disappears immediately should be fine. So for this to be a problem, there have to be overlapping (non-nested) lifetimes of the boxes here... is that's what is going on? |
I'm not sure. I'll try to explain a simplified algorithm:
|
See comment in code. Fixes: rust-lang#131065
1a7f396 to
ce03e7b
Compare
|
Okay so there's some other place in the code where Boxes are being retagged, specifically when two elements are being swapped? Might be worth also making that an entirely bytewise operation without retags. |
|
Not sure what you mean, the swapping - it's more complicated than that since it's first written to an auxiliary buffer - all happens via |
|
Yeah,
Ah, that makes sense. So the order of events is
|
|
That sounds right, yep. |
See comment in code.
Fixes: #151728