Skip to content

Commit 9fed130

Browse files
committed
Auto merge of #94954 - SimonSapin:null-thin3, r=yaahc
Extend ptr::null and null_mut to all thin (including extern) types Fixes #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 #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(const_fn_trait_bound)` * Having `rustc_allow_const_fn_unstable(ptr_metadata)`
2 parents fe9c64d + 7ccc09b commit 9fed130

File tree

3 files changed

+59
-1
lines changed

3 files changed

+59
-1
lines changed

library/core/src/ptr/mod.rs

+46
Original file line numberDiff line numberDiff line change
@@ -507,10 +507,33 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
507507
#[rustc_promotable]
508508
#[rustc_const_stable(feature = "const_ptr_null", since = "1.24.0")]
509509
#[rustc_diagnostic_item = "ptr_null"]
510+
#[cfg(bootstrap)]
510511
pub const fn null<T>() -> *const T {
511512
invalid(0)
512513
}
513514

515+
/// Creates a null raw pointer.
516+
///
517+
/// # Examples
518+
///
519+
/// ```
520+
/// use std::ptr;
521+
///
522+
/// let p: *const i32 = ptr::null();
523+
/// assert!(p.is_null());
524+
/// ```
525+
#[inline(always)]
526+
#[must_use]
527+
#[stable(feature = "rust1", since = "1.0.0")]
528+
#[rustc_promotable]
529+
#[rustc_const_stable(feature = "const_ptr_null", since = "1.24.0")]
530+
#[rustc_allow_const_fn_unstable(ptr_metadata)]
531+
#[rustc_diagnostic_item = "ptr_null"]
532+
#[cfg(not(bootstrap))]
533+
pub const fn null<T: ?Sized + Thin>() -> *const T {
534+
from_raw_parts(0 as *const (), ())
535+
}
536+
514537
/// Creates a null mutable raw pointer.
515538
///
516539
/// # Examples
@@ -527,6 +550,7 @@ pub const fn null<T>() -> *const T {
527550
#[rustc_promotable]
528551
#[rustc_const_stable(feature = "const_ptr_null", since = "1.24.0")]
529552
#[rustc_diagnostic_item = "ptr_null_mut"]
553+
#[cfg(bootstrap)]
530554
pub const fn null_mut<T>() -> *mut T {
531555
invalid_mut(0)
532556
}
@@ -665,6 +689,28 @@ where
665689
addr as *mut T
666690
}
667691

692+
/// Creates a null mutable raw pointer.
693+
///
694+
/// # Examples
695+
///
696+
/// ```
697+
/// use std::ptr;
698+
///
699+
/// let p: *mut i32 = ptr::null_mut();
700+
/// assert!(p.is_null());
701+
/// ```
702+
#[inline(always)]
703+
#[must_use]
704+
#[stable(feature = "rust1", since = "1.0.0")]
705+
#[rustc_promotable]
706+
#[rustc_const_stable(feature = "const_ptr_null", since = "1.24.0")]
707+
#[rustc_allow_const_fn_unstable(ptr_metadata)]
708+
#[rustc_diagnostic_item = "ptr_null_mut"]
709+
#[cfg(not(bootstrap))]
710+
pub const fn null_mut<T: ?Sized + Thin>() -> *mut T {
711+
from_raw_parts_mut(0 as *mut (), ())
712+
}
713+
668714
/// Forms a raw slice from a pointer and a length.
669715
///
670716
/// The `len` argument is the number of **elements**, not the number of bytes.

library/core/tests/ptr.rs

+12
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,18 @@ fn test_is_null() {
9393

9494
let nmi: *mut dyn ToString = null_mut::<isize>();
9595
assert!(nmi.is_null());
96+
97+
#[cfg(not(bootstrap))]
98+
{
99+
extern "C" {
100+
type Extern;
101+
}
102+
let ec: *const Extern = null::<Extern>();
103+
assert!(ec.is_null());
104+
105+
let em: *mut Extern = null_mut::<Extern>();
106+
assert!(em.is_null());
107+
}
96108
}
97109

98110
#[test]

src/test/ui/cast/casts-issue-46365.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ struct Lorem {
33
}
44

55
fn main() {
6-
let _foo: *mut Lorem = core::ptr::null_mut(); // no error here
6+
let _foo: *mut Lorem = core::ptr::NonNull::dangling().as_ptr(); // no error here
77
}

0 commit comments

Comments
 (0)