-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Stacked Borrows violation in BufWriter::into_parts
#127584
Comments
Good catch!
That is odd. Miri uses |
Just searched for and somewhat amusingly
The reason I assigned was conjecture based on likely old information (Miri only checking cases where we passed constant assertions to LLVM by default), but it is the observed behavior. The second potential reason now coming to mind is that |
Ah yes that would explain it. |
I'm putting up a PR to fix just the instance reported here, but I would like to see a larger effort to replace all uses of |
In compiler, libs, or both? All usages of |
Note that I am not a libs reviewer, so before you submit a large PR you should check in with one of these lovely people or post in Zulilp: Lines 941 to 949 in 88fa119
I would prefer a simple policy that we do not use The compiler is much less important here; nobody is running the compiler in Miri and this hazard is specific to an aspect of Stacked Borrows that is not actively used in optimizations the current toolchain does. For the library, being clean with respect to Stacked Borrows is an important quality-of-implementation issue. The same concern does not apply to the compiler. Note that if you run the example program in this issue with |
Replace some `mem::forget`'s with `ManuallyDrop` > but I would like to see a larger effort to replace all uses of `mem::forget`. _Originally posted by `@saethlin` in rust-lang#127584 (comment) So, r? `@saethlin` Sorry, I have finished writing all of this before I got your response.
Rollup merge of rust-lang#127733 - GrigorenkoPV:don't-forget, r=Amanieu Replace some `mem::forget`'s with `ManuallyDrop` > but I would like to see a larger effort to replace all uses of `mem::forget`. _Originally posted by `@saethlin` in rust-lang#127584 (comment) So, r? `@saethlin` Sorry, I have finished writing all of this before I got your response.
Replace some `mem::forget`'s with `ManuallyDrop` > but I would like to see a larger effort to replace all uses of `mem::forget`. _Originally posted by `@saethlin` in rust-lang/rust#127584 (comment) So, r? `@saethlin` Sorry, I have finished writing all of this before I got your response.
I tried this code: [playground]
I expected to see this happen: it runs cleanly under Miri.
Instead, this happened:
The issue is in this construct:
https://github.com/rust-lang/rust/blob/master/library%2Fstd%2Fsrc%2Fio%2Fbuffered%2Fbufwriter.rs#L171-L173
By the SB model, moving a (struct directly containing)
Box
retags thatBox
as the live unique owner of the referenced allocation. Thus passingself
toforget
invalidates the duplicatedBox
(W
) we just retrieved. The correct way to write this is withManuallyDrop
:Meta
Tested against 1.81.0-nightly (2024-07-09 6be96e3).
This also catches
BufWriter::into_inner
, which is implemented usinginto_parts
.IIRC the LLVM backend is currently not informed about this instance of this UB, as the relevant attributes are only added when the argument passing ABI is
Scalar
orScalarPair
, which it is not in this case. Additionally, Miri's SB implementation does not complain when the box isBox<dyn Write>
, (conjecture: sincedyn Write
is notUnpin
).cc @RalfJung — another case of
read; forget
instead ofManuallyDrop::new; read
in std.This was randomly spotted. It might be worth it to do a grep for
forget
to try to spot further such mistakes.forget
's docs call this out as incorrect, but it's still quite easy to overlook.The text was updated successfully, but these errors were encountered: