From 661df4fd5572669e930ec40291e3b2ac17b63553 Mon Sep 17 00:00:00 2001 From: George Bateman Date: Thu, 2 Nov 2023 18:21:45 +0000 Subject: [PATCH 1/2] Remove option_payload_ptr; redundant to offset_of --- .../rustc_hir_analysis/src/check/intrinsic.rs | 19 -------- .../src/lower_intrinsics.rs | 32 ------------- compiler/rustc_span/src/symbol.rs | 1 - library/core/src/intrinsics.rs | 6 --- library/core/src/iter/adapters/filter_map.rs | 3 +- library/core/src/lib.rs | 2 + library/core/src/option.rs | 5 +- library/core/tests/option.rs | 8 ++++ ...n_payload.LowerIntrinsics.panic-abort.diff | 48 ------------------- ..._payload.LowerIntrinsics.panic-unwind.diff | 48 ------------------- tests/mir-opt/lower_intrinsics.rs | 12 ----- 11 files changed, 14 insertions(+), 170 deletions(-) delete mode 100644 tests/mir-opt/lower_intrinsics.option_payload.LowerIntrinsics.panic-abort.diff delete mode 100644 tests/mir-opt/lower_intrinsics.option_payload.LowerIntrinsics.panic-unwind.diff diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index eb009b9368f..7ea21b24fc8 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -225,25 +225,6 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { ], Ty::new_ptr(tcx, ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }), ), - sym::option_payload_ptr => { - let option_def_id = tcx.require_lang_item(hir::LangItem::Option, None); - let p0 = param(0); - ( - 1, - vec![Ty::new_ptr( - tcx, - ty::TypeAndMut { - ty: Ty::new_adt( - tcx, - tcx.adt_def(option_def_id), - tcx.mk_args_from_iter([ty::GenericArg::from(p0)].into_iter()), - ), - mutbl: hir::Mutability::Not, - }, - )], - Ty::new_ptr(tcx, ty::TypeAndMut { ty: p0, mutbl: hir::Mutability::Not }), - ) - } sym::ptr_mask => ( 1, vec![ diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index 5f3d8dfc6c4..249e0fc633e 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -4,7 +4,6 @@ use crate::MirPass; use rustc_middle::mir::*; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::symbol::sym; -use rustc_target::abi::{FieldIdx, VariantIdx}; pub struct LowerIntrinsics; @@ -251,37 +250,6 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { }); terminator.kind = TerminatorKind::Goto { target }; } - sym::option_payload_ptr => { - if let (Some(target), Some(arg)) = (*target, args[0].place()) { - let ty::RawPtr(ty::TypeAndMut { ty: dest_ty, .. }) = - destination.ty(local_decls, tcx).ty.kind() - else { - bug!(); - }; - - block.statements.push(Statement { - source_info: terminator.source_info, - kind: StatementKind::Assign(Box::new(( - *destination, - Rvalue::AddressOf( - Mutability::Not, - arg.project_deeper( - &[ - PlaceElem::Deref, - PlaceElem::Downcast( - Some(sym::Some), - VariantIdx::from_u32(1), - ), - PlaceElem::Field(FieldIdx::from_u32(0), *dest_ty), - ], - tcx, - ), - ), - ))), - }); - terminator.kind = TerminatorKind::Goto { target }; - } - } sym::transmute | sym::transmute_unchecked => { let dst_ty = destination.ty(local_decls, tcx).ty; let Ok([arg]) = <[_; 1]>::try_from(std::mem::take(args)) else { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 302be85a429..2e3b5446405 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1164,7 +1164,6 @@ symbols! { optin_builtin_traits, option, option_env, - option_payload_ptr, options, or, or_patterns, diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index c5aef67b5df..f25ca9e2b18 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2487,12 +2487,6 @@ extern "rust-intrinsic" { where G: FnOnce, F: FnOnce; - - /// This method creates a pointer to any `Some` value. If the argument is - /// `None`, an invalid within-bounds pointer (that is still acceptable for - /// constructing an empty slice) is returned. - #[rustc_nounwind] - pub fn option_payload_ptr(arg: *const Option) -> *const T; } // Some functions are defined here because they accidentally got made diff --git a/library/core/src/iter/adapters/filter_map.rs b/library/core/src/iter/adapters/filter_map.rs index 693479977db..fbff53e43bb 100644 --- a/library/core/src/iter/adapters/filter_map.rs +++ b/library/core/src/iter/adapters/filter_map.rs @@ -97,7 +97,8 @@ where // SAFETY: Loop conditions ensure the index is in bounds. unsafe { - let opt_payload_at = core::intrinsics::option_payload_ptr(&val); + let opt_payload_at = + (&val as *const Option).byte_add(core::mem::offset_of!(Option, Some.0)); let dst = guard.array.as_mut_ptr().add(idx); crate::ptr::copy_nonoverlapping(opt_payload_at.cast(), dst, 1); crate::mem::forget(val); diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 4c6d5df389c..4eab746e28b 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -178,6 +178,8 @@ #![feature(is_ascii_octdigit)] #![feature(isqrt)] #![feature(maybe_uninit_uninit_array)] +#![feature(offset_of)] +#![feature(offset_of_enum)] #![feature(ptr_alignment_type)] #![feature(ptr_metadata)] #![feature(set_ptr_value)] diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 4ddcc49c989..4f644ea4eca 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -779,7 +779,7 @@ impl Option { // `None` case it's just padding). unsafe { slice::from_raw_parts( - crate::intrinsics::option_payload_ptr(crate::ptr::from_ref(self)), + (self as *const Self).byte_add(core::mem::offset_of!(Self, Some.0)).cast(), usize::from(self.is_some()), ) } @@ -835,8 +835,7 @@ impl Option { // the `None` case it's just padding). unsafe { slice::from_raw_parts_mut( - crate::intrinsics::option_payload_ptr(crate::ptr::from_mut(self).cast_const()) - .cast_mut(), + (self as *mut Self).byte_add(core::mem::offset_of!(Self, Some.0)).cast(), usize::from(self.is_some()), ) } diff --git a/library/core/tests/option.rs b/library/core/tests/option.rs index 5defeb50d40..5dc012bab4a 100644 --- a/library/core/tests/option.rs +++ b/library/core/tests/option.rs @@ -568,3 +568,11 @@ fn zip_unzip_roundtrip() { let a = z.unzip(); assert_eq!(a, (x, y)); } + +#[test] +fn as_slice() { + assert_eq!(Some(42).as_slice(), &[42]); + assert_eq!(Some(43).as_mut_slice(), &[43]); + assert_eq!(None::.as_slice(), &[]); + assert_eq!(None::.as_mut_slice(), &[]); +} diff --git a/tests/mir-opt/lower_intrinsics.option_payload.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.option_payload.LowerIntrinsics.panic-abort.diff deleted file mode 100644 index 194478560e9..00000000000 --- a/tests/mir-opt/lower_intrinsics.option_payload.LowerIntrinsics.panic-abort.diff +++ /dev/null @@ -1,48 +0,0 @@ -- // MIR for `option_payload` before LowerIntrinsics -+ // MIR for `option_payload` after LowerIntrinsics - - fn option_payload(_1: &Option, _2: &Option) -> () { - debug o => _1; - debug p => _2; - let mut _0: (); - let mut _4: *const std::option::Option; - let mut _6: *const std::option::Option; - scope 1 { - let _3: *const usize; - scope 2 { - debug _x => _3; - let _5: *const std::string::String; - scope 3 { - debug _y => _5; - } - } - } - - bb0: { - StorageLive(_3); - StorageLive(_4); - _4 = &raw const (*_1); -- _3 = option_payload_ptr::(move _4) -> [return: bb1, unwind unreachable]; -+ _3 = &raw const (((*_4) as Some).0: usize); -+ goto -> bb1; - } - - bb1: { - StorageDead(_4); - StorageLive(_5); - StorageLive(_6); - _6 = &raw const (*_2); -- _5 = option_payload_ptr::(move _6) -> [return: bb2, unwind unreachable]; -+ _5 = &raw const (((*_6) as Some).0: std::string::String); -+ goto -> bb2; - } - - bb2: { - StorageDead(_6); - _0 = const (); - StorageDead(_5); - StorageDead(_3); - return; - } - } - diff --git a/tests/mir-opt/lower_intrinsics.option_payload.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.option_payload.LowerIntrinsics.panic-unwind.diff deleted file mode 100644 index 194478560e9..00000000000 --- a/tests/mir-opt/lower_intrinsics.option_payload.LowerIntrinsics.panic-unwind.diff +++ /dev/null @@ -1,48 +0,0 @@ -- // MIR for `option_payload` before LowerIntrinsics -+ // MIR for `option_payload` after LowerIntrinsics - - fn option_payload(_1: &Option, _2: &Option) -> () { - debug o => _1; - debug p => _2; - let mut _0: (); - let mut _4: *const std::option::Option; - let mut _6: *const std::option::Option; - scope 1 { - let _3: *const usize; - scope 2 { - debug _x => _3; - let _5: *const std::string::String; - scope 3 { - debug _y => _5; - } - } - } - - bb0: { - StorageLive(_3); - StorageLive(_4); - _4 = &raw const (*_1); -- _3 = option_payload_ptr::(move _4) -> [return: bb1, unwind unreachable]; -+ _3 = &raw const (((*_4) as Some).0: usize); -+ goto -> bb1; - } - - bb1: { - StorageDead(_4); - StorageLive(_5); - StorageLive(_6); - _6 = &raw const (*_2); -- _5 = option_payload_ptr::(move _6) -> [return: bb2, unwind unreachable]; -+ _5 = &raw const (((*_6) as Some).0: std::string::String); -+ goto -> bb2; - } - - bb2: { - StorageDead(_6); - _0 = const (); - StorageDead(_5); - StorageDead(_3); - return; - } - } - diff --git a/tests/mir-opt/lower_intrinsics.rs b/tests/mir-opt/lower_intrinsics.rs index 913605cc2b2..cba2bc18d86 100644 --- a/tests/mir-opt/lower_intrinsics.rs +++ b/tests/mir-opt/lower_intrinsics.rs @@ -222,18 +222,6 @@ pub fn write_via_move_string(r: &mut String, v: String) { pub enum Never {} -// EMIT_MIR lower_intrinsics.option_payload.LowerIntrinsics.diff -pub fn option_payload(o: &Option, p: &Option) { - // CHECK-LABEL: fn option_payload( - // CHECK: {{_.*}} = &raw const (((*{{_.*}}) as Some).0: usize); - // CHECK: {{_.*}} = &raw const (((*{{_.*}}) as Some).0: std::string::String); - - unsafe { - let _x = core::intrinsics::option_payload_ptr(o); - let _y = core::intrinsics::option_payload_ptr(p); - } -} - // EMIT_MIR lower_intrinsics.ptr_offset.LowerIntrinsics.diff pub unsafe fn ptr_offset(p: *const i32, d: isize) -> *const i32 { // CHECK-LABEL: fn ptr_offset( From 58ea02e872f101717d9e2e3dfb308b4897c9c904 Mon Sep 17 00:00:00 2001 From: George Bateman Date: Sat, 18 Nov 2023 10:50:47 +0000 Subject: [PATCH 2/2] Update based on petrochenkov's review --- library/core/src/iter/adapters/filter_map.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/library/core/src/iter/adapters/filter_map.rs b/library/core/src/iter/adapters/filter_map.rs index fbff53e43bb..32308c84d71 100644 --- a/library/core/src/iter/adapters/filter_map.rs +++ b/library/core/src/iter/adapters/filter_map.rs @@ -97,10 +97,11 @@ where // SAFETY: Loop conditions ensure the index is in bounds. unsafe { - let opt_payload_at = - (&val as *const Option).byte_add(core::mem::offset_of!(Option, Some.0)); + let opt_payload_at: *const MaybeUninit = (&val as *const Option) + .byte_add(core::mem::offset_of!(Option, Some.0)) + .cast(); let dst = guard.array.as_mut_ptr().add(idx); - crate::ptr::copy_nonoverlapping(opt_payload_at.cast(), dst, 1); + crate::ptr::copy_nonoverlapping(opt_payload_at, dst, 1); crate::mem::forget(val); };