Skip to content

Commit e4eff6a

Browse files
authored
Rollup merge of rust-lang#133116 - RalfJung:const-null-ptr, r=dtolnay
stabilize const_ptr_is_null FCP passed in rust-lang#74939. The second commit cleans up const stability around UB checks a bit, now that everything they need (except for `const_eval_select`) is stable. Fixes rust-lang#74939
2 parents 1e4a9ee + e4fb962 commit e4eff6a

File tree

7 files changed

+36
-33
lines changed

7 files changed

+36
-33
lines changed

core/src/intrinsics/mod.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -3292,8 +3292,8 @@ pub const unsafe fn ptr_offset_from_unsigned<T>(_ptr: *const T, _base: *const T)
32923292

32933293
/// See documentation of `<*const T>::guaranteed_eq` for details.
32943294
/// Returns `2` if the result is unknown.
3295-
/// Returns `1` if the pointers are guaranteed equal
3296-
/// Returns `0` if the pointers are guaranteed inequal
3295+
/// Returns `1` if the pointers are guaranteed equal.
3296+
/// Returns `0` if the pointers are guaranteed inequal.
32973297
#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020"))]
32983298
#[rustc_intrinsic]
32993299
#[rustc_nounwind]
@@ -4014,9 +4014,9 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us
40144014
count: usize = count,
40154015
) => {
40164016
let zero_size = count == 0 || size == 0;
4017-
ub_checks::is_aligned_and_not_null(src, align, zero_size)
4018-
&& ub_checks::is_aligned_and_not_null(dst, align, zero_size)
4019-
&& ub_checks::is_nonoverlapping(src, dst, size, count)
4017+
ub_checks::maybe_is_aligned_and_not_null(src, align, zero_size)
4018+
&& ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size)
4019+
&& ub_checks::maybe_is_nonoverlapping(src, dst, size, count)
40204020
}
40214021
);
40224022

@@ -4120,8 +4120,8 @@ pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
41204120
align: usize = align_of::<T>(),
41214121
zero_size: bool = T::IS_ZST || count == 0,
41224122
) =>
4123-
ub_checks::is_aligned_and_not_null(src, align, zero_size)
4124-
&& ub_checks::is_aligned_and_not_null(dst, align, zero_size)
4123+
ub_checks::maybe_is_aligned_and_not_null(src, align, zero_size)
4124+
&& ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size)
41254125
);
41264126
copy(src, dst, count)
41274127
}
@@ -4202,7 +4202,7 @@ pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
42024202
addr: *const () = dst as *const (),
42034203
align: usize = align_of::<T>(),
42044204
zero_size: bool = T::IS_ZST || count == 0,
4205-
) => ub_checks::is_aligned_and_not_null(addr, align, zero_size)
4205+
) => ub_checks::maybe_is_aligned_and_not_null(addr, align, zero_size)
42064206
);
42074207
write_bytes(dst, val, count)
42084208
}

core/src/lib.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
// tidy-alphabetical-start
110110
#![cfg_attr(bootstrap, feature(const_exact_div))]
111111
#![cfg_attr(bootstrap, feature(const_fmt_arguments_new))]
112+
#![cfg_attr(bootstrap, feature(const_ub_checks))]
112113
#![feature(array_ptr_get)]
113114
#![feature(asm_experimental_arch)]
114115
#![feature(const_align_of_val)]
@@ -121,7 +122,6 @@
121122
#![feature(const_heap)]
122123
#![feature(const_nonnull_new)]
123124
#![feature(const_pin_2)]
124-
#![feature(const_ptr_is_null)]
125125
#![feature(const_ptr_sub_ptr)]
126126
#![feature(const_raw_ptr_comparison)]
127127
#![feature(const_size_of_val)]
@@ -132,7 +132,6 @@
132132
#![feature(const_type_id)]
133133
#![feature(const_type_name)]
134134
#![feature(const_typed_swap)]
135-
#![feature(const_ub_checks)]
136135
#![feature(core_intrinsics)]
137136
#![feature(coverage_attribute)]
138137
#![feature(do_not_recommend)]

