diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 01cadd78cc09d..53d11ebb5d621 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -174,6 +174,7 @@ #![feature(isqrt)] #![feature(lazy_get)] #![feature(link_cfg)] +#![feature(non_null_from_ref)] #![feature(offset_of_enum)] #![feature(panic_internals)] #![feature(ptr_alignment_type)] diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index daa40b3c9d2e5..44936d69bc966 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -230,6 +230,24 @@ impl NonNull { } } + /// Converts a reference to a `NonNull` pointer. + #[unstable(feature = "non_null_from_ref", issue = "130823")] + #[rustc_const_unstable(feature = "non_null_from_ref", issue = "130823")] + #[inline] + pub const fn from_ref(r: &T) -> Self { + // SAFETY: A reference cannot be null. + unsafe { NonNull { pointer: r as *const T } } + } + + /// Converts a mutable reference to a `NonNull` pointer. + #[unstable(feature = "non_null_from_ref", issue = "130823")] + #[rustc_const_unstable(feature = "non_null_from_ref", issue = "130823")] + #[inline] + pub const fn from_mut(r: &mut T) -> Self { + // SAFETY: A mutable reference cannot be null. + unsafe { NonNull { pointer: r as *mut T } } + } + /// Performs the same functionality as [`std::ptr::from_raw_parts`], except that a /// `NonNull` pointer is returned, as opposed to a raw `*const` pointer. /// @@ -1753,9 +1771,8 @@ impl From<&mut T> for NonNull { /// /// This conversion is safe and infallible since references cannot be null. #[inline] - fn from(reference: &mut T) -> Self { - // SAFETY: A mutable reference cannot be null. - unsafe { NonNull { pointer: reference as *mut T } } + fn from(r: &mut T) -> Self { + NonNull::from_mut(r) } } @@ -1765,8 +1782,7 @@ impl From<&T> for NonNull { /// /// This conversion is safe and infallible since references cannot be null. #[inline] - fn from(reference: &T) -> Self { - // SAFETY: A reference cannot be null. - unsafe { NonNull { pointer: reference as *const T } } + fn from(r: &T) -> Self { + NonNull::from_ref(r) } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir index 3aa483ed1aefa..bd56ab67e0029 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir @@ -19,30 +19,30 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { debug i => _22; debug x => _23; } - scope 17 (inlined > as Iterator>::next) { + scope 18 (inlined > as Iterator>::next) { let mut _14: &mut std::slice::Iter<'_, T>; let mut _15: std::option::Option<&T>; let mut _19: (usize, bool); let mut _20: (usize, &T); - scope 18 { + scope 19 { let _18: usize; - scope 23 { + scope 24 { } } - scope 19 { - scope 20 { - scope 26 (inlined as FromResidual>>::from_residual) { + scope 20 { + scope 21 { + scope 27 (inlined as FromResidual>>::from_residual) { } } } - scope 21 { - scope 22 { + scope 22 { + scope 23 { } } - scope 24 (inlined as Try>::branch) { + scope 25 (inlined as Try>::branch) { let mut _16: isize; let _17: &T; - scope 25 { + scope 26 { } } } @@ -59,29 +59,31 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { let _9: *const T; scope 7 { } - scope 11 (inlined without_provenance::) { + scope 12 (inlined without_provenance::) { } - scope 12 (inlined NonNull::::as_ptr) { + scope 13 (inlined NonNull::::as_ptr) { } - scope 13 (inlined std::ptr::mut_ptr::::add) { + scope 14 (inlined std::ptr::mut_ptr::::add) { } } scope 8 (inlined as From<&[T]>>::from) { - let mut _4: *const [T]; + scope 9 (inlined NonNull::<[T]>::from_ref) { + let mut _4: *const [T]; + } } - scope 9 (inlined NonNull::<[T]>::cast::) { + scope 10 (inlined NonNull::<[T]>::cast::) { let mut _5: *const T; - scope 10 (inlined NonNull::<[T]>::as_ptr) { + scope 11 (inlined NonNull::<[T]>::as_ptr) { } } } } } - scope 14 (inlined as Iterator>::enumerate) { - scope 15 (inlined Enumerate::>::new) { + scope 15 (inlined as Iterator>::enumerate) { + scope 16 (inlined Enumerate::>::new) { } } - scope 16 (inlined > as IntoIterator>::into_iter) { + scope 17 (inlined > as IntoIterator>::into_iter) { } bb0: { diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir index 4cc0aa0ed788d..57f09a4631b5d 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir @@ -34,29 +34,31 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { let _9: *const T; scope 7 { } - scope 11 (inlined without_provenance::) { + scope 12 (inlined without_provenance::) { } - scope 12 (inlined NonNull::::as_ptr) { + scope 13 (inlined NonNull::::as_ptr) { } - scope 13 (inlined std::ptr::mut_ptr::::add) { + scope 14 (inlined std::ptr::mut_ptr::::add) { } } scope 8 (inlined as From<&[T]>>::from) { - let mut _4: *const [T]; + scope 9 (inlined NonNull::<[T]>::from_ref) { + let mut _4: *const [T]; + } } - scope 9 (inlined NonNull::<[T]>::cast::) { + scope 10 (inlined NonNull::<[T]>::cast::) { let mut _5: *const T; - scope 10 (inlined NonNull::<[T]>::as_ptr) { + scope 11 (inlined NonNull::<[T]>::as_ptr) { } } } } } - scope 14 (inlined as Iterator>::enumerate) { - scope 15 (inlined Enumerate::>::new) { + scope 15 (inlined as Iterator>::enumerate) { + scope 16 (inlined Enumerate::>::new) { } } - scope 16 (inlined > as IntoIterator>::into_iter) { + scope 17 (inlined > as IntoIterator>::into_iter) { } bb0: { diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir index 507afa63c6884..4050304f46981 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir @@ -31,25 +31,27 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { let _9: *const T; scope 7 { } - scope 11 (inlined without_provenance::) { + scope 12 (inlined without_provenance::) { } - scope 12 (inlined NonNull::::as_ptr) { + scope 13 (inlined NonNull::::as_ptr) { } - scope 13 (inlined std::ptr::mut_ptr::::add) { + scope 14 (inlined std::ptr::mut_ptr::::add) { } } scope 8 (inlined as From<&[T]>>::from) { - let mut _4: *const [T]; + scope 9 (inlined NonNull::<[T]>::from_ref) { + let mut _4: *const [T]; + } } - scope 9 (inlined NonNull::<[T]>::cast::) { + scope 10 (inlined NonNull::<[T]>::cast::) { let mut _5: *const T; - scope 10 (inlined NonNull::<[T]>::as_ptr) { + scope 11 (inlined NonNull::<[T]>::as_ptr) { } } } } } - scope 14 (inlined as IntoIterator>::into_iter) { + scope 15 (inlined as IntoIterator>::into_iter) { } bb0: { diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir index a25f12edc28e9..2c3d7ab1e4a89 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir @@ -31,25 +31,27 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { let _9: *const T; scope 7 { } - scope 11 (inlined without_provenance::) { + scope 12 (inlined without_provenance::) { } - scope 12 (inlined NonNull::::as_ptr) { + scope 13 (inlined NonNull::::as_ptr) { } - scope 13 (inlined std::ptr::mut_ptr::::add) { + scope 14 (inlined std::ptr::mut_ptr::::add) { } } scope 8 (inlined as From<&[T]>>::from) { - let mut _4: *const [T]; + scope 9 (inlined NonNull::<[T]>::from_ref) { + let mut _4: *const [T]; + } } - scope 9 (inlined NonNull::<[T]>::cast::) { + scope 10 (inlined NonNull::<[T]>::cast::) { let mut _5: *const T; - scope 10 (inlined NonNull::<[T]>::as_ptr) { + scope 11 (inlined NonNull::<[T]>::as_ptr) { } } } } } - scope 14 (inlined as IntoIterator>::into_iter) { + scope 15 (inlined as IntoIterator>::into_iter) { } bb0: { diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir index 1b397a4e4cdde..a6ccd435c40eb 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir @@ -18,7 +18,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { scope 2 { debug x => _17; } - scope 17 (inlined > as Iterator>::next) { + scope 18 (inlined > as Iterator>::next) { let mut _14: &mut std::slice::Iter<'_, T>; } } @@ -34,29 +34,31 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { let _9: *const T; scope 7 { } - scope 11 (inlined without_provenance::) { + scope 12 (inlined without_provenance::) { } - scope 12 (inlined NonNull::::as_ptr) { + scope 13 (inlined NonNull::::as_ptr) { } - scope 13 (inlined std::ptr::mut_ptr::::add) { + scope 14 (inlined std::ptr::mut_ptr::::add) { } } scope 8 (inlined as From<&[T]>>::from) { - let mut _4: *const [T]; + scope 9 (inlined NonNull::<[T]>::from_ref) { + let mut _4: *const [T]; + } } - scope 9 (inlined NonNull::<[T]>::cast::) { + scope 10 (inlined NonNull::<[T]>::cast::) { let mut _5: *const T; - scope 10 (inlined NonNull::<[T]>::as_ptr) { + scope 11 (inlined NonNull::<[T]>::as_ptr) { } } } } } - scope 14 (inlined as Iterator>::rev) { - scope 15 (inlined Rev::>::new) { + scope 15 (inlined as Iterator>::rev) { + scope 16 (inlined Rev::>::new) { } } - scope 16 (inlined > as IntoIterator>::into_iter) { + scope 17 (inlined > as IntoIterator>::into_iter) { } bb0: { diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir index 77689dd9b513e..df11c8e3b4966 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir @@ -18,7 +18,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { scope 2 { debug x => _17; } - scope 17 (inlined > as Iterator>::next) { + scope 18 (inlined > as Iterator>::next) { let mut _14: &mut std::slice::Iter<'_, T>; } } @@ -34,29 +34,31 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { let _9: *const T; scope 7 { } - scope 11 (inlined without_provenance::) { + scope 12 (inlined without_provenance::) { } - scope 12 (inlined NonNull::::as_ptr) { + scope 13 (inlined NonNull::::as_ptr) { } - scope 13 (inlined std::ptr::mut_ptr::::add) { + scope 14 (inlined std::ptr::mut_ptr::::add) { } } scope 8 (inlined as From<&[T]>>::from) { - let mut _4: *const [T]; + scope 9 (inlined NonNull::<[T]>::from_ref) { + let mut _4: *const [T]; + } } - scope 9 (inlined NonNull::<[T]>::cast::) { + scope 10 (inlined NonNull::<[T]>::cast::) { let mut _5: *const T; - scope 10 (inlined NonNull::<[T]>::as_ptr) { + scope 11 (inlined NonNull::<[T]>::as_ptr) { } } } } } - scope 14 (inlined as Iterator>::rev) { - scope 15 (inlined Rev::>::new) { + scope 15 (inlined as Iterator>::rev) { + scope 16 (inlined Rev::>::new) { } } - scope 16 (inlined > as IntoIterator>::into_iter) { + scope 17 (inlined > as IntoIterator>::into_iter) { } bb0: {