-
Notifications
You must be signed in to change notification settings - Fork 110
Implement FromZeroes for thin raw pointers #294
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Closed
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -945,6 +945,40 @@ safety_comment! { | |
unsafe_impl!(T: ?Sized + Unaligned => Unaligned for ManuallyDrop<T>); | ||
assert_unaligned!(ManuallyDrop<()>, ManuallyDrop<u8>); | ||
} | ||
safety_comment! { | ||
/// SAFETY: | ||
/// The all-zeroes const and mut raw pointers are valid, and it is sound to | ||
/// materialize them from nothing. The existence of `ptr::null` [1] and | ||
/// `ptr::null_mut` [2], which are safe functions, guarantees this (if this | ||
/// were not sound, these functions could not exist). Unlike non-null | ||
/// pointers, it is always unsound to dereference null pointers, and so it's | ||
/// not a footgun that converting from zeroes may not preserve pointer | ||
/// provenance information. | ||
/// | ||
/// Since the encoding of fat pointers is not currently defined by the | ||
/// reference, it would not be sound to implement `FromZeroes` for fat | ||
/// pointer types such `*const T` for `T: ?Sized` or even for more | ||
/// constrained pointer types such as `*const [T]` for `T: Sized`. | ||
/// | ||
/// Currently, though it would likely be sound, we choose not to implement | ||
/// `FromBytes` or `AsBytes` for raw pointers because it would be easy for | ||
/// code to mistakenly assume that converting from a raw pointer to a | ||
/// different representation (such as a byte array) and back again via | ||
/// `FromBytes` and `AsBytes` would result in a semantically identical | ||
/// pointer. Thanks to provenance information, that may not actually be | ||
/// true, so this would present a serious footgun. Note that this aspect of | ||
/// Rust's memory model is still up in the air, so it's possible that these | ||
/// conversions will one day be determined to be sound, at which point we | ||
/// could choose to support these impls. See #170 for more information. | ||
/// | ||
/// [1] https://doc.rust-lang.org/core/ptr/fn.null.html | ||
/// [2] https://doc.rust-lang.org/core/ptr/fn.null_mut.html | ||
// TODO(https://github.com/rust-lang/reference/pull/1392#issuecomment-1696768191): | ||
// Once the validity of materializing null pointers is guaranteed in the | ||
// reference, cite that instead of `null` and `null_mut`. | ||
unsafe_impl!(T: Sized => FromZeroes for *const T); | ||
unsafe_impl!(T: Sized => FromZeroes for *mut T); | ||
Comment on lines
+979
to
+980
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This snippet from the internals of the standard library gives me pause: pub const fn invalid<T>(addr: usize) -> *const T {
// FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
// We use transmute rather than a cast so tools like Miri can tell that this
// is *not* the same as from_exposed_addr.
// SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that
// pointer).
unsafe { mem::transmute(addr) }
} The use of |
||
} | ||
safety_comment! { | ||
/// SAFETY: | ||
/// Per the reference [1]: | ||
|
@@ -3983,6 +4017,9 @@ mod tests { | |
assert_impls!(Unalign<u8>: FromZeroes, FromBytes, AsBytes, Unaligned); | ||
assert_impls!(Unalign<NotZerocopy>: Unaligned, !FromZeroes, !FromBytes, !AsBytes); | ||
|
||
assert_impls!(*const NotZerocopy: FromZeroes, !FromBytes, !AsBytes, !Unaligned); | ||
assert_impls!(*mut NotZerocopy: FromZeroes, !FromBytes, !AsBytes, !Unaligned); | ||
|
||
assert_impls!([u8]: FromZeroes, FromBytes, AsBytes, Unaligned); | ||
assert_impls!([NotZerocopy]: !FromZeroes, !FromBytes, !AsBytes, !Unaligned); | ||
assert_impls!([u8; 0]: FromZeroes, FromBytes, AsBytes, Unaligned); | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Is it clearly documented anywhere that
0
is a valid value for the null pointer? Infamously, the C standard does not require that null pointers have an all-zero bit-pattern, only that they compare as equal to0
.