core/src/ptr/const_ptr.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,18 @@ impl<T: ?Sized> *const T {
2929
/// assert!(!ptr.is_null());
3030
/// ```
3131
#[stable(feature = "rust1", since = "1.0.0")]
32-
#[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")]
32+
#[rustc_const_stable(feature = "const_ptr_is_null", since = "CURRENT_RUSTC_VERSION")]
3333
#[rustc_diagnostic_item = "ptr_const_is_null"]
3434
#[inline]
35+
#[rustc_allow_const_fn_unstable(const_eval_select)]
3536
pub const fn is_null(self) -> bool {
3637
// Compare via a cast to a thin pointer, so fat pointers are only
3738
// considering their "data" part for null-ness.
3839
let ptr = self as *const u8;
3940
const_eval_select!(
4041
@capture { ptr: *const u8 } -> bool:
41-
if const #[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")] {
42+
// This use of `const_raw_ptr_comparison` has been explicitly blessed by t-lang.
43+
if const #[rustc_allow_const_fn_unstable(const_raw_ptr_comparison)] {
4244
match (ptr).guaranteed_eq(null_mut()) {
4345
Some(res) => res,
4446
// To remain maximally convervative, we stop execution when we don't
@@ -280,7 +282,7 @@ impl<T: ?Sized> *const T {
280282
/// }
281283
/// ```
282284
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
283-
#[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")]
285+
#[rustc_const_stable(feature = "const_ptr_is_null", since = "CURRENT_RUSTC_VERSION")]
284286
#[inline]
285287
pub const unsafe fn as_ref<'a>(self) -> Option<&'a T> {
286288
// SAFETY: the caller must guarantee that `self` is valid

core/src/ptr/mod.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -1103,9 +1103,9 @@ pub const unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
11031103
count: usize = count,
11041104
) => {
11051105
let zero_size = size == 0 || count == 0;
1106-
ub_checks::is_aligned_and_not_null(x, align, zero_size)
1107-
&& ub_checks::is_aligned_and_not_null(y, align, zero_size)
1108-
&& ub_checks::is_nonoverlapping(x, y, size, count)
1106+
ub_checks::maybe_is_aligned_and_not_null(x, align, zero_size)
1107+
&& ub_checks::maybe_is_aligned_and_not_null(y, align, zero_size)
1108+
&& ub_checks::maybe_is_nonoverlapping(x, y, size, count)
11091109
}
11101110
);
11111111

@@ -1216,7 +1216,7 @@ pub const unsafe fn replace<T>(dst: *mut T, src: T) -> T {
12161216
addr: *const () = dst as *const (),
12171217
align: usize = align_of::<T>(),
12181218
is_zst: bool = T::IS_ZST,
1219-
) => ub_checks::is_aligned_and_not_null(addr, align, is_zst)
1219+
) => ub_checks::maybe_is_aligned_and_not_null(addr, align, is_zst)
12201220
);
12211221
mem::replace(&mut *dst, src)
12221222
}
@@ -1369,7 +1369,7 @@ pub const unsafe fn read<T>(src: *const T) -> T {
13691369
addr: *const () = src as *const (),
13701370
align: usize = align_of::<T>(),
13711371
is_zst: bool = T::IS_ZST,
1372-
) => ub_checks::is_aligned_and_not_null(addr, align, is_zst)
1372+
) => ub_checks::maybe_is_aligned_and_not_null(addr, align, is_zst)
13731373
);
13741374
crate::intrinsics::read_via_copy(src)
13751375
}
@@ -1573,7 +1573,7 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
15731573
addr: *mut () = dst as *mut (),
15741574
align: usize = align_of::<T>(),
15751575
is_zst: bool = T::IS_ZST,
1576-
) => ub_checks::is_aligned_and_not_null(addr, align, is_zst)
1576+
) => ub_checks::maybe_is_aligned_and_not_null(addr, align, is_zst)
15771577
);
15781578
intrinsics::write_via_move(dst, src)
15791579
}
@@ -1745,7 +1745,7 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
17451745
addr: *const () = src as *const (),
17461746
align: usize = align_of::<T>(),
17471747
is_zst: bool = T::IS_ZST,
1748-
) => ub_checks::is_aligned_and_not_null(addr, align, is_zst)
1748+
) => ub_checks::maybe_is_aligned_and_not_null(addr, align, is_zst)
17491749
);
17501750
intrinsics::volatile_load(src)
17511751
}
@@ -1825,7 +1825,7 @@ pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
18251825
addr: *mut () = dst as *mut (),
18261826
align: usize = align_of::<T>(),
18271827
is_zst: bool = T::IS_ZST,
1828-
) => ub_checks::is_aligned_and_not_null(addr, align, is_zst)
1828+
) => ub_checks::maybe_is_aligned_and_not_null(addr, align, is_zst)
18291829
);
18301830
intrinsics::volatile_store(dst, src);
18311831
}

core/src/ptr/mut_ptr.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ impl<T: ?Sized> *mut T {
2929
/// assert!(!ptr.is_null());
3030
/// ```
3131
#[stable(feature = "rust1", since = "1.0.0")]
32-
#[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")]
32+
#[rustc_const_stable(feature = "const_ptr_is_null", since = "CURRENT_RUSTC_VERSION")]
3333
#[rustc_diagnostic_item = "ptr_is_null"]
3434
#[inline]
3535
pub const fn is_null(self) -> bool {
@@ -271,7 +271,7 @@ impl<T: ?Sized> *mut T {
271271
/// }
272272
/// ```
273273
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
274-
#[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")]
274+
#[rustc_const_stable(feature = "const_ptr_is_null", since = "CURRENT_RUSTC_VERSION")]
275275
#[inline]
276276
pub const unsafe fn as_ref<'a>(self) -> Option<&'a T> {
277277
// SAFETY: the caller must guarantee that `self` is valid for a
@@ -619,7 +619,7 @@ impl<T: ?Sized> *mut T {
619619
/// println!("{s:?}"); // It'll print: "[4, 2, 3]".
620620
/// ```
621621
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
622-
#[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")]
622+
#[rustc_const_stable(feature = "const_ptr_is_null", since = "CURRENT_RUSTC_VERSION")]
623623
#[inline]
624624
pub const unsafe fn as_mut<'a>(self) -> Option<&'a mut T> {
625625
// SAFETY: the caller must guarantee that `self` is be valid for

core/src/slice/raw.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T]
132132
align: usize = align_of::<T>(),
133133
len: usize = len,
134134
) =>
135-
ub_checks::is_aligned_and_not_null(data, align, false)
135+
ub_checks::maybe_is_aligned_and_not_null(data, align, false)
136136
&& ub_checks::is_valid_allocation_size(size, len)
137137
);
138138
&*ptr::slice_from_raw_parts(data, len)
@@ -186,7 +186,7 @@ pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a m
186186
align: usize = align_of::<T>(),
187187
len: usize = len,
188188
) =>
189-
ub_checks::is_aligned_and_not_null(data, align, false)
189+
ub_checks::maybe_is_aligned_and_not_null(data, align, false)
190190
&& ub_checks::is_valid_allocation_size(size, len)
191191
);
192192
&mut *ptr::slice_from_raw_parts_mut(data, len)

core/src/ub_checks.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,6 @@ macro_rules! assert_unsafe_precondition {
6464
#[rustc_no_mir_inline]
6565
#[inline]
6666
#[rustc_nounwind]
67-
#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_ub_checks", issue = "none"))]
68-
#[rustc_allow_const_fn_unstable(const_ptr_is_null, const_ub_checks)] // only for UB checks
6967
const fn precondition_check($($name:$ty),*) {
7068
if !$e {
7169
::core::panicking::panic_nounwind(
@@ -116,12 +114,16 @@ pub(crate) const fn check_language_ub() -> bool {
116114
/// for `assert_unsafe_precondition!` with `check_language_ub`, in which case the
117115
/// check is anyway not executed in `const`.
118116
#[inline]
119-
#[rustc_const_unstable(feature = "const_ub_checks", issue = "none")]
120-
pub(crate) const fn is_aligned_and_not_null(ptr: *const (), align: usize, is_zst: bool) -> bool {
117+
#[rustc_allow_const_fn_unstable(const_eval_select)]
118+
pub(crate) const fn maybe_is_aligned_and_not_null(
119+
ptr: *const (),
120+
align: usize,
121+
is_zst: bool,
122+
) -> bool {
121123
// This is just for safety checks so we can const_eval_select.
122124
const_eval_select!(
123125
@capture { ptr: *const (), align: usize, is_zst: bool } -> bool:
124-
if const #[rustc_const_unstable(feature = "const_ub_checks", issue = "none")] {
126+
if const {
125127
is_zst || !ptr.is_null()
126128
} else {
127129
ptr.is_aligned_to(align) && (is_zst || !ptr.is_null())
@@ -141,8 +143,8 @@ pub(crate) const fn is_valid_allocation_size(size: usize, len: usize) -> bool {
141143
/// Note that in const-eval this function just returns `true` and therefore must
142144
/// only be used with `assert_unsafe_precondition!`, similar to `is_aligned_and_not_null`.
143145
#[inline]
144-
#[rustc_const_unstable(feature = "const_ub_checks", issue = "none")]
145-
pub(crate) const fn is_nonoverlapping(
146+
#[rustc_allow_const_fn_unstable(const_eval_select)]
147+
pub(crate) const fn maybe_is_nonoverlapping(
146148
src: *const (),
147149
dst: *const (),
148150
size: usize,

0 commit comments

Comments
 (0)