Rollup merge of #130822 - bjoernager:non-null-from-ref, r=dtolnay

Add `from_ref` and `from_mut` constructors to `core::ptr::NonNull`.

Relevant tracking issue: #130823

The `core::ptr::NonNull` type should have the convenience constructors `from_ref` and `from_mut` for parity with `core::ptr::from_ref` and `core::ptr::from_mut`.

Although the type in question already implements `From<&T>` and `From<&mut T>`, these new functions also carry the ability to be used in constant expressions (due to not being behind a trait).
This commit is contained in:
Matthias Krüger 2024-10-16 19:18:30 +02:00 committed by GitHub
commit 1817de609b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 97 additions and 68 deletions

View File

@ -153,6 +153,7 @@
#![feature(isqrt)] #![feature(isqrt)]
#![feature(lazy_get)] #![feature(lazy_get)]
#![feature(link_cfg)] #![feature(link_cfg)]
#![feature(non_null_from_ref)]
#![feature(offset_of_enum)] #![feature(offset_of_enum)]
#![feature(panic_internals)] #![feature(panic_internals)]
#![feature(ptr_alignment_type)] #![feature(ptr_alignment_type)]

View File

@ -230,6 +230,24 @@ impl<T: ?Sized> NonNull<T> {
} }
} }
/// 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 /// Performs the same functionality as [`std::ptr::from_raw_parts`], except that a
/// `NonNull` pointer is returned, as opposed to a raw `*const` pointer. /// `NonNull` pointer is returned, as opposed to a raw `*const` pointer.
/// ///
@ -1753,9 +1771,8 @@ impl<T: ?Sized> From<&mut T> for NonNull<T> {
/// ///
/// This conversion is safe and infallible since references cannot be null. /// This conversion is safe and infallible since references cannot be null.
#[inline] #[inline]
fn from(reference: &mut T) -> Self { fn from(r: &mut T) -> Self {
// SAFETY: A mutable reference cannot be null. NonNull::from_mut(r)
unsafe { NonNull { pointer: reference as *mut T } }
} }
} }
@ -1765,8 +1782,7 @@ impl<T: ?Sized> From<&T> for NonNull<T> {
/// ///
/// This conversion is safe and infallible since references cannot be null. /// This conversion is safe and infallible since references cannot be null.
#[inline] #[inline]
fn from(reference: &T) -> Self { fn from(r: &T) -> Self {
// SAFETY: A reference cannot be null. NonNull::from_ref(r)
unsafe { NonNull { pointer: reference as *const T } }
} }
} }

View File

