-
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
Document unsafety in core::ptr #71507
Document unsafety in core::ptr #71507
Conversation
Changed raw pointer name from ptr to raw_pointer to avoid confusion with the `use std::ptr` statement a few lines above. This way the crate name and pointer name are well differenciated.
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @steveklabnik (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left you some comments :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left other remarks I'm not completely sure about.
I think we should also ping someone from the Libs team, cc @Mark-Simulacrum do you have time for (yet another) review?
src/libcore/ptr/non_null.rs
Outdated
@@ -69,6 +67,8 @@ impl<T: Sized> NonNull<T> { | |||
#[rustc_const_stable(feature = "const_nonnull_dangling", since = "1.32.0")] | |||
#[inline] | |||
pub const fn dangling() -> Self { | |||
// SAFETY: mem::align_of() returns a valid, non-null pointer. The |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure it would be right to call the pointer returned by mem::align_of
"valid". It is still dangling.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good point. I thought of "valid" as in "non-null" and "usable", but it is in fact dangling and dangerous. We could simply put non-null and remove the "valid" to avoid confusion
// SAFETY: mem::align_of() returns a valid, non-null pointer. The | |
// SAFETY: mem::align_of() returns a non-null pointer. The |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for all your comments by the way @LeSeulArtichaut
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No problem! I've got some spare time, being locked down at home :P
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mem::align_of
doesn't return a pointer, it returns a usize
. By casting it to a pointer, you are creating the lowest non-zero *mut T
that is properly aligned.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ecstatic-morse Changed in 75a73d1
@@ -213,6 +221,8 @@ impl<T: ?Sized> From<Unique<T>> for NonNull<T> { | |||
impl<T: ?Sized> From<&mut T> for NonNull<T> { | |||
#[inline] | |||
fn from(reference: &mut T) -> Self { | |||
// SAFETY: A mutable reference cannot be null, so the conditions for | |||
// new_unchecked() are respected. | |||
unsafe { NonNull { pointer: reference as *mut T } } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You refer to new_unchecked
in the SAFETY
comment, but it's not what's called here. We should always be using new_unchecked
to create NonNull
s, even internally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ecstatic-morse Do you think I should add it to this PR ? I feel like changing the code is a bit outside of its scope. I'm changing the SAFETY
comment
src/libcore/ptr/unique.rs
Outdated
@@ -176,6 +181,7 @@ impl<T: ?Sized> From<&mut T> for Unique<T> { | |||
impl<T: ?Sized> From<&T> for Unique<T> { | |||
#[inline] | |||
fn from(reference: &T) -> Self { | |||
// SAFETY: A reference cannot be null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understanding is that Unique
guarantees that its referent is not aliased. This is not guaranteed by &T
, so I think this From
impl is unsound. Presumably we justify this because it only becomes UB when we actually create a &mut
from a Unique
, which is unsafe
. cc @rust-lang/libs
It's important to state why all invariants are upheld when annotating these unsafe
blocks, not just the one about null pointers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@RalfJung I think mentioned recently that while Unique perhaps should provide that guarantee, it does not today.
I agree though that this impl seems very suspicious -- I believe Unique is std-internal today, so we can probably drop this impl?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the docs for Unique::new_unchecked
, it is only stated that the pointer must be non-null
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don’t believe Unique
has such a language-level guarantee.
What if we just removed it? #71530
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don’t believe Unique has such a language-level guarantee.
It doesn't right now mostly because we don't know how to exactly phrase the guarantee.
I agree that an instance turning a shared reference into Unique
sounds wrong, and should be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The instance was added in #42959. Not sure why noone complained back then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is outside the scope of this pull request, which aims at commenting some unsafe blocks. I removed it.
rust-lang#71507 (comment) discusses whether `Unique` not actually being unique is UB. `Unique` has very limited use over `NonNull`, so it doesn’t seem worth spending a lot of effort defining an abstraction and coming up with rules about what uses of it are or aren’t sound.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I cannot really review for correctness, but formatting and such looks good to me.
Thanks! Can you squash this down to one commit? With that I think we'll be ready to go. |
33c4981
to
8558ccd
Compare
@Mark-Simulacrum Thanks, I squashed it |
Add documentation example to slice_from_raw_parts_mut() Add SAFETY explanations to some unsafe blocks in libcore/ptr * libcore/ptr/mod.rs * libcore/ptr/unique.rs * libcore/ptr/non_null.rs safety-mod.rs: Add SAFETY to slice_from_raw_parts(), slice_from_raw_parts_mut() slice_from_raw_parts_mut: Add documentation example safety-ptr-unique.rs: Add SAFETY to new() and cast() safety-ptr-non_null.rs: Add SAFETY to new() safety-ptr-non_null.rs: Add SAFETY to cast() safety-ptr-non_null.rs: Add SAFETY to from() impls safety-ptr-unique.rs: Add SAFETY to from() impls safety-ptr-non_null.rs: Add SAFETY to new() safety-ptr-unique.rs: Add SAFETY to new() safety-ptr-mod.rs: Fix safety explanation rust-lang#71507 (comment) safety-prt-non_null.rs: Fix SAFETY comment syntax safety-ptr-unique.rs: Fix syntax for empty() safety-ptr-non_null.rs: Fix misuse of non-null for align_of() safety-ptr-non_null.rs: Remove incorrect SAFETY comment safety-ptr-unique.rs: Remove unsound SAFETY comment safety-ptr-mod.rs: Add std comment on slice_from_raw_parts guarantee safety-ptr-unique.rs: Remove incorrect safety comment Creating a Unique from a NonNull has strict guarantees that the current implementation does not guarantee rust-lang#71507 (comment) safety-ptr: Re-adding ignore-tidy directive
@bors r+ rollup |
📌 Commit 8558ccd has been approved by |
…-ptr, r=Mark-Simulacrum Document unsafety in core::ptr Contributes to rust-lang#66219 I have yet to document all the `unsafe` blocks in the lib and would like to know if I'm headed in the right direction r? @steveklabnik
Rollup of 6 pull requests Successful merges: - rust-lang#71507 (Document unsafety in core::ptr) - rust-lang#71572 (test iterator chain type length blowup) - rust-lang#71617 (Suggest `into` instead of `try_into` if possible with int types) - rust-lang#71627 (Fix wrong argument in autoderef process) - rust-lang#71678 (Add an index page for nightly rustc docs.) - rust-lang#71680 (Fix doc link to Eq trait from PartialEq trait) Failed merges: - rust-lang#71597 (Rename Unique::empty() -> Unique::dangling()) r? @ghost
Contributes to #66219
I have yet to document all the
unsafe
blocks in the lib and would like to know if I'm headed in the right directionr? @steveklabnik