Skip to content

Commit 33688d2

Browse files
committed
Auto merge of #117525 - GKFX:remove_option_payload_ptr, r=petrochenkov
Remove option_payload_ptr; redundant to offset_of The `option_payload_ptr` intrinsic is no longer required as `offset_of` supports traversing enums (#114208). This PR removes it in order to dogfood offset_of (as suggested at #106655 (comment)). However, it will not build until those changes reach beta (which I think is within the next 8 days?) so I've opened it as a draft.
2 parents e1e60b6 + 58ea02e commit 33688d2

File tree

11 files changed

+16
-171
lines changed

11 files changed

+16
-171
lines changed

compiler/rustc_hir_analysis/src/check/intrinsic.rs

-19
Original file line numberDiff line numberDiff line change
@@ -225,25 +225,6 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
225225
],
226226
Ty::new_ptr(tcx, ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
227227
),
228-
sym::option_payload_ptr => {
229-
let option_def_id = tcx.require_lang_item(hir::LangItem::Option, None);
230-
let p0 = param(0);
231-
(
232-
1,
233-
vec![Ty::new_ptr(
234-
tcx,
235-
ty::TypeAndMut {
236-
ty: Ty::new_adt(
237-
tcx,
238-
tcx.adt_def(option_def_id),
239-
tcx.mk_args_from_iter([ty::GenericArg::from(p0)].into_iter()),
240-
),
241-
mutbl: hir::Mutability::Not,
242-
},
243-
)],
244-
Ty::new_ptr(tcx, ty::TypeAndMut { ty: p0, mutbl: hir::Mutability::Not }),
245-
)
246-
}
247228
sym::ptr_mask => (
248229
1,
249230
vec![

compiler/rustc_mir_transform/src/lower_intrinsics.rs

-32
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use crate::MirPass;
44
use rustc_middle::mir::*;
55
use rustc_middle::ty::{self, TyCtxt};
66
use rustc_span::symbol::sym;
7-
use rustc_target::abi::{FieldIdx, VariantIdx};
87

98
pub struct LowerIntrinsics;
109

@@ -251,37 +250,6 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
251250
});
252251
terminator.kind = TerminatorKind::Goto { target };
253252
}
254-
sym::option_payload_ptr => {
255-
if let (Some(target), Some(arg)) = (*target, args[0].place()) {
256-
let ty::RawPtr(ty::TypeAndMut { ty: dest_ty, .. }) =
257-
destination.ty(local_decls, tcx).ty.kind()
258-
else {
259-
bug!();
260-
};
261-
262-
block.statements.push(Statement {
263-
source_info: terminator.source_info,
264-
kind: StatementKind::Assign(Box::new((
265-
*destination,
266-
Rvalue::AddressOf(
267-
Mutability::Not,
268-
arg.project_deeper(
269-
&[
270-
PlaceElem::Deref,
271-
PlaceElem::Downcast(
272-
Some(sym::Some),
273-
VariantIdx::from_u32(1),
274-
),
275-
PlaceElem::Field(FieldIdx::from_u32(0), *dest_ty),
276-
],
277-
tcx,
278-
),
279-
),
280-
))),
281-
});
282-
terminator.kind = TerminatorKind::Goto { target };
283-
}
284-
}
285253
sym::transmute | sym::transmute_unchecked => {
286254
let dst_ty = destination.ty(local_decls, tcx).ty;
287255
let Ok([arg]) = <[_; 1]>::try_from(std::mem::take(args)) else {

compiler/rustc_span/src/symbol.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1164,7 +1164,6 @@ symbols! {
11641164
optin_builtin_traits,
11651165
option,
11661166
option_env,
1167-
option_payload_ptr,
11681167
options,
11691168
or,
11701169
or_patterns,

library/core/src/intrinsics.rs

-6
Original file line numberDiff line numberDiff line change
@@ -2487,12 +2487,6 @@ extern "rust-intrinsic" {
24872487
where
24882488
G: FnOnce<ARG, Output = RET>,
24892489
F: FnOnce<ARG, Output = RET>;
2490-
2491-
/// This method creates a pointer to any `Some` value. If the argument is
2492-
/// `None`, an invalid within-bounds pointer (that is still acceptable for
2493-
/// constructing an empty slice) is returned.
2494-
#[rustc_nounwind]
2495-
pub fn option_payload_ptr<T>(arg: *const Option<T>) -> *const T;
24962490
}
24972491

24982492
// Some functions are defined here because they accidentally got made

library/core/src/iter/adapters/filter_map.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,11 @@ where
9797
// SAFETY: Loop conditions ensure the index is in bounds.
9898

9999
unsafe {
100-
let opt_payload_at = core::intrinsics::option_payload_ptr(&val);
100+
let opt_payload_at: *const MaybeUninit<B> = (&val as *const Option<B>)
101+
.byte_add(core::mem::offset_of!(Option<B>, Some.0))
102+
.cast();
101103
let dst = guard.array.as_mut_ptr().add(idx);
102-
crate::ptr::copy_nonoverlapping(opt_payload_at.cast(), dst, 1);
104+
crate::ptr::copy_nonoverlapping(opt_payload_at, dst, 1);
103105
crate::mem::forget(val);
104106
};
105107

library/core/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@
178178
#![feature(is_ascii_octdigit)]
179179
#![feature(isqrt)]
180180
#![feature(maybe_uninit_uninit_array)]
181+
#![feature(offset_of)]
182+
#![feature(offset_of_enum)]
181183
#![feature(ptr_alignment_type)]
182184
#![feature(ptr_metadata)]
183185
#![feature(set_ptr_value)]

library/core/src/option.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,7 @@ impl<T> Option<T> {
780780
// `None` case it's just padding).
781781
unsafe {
782782
slice::from_raw_parts(
783-
crate::intrinsics::option_payload_ptr(crate::ptr::from_ref(self)),
783+
(self as *const Self).byte_add(core::mem::offset_of!(Self, Some.0)).cast(),
784784
usize::from(self.is_some()),
785785
)
786786
}
@@ -836,8 +836,7 @@ impl<T> Option<T> {
836836
// the `None` case it's just padding).
837837
unsafe {
838838
slice::from_raw_parts_mut(
839-
crate::intrinsics::option_payload_ptr(crate::ptr::from_mut(self).cast_const())
840-
.cast_mut(),
839+
(self as *mut Self).byte_add(core::mem::offset_of!(Self, Some.0)).cast(),
841840
usize::from(self.is_some()),
842841
)
843842
}

library/core/tests/option.rs

+8
Original file line numberDiff line numberDiff line change
@@ -568,3 +568,11 @@ fn zip_unzip_roundtrip() {
568568
let a = z.unzip();
569569
assert_eq!(a, (x, y));
570570
}
571+
572+
#[test]
573+
fn as_slice() {
574+
assert_eq!(Some(42).as_slice(), &[42]);
575+
assert_eq!(Some(43).as_mut_slice(), &[43]);
576+
assert_eq!(None::<i32>.as_slice(), &[]);
577+
assert_eq!(None::<i32>.as_mut_slice(), &[]);
578+
}

tests/mir-opt/lower_intrinsics.option_payload.LowerIntrinsics.panic-abort.diff

-48
This file was deleted.

tests/mir-opt/lower_intrinsics.option_payload.LowerIntrinsics.panic-unwind.diff

-48
This file was deleted.

tests/mir-opt/lower_intrinsics.rs

-12
Original file line numberDiff line numberDiff line change
@@ -222,18 +222,6 @@ pub fn write_via_move_string(r: &mut String, v: String) {
222222

223223
pub enum Never {}
224224

225-
// EMIT_MIR lower_intrinsics.option_payload.LowerIntrinsics.diff
226-
pub fn option_payload(o: &Option<usize>, p: &Option<String>) {
227-
// CHECK-LABEL: fn option_payload(
228-
// CHECK: {{_.*}} = &raw const (((*{{_.*}}) as Some).0: usize);
229-
// CHECK: {{_.*}} = &raw const (((*{{_.*}}) as Some).0: std::string::String);
230-
231-
unsafe {
232-
let _x = core::intrinsics::option_payload_ptr(o);
233-
let _y = core::intrinsics::option_payload_ptr(p);
234-
}
235-
}
236-
237225
// EMIT_MIR lower_intrinsics.ptr_offset.LowerIntrinsics.diff
238226
pub unsafe fn ptr_offset(p: *const i32, d: isize) -> *const i32 {
239227
// CHECK-LABEL: fn ptr_offset(

0 commit comments

Comments
 (0)