@ -19,30 +19,30 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
debug i => _22; debug i => _22;
debug x => _23; debug x => _23;
} }
scope 17 (inlined <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next) { scope 18 (inlined <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next) {
let mut _14: &mut std::slice::Iter<'_, T>; let mut _14: &mut std::slice::Iter<'_, T>;
let mut _15: std::option::Option<&T>; let mut _15: std::option::Option<&T>;
let mut _19: (usize, bool); let mut _19: (usize, bool);
let mut _20: (usize, &T); let mut _20: (usize, &T);
scope 18 { scope 19 {
let _18: usize; let _18: usize;
scope 23 { scope 24 {
} }
} }
scope 19 { scope 20 {
scope 20 { scope 21 {
scope 26 (inlined <Option<(usize, &T)> as FromResidual<Option<Infallible>>>::from_residual) { scope 27 (inlined <Option<(usize, &T)> as FromResidual<Option<Infallible>>>::from_residual) {
} }
} }
} }
scope 21 { scope 22 {
scope 22 { scope 23 {
} }
} }
scope 24 (inlined <Option<&T> as Try>::branch) { scope 25 (inlined <Option<&T> as Try>::branch) {
let mut _16: isize; let mut _16: isize;
let _17: &T; 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; let _9: *const T;
scope 7 { scope 7 {
} }
scope 11 (inlined without_provenance::<T>) { scope 12 (inlined without_provenance::<T>) {
} }
scope 12 (inlined NonNull::<T>::as_ptr) { scope 13 (inlined NonNull::<T>::as_ptr) {
} }
scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) { scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
} }
} }
scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) { scope 8 (inlined <NonNull<[T]> 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::<T>) { scope 10 (inlined NonNull::<[T]>::cast::<T>) {
let mut _5: *const T; let mut _5: *const T;
scope 10 (inlined NonNull::<[T]>::as_ptr) { scope 11 (inlined NonNull::<[T]>::as_ptr) {
} }
} }
} }
} }
} }
scope 14 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) { scope 15 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
scope 15 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) { scope 16 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
} }
} }
scope 16 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) { scope 17 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
} }
bb0: { bb0: {

View File

@ -34,29 +34,31 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
let _9: *const T; let _9: *const T;
scope 7 { scope 7 {
} }
scope 11 (inlined without_provenance::<T>) { scope 12 (inlined without_provenance::<T>) {
} }
scope 12 (inlined NonNull::<T>::as_ptr) { scope 13 (inlined NonNull::<T>::as_ptr) {
} }
scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) { scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
} }
} }
scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) { scope 8 (inlined <NonNull<[T]> 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::<T>) { scope 10 (inlined NonNull::<[T]>::cast::<T>) {
let mut _5: *const T; let mut _5: *const T;
scope 10 (inlined NonNull::<[T]>::as_ptr) { scope 11 (inlined NonNull::<[T]>::as_ptr) {
} }
} }
} }
} }
} }
scope 14 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) { scope 15 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
scope 15 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) { scope 16 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
} }
} }
scope 16 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) { scope 17 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
} }
bb0: { bb0: {

View File

@ -31,25 +31,27 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
let _9: *const T; let _9: *const T;
scope 7 { scope 7 {
} }
scope 11 (inlined without_provenance::<T>) { scope 12 (inlined without_provenance::<T>) {
} }
scope 12 (inlined NonNull::<T>::as_ptr) { scope 13 (inlined NonNull::<T>::as_ptr) {
} }
scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) { scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
} }
} }
scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) { scope 8 (inlined <NonNull<[T]> 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::<T>) { scope 10 (inlined NonNull::<[T]>::cast::<T>) {
let mut _5: *const T; let mut _5: *const T;
scope 10 (inlined NonNull::<[T]>::as_ptr) { scope 11 (inlined NonNull::<[T]>::as_ptr) {
} }
} }
} }
} }
} }
scope 14 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) { scope 15 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
} }
bb0: { bb0: {

View File

@ -31,25 +31,27 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
let _9: *const T; let _9: *const T;
scope 7 { scope 7 {
} }
scope 11 (inlined without_provenance::<T>) { scope 12 (inlined without_provenance::<T>) {
} }
scope 12 (inlined NonNull::<T>::as_ptr) { scope 13 (inlined NonNull::<T>::as_ptr) {
} }
scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) { scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
} }
} }
scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) { scope 8 (inlined <NonNull<[T]> 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::<T>) { scope 10 (inlined NonNull::<[T]>::cast::<T>) {
let mut _5: *const T; let mut _5: *const T;
scope 10 (inlined NonNull::<[T]>::as_ptr) { scope 11 (inlined NonNull::<[T]>::as_ptr) {
} }
} }
} }
} }
} }
scope 14 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) { scope 15 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
} }
bb0: { bb0: {

View File

@ -18,7 +18,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
scope 2 { scope 2 {
debug x => _17; debug x => _17;
} }
scope 17 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) { scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
let mut _14: &mut std::slice::Iter<'_, T>; 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; let _9: *const T;
scope 7 { scope 7 {
} }
scope 11 (inlined without_provenance::<T>) { scope 12 (inlined without_provenance::<T>) {
} }
scope 12 (inlined NonNull::<T>::as_ptr) { scope 13 (inlined NonNull::<T>::as_ptr) {
} }
scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) { scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
} }
} }
scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) { scope 8 (inlined <NonNull<[T]> 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::<T>) { scope 10 (inlined NonNull::<[T]>::cast::<T>) {
let mut _5: *const T; let mut _5: *const T;
scope 10 (inlined NonNull::<[T]>::as_ptr) { scope 11 (inlined NonNull::<[T]>::as_ptr) {
} }
} }
} }
} }
} }
scope 14 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) { scope 15 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
scope 15 (inlined Rev::<std::slice::Iter<'_, T>>::new) { scope 16 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
} }
} }
scope 16 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) { scope 17 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
} }
bb0: { bb0: {

View File

@ -18,7 +18,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
scope 2 { scope 2 {
debug x => _17; debug x => _17;
} }
scope 17 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) { scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
let mut _14: &mut std::slice::Iter<'_, T>; 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; let _9: *const T;
scope 7 { scope 7 {
} }
scope 11 (inlined without_provenance::<T>) { scope 12 (inlined without_provenance::<T>) {
} }
scope 12 (inlined NonNull::<T>::as_ptr) { scope 13 (inlined NonNull::<T>::as_ptr) {
} }
scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) { scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
} }
} }
scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) { scope 8 (inlined <NonNull<[T]> 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::<T>) { scope 10 (inlined NonNull::<[T]>::cast::<T>) {
let mut _5: *const T; let mut _5: *const T;
scope 10 (inlined NonNull::<[T]>::as_ptr) { scope 11 (inlined NonNull::<[T]>::as_ptr) {
} }
} }
} }
} }
} }
scope 14 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) { scope 15 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
scope 15 (inlined Rev::<std::slice::Iter<'_, T>>::new) { scope 16 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
} }
} }
scope 16 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) { scope 17 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
} }
bb0: { bb0: {