-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Mutable reference protected by a mutex in static context is considered UB #120450
Comments
I think you're assuming the problem is in type-checking, but if that were the case this would be an entirely different error message. This error comes out of
|
I'm new to the rust compiler, so please bear with me. Is it even possible to fix the behavior I describend in the const validation? Do I have access to the information of a certain type implements Sync or not? Thanks! |
Trait bounds are not related. Looking through the tracking issue for |
Since the recent compiler version mutable references are disallowed in statics, even behind Send-Types like mutexes. I created already a bug report but I'm not sure if this is easily fixed (rust-lang/rust#120450 (comment)) Therefore, we use OnceCell in our static page allocator or the option type in our test setup.
Urgh, this is a nasty interaction. This gets rejected the way it should: static MUTABLE_REFERENCE_HOLDER: Mutex<&mut [u8]> = Mutex::new(&mut [1]);
// ERROR: error[E0716]: temporary value dropped while borrowed But with an empty slice, it gets promoted, and so there's no issue with pointing to a temporary -- and so we reach const validation, where it gets rejected as expected. We may have to adjust validity to make it so that "mutable reference to 0 bytes" is allowed. But I'm concerned that people might then unsafely turn that into a reference that covers more than 0 bytes and now we need subobject provenance to explain why their code is UB and I don't want to have subobject provenance. What we could allow is a mutable reference that doesn't point to actual memory. I don't know what exactly the internal representation of the empty slice here will be, but that should be sufficient for this specific case. |
🤔 Could we do something as restrictive as ZST promoteds?
|
This has nothing to do with The compiler is wrong though, there is nothing mutable, so I fixed the check: #121179. |
However even with that PR, we still reject this code: #![feature(const_mut_refs)]
use std::sync::Mutex;
static BAR: Mutex<&mut [u8]> = unsafe {
static mut FOO: [u8; 1] = [42]; // a private static that we are sure nobody else will reference
Mutex::new(&mut FOO)
}; Arguably there is no issue with implicitly creating mutable memory here. It's not even unsound, since we are hiding the It already passes the static checks. (Interestingly, it passes them even before #120932 landed. Turns out the local that stores the |
Rollup merge of rust-lang#121179 - RalfJung:zst-mutable-refs, r=oli-obk allow mutable references in const values when they point to no memory Fixes rust-lang#120450 The second commit is just some drive-by test suite cleanup. r? `@oli-obk`
Reopening due to my comment above. |
This reverts commit 58315b0. The mentioned compiler bug (rust-lang/rust#120450) is fixed now so we can continue to use mutable statics which doesn't point to any memory. Update rust-toolchain to the latest nightly.
I'm slowly wondering why we reject mutable allocs within immutable statics at all 😅. You can only use them mutably if they are only used via raw pointers or protected by some mutex-like guard. Even static FOO: &mut u8 = &mut 42; Is just surprising, but not actually mutable |
I think for your example I'd say it's not nice that the mutable allocation doesn't have a "name", that it just exists implicitly as a local variable in the |
The reason I'm bringing it up is that we could eliminate |
We don't allow mutable "inner" allocations in |
I think before #119044, this code actually got accepted. That PR introduced fn may_contain_mutable_ref(self) -> bool {
match self {
CtfeValidationMode::Static { mutbl } => mutbl == Mutability::Mut,
CtfeValidationMode::Promoted { .. } => false,
CtfeValidationMode::Const { .. } => false,
}
} whereas previously we only rejected mutable references in So maybe we should just change that to say |
👍
jup |
Rollup merge of rust-lang#121782 - RalfJung:mutable-ref-in-static, r=oli-obk allow statics pointing to mutable statics Fixes rust-lang#120450 for good. We can even simplify our checks: no need to specifically go looking for mutable references in const, we can just reject any reference that points to something mutable. r? `@oli-obk`
I tried this code:
I expected to see this happen: This code should compile because the mutable reference is protected by a Mutex and therefore, it is safe to access.
Instead, this happened: I receive the following compiler error:
I am not entirely sure if I'm missing something here. Is this UB or not?
Since a mutable reference to a slice of u8 is Send the mutex is Send + Sync. Therefore, I assume this should be allowed?
If this is in fact a mistake in the compiler, I'd be glad to try to provide a pull request with a fix. In my head the compiler need to look at the Sync trait and if it is implement by a type, this is not UB.
Meta
rustc --version --verbose
:The text was updated successfully, but these errors were encountered: