diff options
| author | Simon Sapin <simon.sapin@exyr.org> | 2022-02-14 20:05:45 +0100 |
|---|---|---|
| committer | Simon Sapin <simon.sapin@exyr.org> | 2022-05-13 18:03:06 +0200 |
| commit | 7ccc09b210469fe598e8c829bccd83f3745b9e38 (patch) | |
| tree | 245f40054a79777e0f4bf8bb6ec7c4914a2cbc18 | |
| parent | 1c80ac003b59a2e708f127a721904e92ea51d0b9 (diff) | |
| download | rust-7ccc09b210469fe598e8c829bccd83f3745b9e38.tar.gz rust-7ccc09b210469fe598e8c829bccd83f3745b9e38.zip | |
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)`
| -rw-r--r-- | library/core/src/ptr/mod.rs | 46 | ||||
| -rw-r--r-- | library/core/tests/ptr.rs | 12 | ||||
| -rw-r--r-- | src/test/ui/cast/casts-issue-46365.rs | 2 |
3 files changed, 59 insertions, 1 deletions
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index ba8b0670147..0658ed812d1 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -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 @@ where 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. diff --git a/library/core/tests/ptr.rs b/library/core/tests/ptr.rs index 03fe56022b0..c5242ad04de 100644 --- a/library/core/tests/ptr.rs +++ b/library/core/tests/ptr.rs @@ -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] diff --git a/src/test/ui/cast/casts-issue-46365.rs b/src/test/ui/cast/casts-issue-46365.rs index 3d0fea245c0..a2205b718c1 100644 --- a/src/test/ui/cast/casts-issue-46365.rs +++ b/src/test/ui/cast/casts-issue-46365.rs @@ -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 } |
