add safety sections for three functions in core::mem#154665
add safety sections for three functions in core::mem#154665hxuhack wants to merge 1 commit intorust-lang:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR improves the API documentation for unsafe/legacy core::mem APIs by adding explicit # Safety sections, helping users understand the invariants required to call these functions soundly.
Changes:
- Added a
# Safetysection tomem::zeroeddescribing the “all-zero must be valid forT” requirement. - Added a
# Safetysection to deprecatedmem::uninitializedto discourage use. - Added a
# Safetysection tomem::transmute_copylisting key caller obligations.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
These safety sections are duplicating what is already said below. They also cause text that was previously not part of any section to be part of the safety section. Also would you mind disabling the option to automatically request copilot reviews in your user settings? These copilot reviews are still shown to people like me who have disabled every copilot related option that github offers. |
|
@bjorn3 I wasn't aware that Copilot had permission to provide automatic reviews for this repository. I have disabled it now. Sorry about that.
|
This comment has been minimized.
This comment has been minimized.
In the first commit, I tried to preserve the original text, although I also noticed the duplication.
I have reorganized the Safety section so that all text before the Example section is now relevant to safety. Does this version work for you? |
|
The case about |
|
As you mentioned on zulip, it seems incorrect to state that
for What would you suggest should be documented here instead as the precondition? |
|
You seem to have misunderstood what I said. "Rust's aliasing rules" refers to two different things, depending on context:
This is the same dichotomy as in my old blog post. It is a fundamental aspect of working with unsafe Rust that your model and PR do not seem to properly capture. |
|
Ok, thanks, Ralf, for the clarification. This operates at the type-system level. |
| /// | ||
| /// # Safety | ||
| /// | ||
| /// Do not use; reserved for legacy code only. |
There was a problem hiding this comment.
I don't think this should be in a safety section. The function is already deprecated (signaling it shouldn't be used).
The safety requirement here is ultimately equivalent to MaybeUninit::assume_init's, everything else here is describing that being hard to ensure without the 'initialization' phase MaybeUninit provides.
There was a problem hiding this comment.
They are different.
mem::uninitialized directly produces an invalid value, which leads to language-level UB. For example, if the value implements Drop and the program panics after creating it, the program may end up with a dropping uninitialised value during unwinding, which is UB. That is why this API has been deprecated.
MaybeUninit::assume_init is different. You can create a value of type MaybeUninit<T>, initialize it step by step, and finally call MaybeUninit::assume_init. This approach is safe even if T implements Drop and the program panics at any point during initialization.
There are many issues in the past, e.g., CVE-2019-15552, CVE-2019-15553.
That's why the doc of mem::uninitialized says "The reason for deprecation is that the function basically cannot be used correctly"
library/core/src/mem/mod.rs
Outdated
| /// * [`size_of::<Src>`][size_of] must be greater than or equal to [`size_of::<Dst>`][size_of]. | ||
| /// It is not a compile-time error if `Src` and `Dst` have different sizes, but it | ||
| /// is highly encouraged to only invoke this function where `Src` and `Dst` have the | ||
| /// same size. |
There was a problem hiding this comment.
This feels confusing to me. Half the point of using transmute_copy is when the two types don't have the same size (or at least not provably so to the compiler) -- otherwise you could just transmute in most cases.
I'm wondering if this should just defer to the Safety documentation of read_unaligned, which is what this boils down to AFAICT.
There was a problem hiding this comment.
This feels confusing to me. Half the point of using transmute_copy is when the two types don't have the same size (or at least not provably so to the compiler) -- otherwise you could just transmute in most cases.
I copied this sentence from the original documentation without modification, although I also find it odd that it highlights “highly encouraged to only invoke this function where Src and Dst have the same size.” I think we should remove this sentence.
There was a problem hiding this comment.
I also considered referring to the safety requirements of the callee, read_unaligned. However, I give up the choice for three reasons:
- The current safety requirements documented for
read_unalignedfocus on pointer validity, which is not a concern for this function.. - This function has an additional requirement regarding the sizes of
SrcandDst. - The current description of the library-level UB that may be introduced by
read_unalignedis misleading. It states that it is unsafe ifTis notCopy, which makes readers falsely think it would be safe if itTisCopy, as discussed in zulip.
|
Reminder, once the PR becomes ready for a review, use |
|
@rustbot ready |
This pull request adds Safety sections for three library APIs in the
core::memmodule:mem::uninitializedmem::zeroedmem::transmute_copyr? @Mark-Simulacrum