Skip to content

move Option::as_(mut_)slice to use offset_of!, part 1 #117594

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

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@
#![feature(is_ascii_octdigit)]
#![feature(isqrt)]
#![feature(maybe_uninit_uninit_array)]
#![feature(offset_of)]
#![feature(ptr_alignment_type)]
#![feature(ptr_metadata)]
#![feature(set_ptr_value)]
Expand Down
14 changes: 12 additions & 2 deletions library/core/src/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -774,12 +774,17 @@ impl<T> Option<T> {
// just needs to be aligned, which it is because `&self` is aligned and
// the offset used is a multiple of alignment.
//
// In the new version, the intrinsic always returns a pointer to an
// In the new version, the `byte_add` always returns a pointer to an
// in-bounds and correctly aligned position for a `T` (even if in the
// `None` case it's just padding).
unsafe {
slice::from_raw_parts(
#[cfg(bootstrap)]
crate::intrinsics::option_payload_ptr(crate::ptr::from_ref(self)),
#[cfg(not(bootstrap))]
crate::ptr::from_ref(self)
.cast::<T>()
.byte_add(crate::mem::offset_of!(Self, Some.0)),
usize::from(self.is_some()),
)
}
Expand Down Expand Up @@ -828,15 +833,20 @@ impl<T> Option<T> {
// just needs to be aligned, which it is because `&self` is aligned and
// the offset used is a multiple of alignment.
//
// In the new version, the intrinsic creates a `*const T` from a
// In the new version, the `byte_add` creates a `*const T` from a
// mutable reference so it is safe to cast back to a mutable pointer
// here. As with `as_slice`, the intrinsic always returns a pointer to
// an in-bounds and correctly aligned position for a `T` (even if in
// the `None` case it's just padding).
unsafe {
slice::from_raw_parts_mut(
#[cfg(bootstrap)]
crate::intrinsics::option_payload_ptr(crate::ptr::from_mut(self).cast_const())
.cast_mut(),
#[cfg(not(bootstrap))]
crate::ptr::from_mut(self)
.cast::<T>()
.byte_add(crate::mem::offset_of!(Option<T>, Some.0)),
usize::from(self.is_some()),
)
}
Expand Down