Extend ptr::null and null_mut to all thin (including extern) types
Fixes https://github.com/rust-lang/rust/issues/93959 This change was accepted in https://rust-lang.github.io/rfcs/2580-ptr-meta.html Note that this changes the signature of **stable** functions. The change should be backward-compatible, but it is **insta-stable** since it cannot (easily, at all?) be made available only through a `#![feature(…)]` opt-in. The RFC also proposed the same change for `NonNull::dangling`, which makes sense it terms of its signature but not in terms of its implementation. `dangling` uses `align_of()` as an address. But what `align_of()` should be for extern types or whether it should be allowed at all remains an open question. This commit depends on https://github.com/rust-lang/rust/pull/93977, which is not yet part of the bootstrap compiler. So `#[cfg]` is used to only apply the change in stage 1+. As far a I know bounds cannot be made conditional with `#[cfg]`, so the entire functions are duplicated. This is unfortunate but temporary. Since this duplication makes it less obvious in the diff, the new definitions differ in: * More permissive bounds (`Thin` instead of implied `Sized`) * Different implementation * Having `rustc_allow_const_fn_unstable(ptr_metadata)`
This commit is contained in:
parent
1c80ac003b
commit
7ccc09b210
@ -507,10 +507,33 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
|
||||
#[rustc_promotable]
|
||||
#[rustc_const_stable(feature = "const_ptr_null", since = "1.24.0")]
|
||||
#[rustc_diagnostic_item = "ptr_null"]
|
||||
#[cfg(bootstrap)]
|
||||
pub const fn null<T>() -> *const T {
|
||||
invalid(0)
|
||||
}
|
||||
|
||||
/// Creates a null raw pointer.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::ptr;
|
||||
///
|
||||
/// let p: *const i32 = ptr::null();
|
||||
/// assert!(p.is_null());
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_promotable]
|
||||
#[rustc_const_stable(feature = "const_ptr_null", since = "1.24.0")]
|
||||
#[rustc_allow_const_fn_unstable(ptr_metadata)]
|
||||
#[rustc_diagnostic_item = "ptr_null"]
|
||||
#[cfg(not(bootstrap))]
|
||||
pub const fn null<T: ?Sized + Thin>() -> *const T {
|
||||
from_raw_parts(0 as *const (), ())
|
||||
}
|
||||
|
||||
/// Creates a null mutable raw pointer.
|
||||
///
|
||||
/// # Examples
|
||||
@ -527,6 +550,7 @@ pub const fn null<T>() -> *const T {
|
||||
#[rustc_promotable]
|
||||
#[rustc_const_stable(feature = "const_ptr_null", since = "1.24.0")]
|
||||
#[rustc_diagnostic_item = "ptr_null_mut"]
|
||||
#[cfg(bootstrap)]
|
||||
pub const fn null_mut<T>() -> *mut T {
|
||||
invalid_mut(0)
|
||||
}
|
||||
@ -657,6 +681,28 @@ pub fn from_exposed_addr_mut<T>(addr: usize) -> *mut T
|
||||
addr as *mut T
|
||||
}
|
||||
|
||||
/// Creates a null mutable raw pointer.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::ptr;
|
||||
///
|
||||
/// let p: *mut i32 = ptr::null_mut();
|
||||
/// assert!(p.is_null());
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_promotable]
|
||||
#[rustc_const_stable(feature = "const_ptr_null", since = "1.24.0")]
|
||||
#[rustc_allow_const_fn_unstable(ptr_metadata)]
|
||||
#[rustc_diagnostic_item = "ptr_null_mut"]
|
||||
#[cfg(not(bootstrap))]
|
||||
pub const fn null_mut<T: ?Sized + Thin>() -> *mut T {
|
||||
from_raw_parts_mut(0 as *mut (), ())
|
||||
}
|
||||
|
||||
/// Forms a raw slice from a pointer and a length.
|
||||
///
|
||||
/// The `len` argument is the number of **elements**, not the number of bytes.
|
||||
|
@ -93,6 +93,18 @@ fn test_is_null() {
|
||||
|
||||
let nmi: *mut dyn ToString = null_mut::<isize>();
|
||||
assert!(nmi.is_null());
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
{
|
||||
extern "C" {
|
||||
type Extern;
|
||||
}
|
||||
let ec: *const Extern = null::<Extern>();
|
||||
assert!(ec.is_null());
|
||||
|
||||
let em: *mut Extern = null_mut::<Extern>();
|
||||
assert!(em.is_null());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -3,5 +3,5 @@ struct Lorem {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _foo: *mut Lorem = core::ptr::null_mut(); // no error here
|
||||
let _foo: *mut Lorem = core::ptr::NonNull::dangling().as_ptr(); // no error here
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user