Skip to content

Commit 15bcd0a

Browse files
borsgitbot
authored and
gitbot
committed
Auto merge of rust-lang#136534 - jhpratt:rollup-dnz57dq, r=jhpratt
Rollup of 6 pull requests Successful merges: - rust-lang#136398 (add UnsafeCell direct access APIs) - rust-lang#136465 (Some `rustc_middle` cleanups) - rust-lang#136479 (std::fs: further simplify dirent64 handling) - rust-lang#136504 (Fix last compare-mode false negatives in tests) - rust-lang#136511 (Add `cast_signed` and `cast_unsigned` methods for `NonZero` types) - rust-lang#136518 (Add note about `FnPtr` trait being exposed as public bound) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 36061e0 + dd30ea2 commit 15bcd0a

File tree

4 files changed

+157
-10
lines changed

4 files changed

+157
-10
lines changed

core/src/cell.rs

+84
Original file line numberDiff line numberDiff line change
@@ -2118,6 +2118,35 @@ impl<T> UnsafeCell<T> {
21182118
pub const fn into_inner(self) -> T {
21192119
self.value
21202120
}
2121+
2122+
/// Replace the value in this `UnsafeCell` and return the old value.
2123+
///
2124+
/// # Safety
2125+
///
2126+
/// The caller must take care to avoid aliasing and data races.
2127+
///
2128+
/// - It is Undefined Behavior to allow calls to race with
2129+
/// any other access to the wrapped value.
2130+
/// - It is Undefined Behavior to call this while any other
2131+
/// reference(s) to the wrapped value are alive.
2132+
///
2133+
/// # Examples
2134+
///
2135+
/// ```
2136+
/// #![feature(unsafe_cell_access)]
2137+
/// use std::cell::UnsafeCell;
2138+
///
2139+
/// let uc = UnsafeCell::new(5);
2140+
///
2141+
/// let old = unsafe { uc.replace(10) };
2142+
/// assert_eq!(old, 5);
2143+
/// ```
2144+
#[inline]
2145+
#[unstable(feature = "unsafe_cell_access", issue = "136327")]
2146+
pub const unsafe fn replace(&self, value: T) -> T {
2147+
// SAFETY: pointer comes from `&self` so naturally satisfies invariants.
2148+
unsafe { ptr::replace(self.get(), value) }
2149+
}
21212150
}
21222151

21232152
impl<T: ?Sized> UnsafeCell<T> {
@@ -2230,6 +2259,61 @@ impl<T: ?Sized> UnsafeCell<T> {
22302259
// no guarantee for user code that this will work in future versions of the compiler!
22312260
this as *const T as *mut T
22322261
}
2262+
2263+
/// Get a shared reference to the value within the `UnsafeCell`.
2264+
///
2265+
/// # Safety
2266+
///
2267+
/// - It is Undefined Behavior to call this while any mutable
2268+
/// reference to the wrapped value is alive.
2269+
/// - Mutating the wrapped value while the returned
2270+
/// reference is alive is Undefined Behavior.
2271+
///
2272+
/// # Examples
2273+
///
2274+
/// ```
2275+
/// #![feature(unsafe_cell_access)]
2276+
/// use std::cell::UnsafeCell;
2277+
///
2278+
/// let uc = UnsafeCell::new(5);
2279+
///
2280+
/// let val = unsafe { uc.as_ref_unchecked() };
2281+
/// assert_eq!(val, &5);
2282+
/// ```
2283+
#[inline]
2284+
#[unstable(feature = "unsafe_cell_access", issue = "136327")]
2285+
pub const unsafe fn as_ref_unchecked(&self) -> &T {
2286+
// SAFETY: pointer comes from `&self` so naturally satisfies ptr-to-ref invariants.
2287+
unsafe { self.get().as_ref_unchecked() }
2288+
}
2289+
2290+
/// Get an exclusive reference to the value within the `UnsafeCell`.
2291+
///
2292+
/// # Safety
2293+
///
2294+
/// - It is Undefined Behavior to call this while any other
2295+
/// reference(s) to the wrapped value are alive.
2296+
/// - Mutating the wrapped value through other means while the
2297+
/// returned reference is alive is Undefined Behavior.
2298+
///
2299+
/// # Examples
2300+
///
2301+
/// ```
2302+
/// #![feature(unsafe_cell_access)]
2303+
/// use std::cell::UnsafeCell;
2304+
///
2305+
/// let uc = UnsafeCell::new(5);
2306+
///
2307+
/// unsafe { *uc.as_mut_unchecked() += 1; }
2308+
/// assert_eq!(uc.into_inner(), 6);
2309+
/// ```
2310+
#[inline]
2311+
#[unstable(feature = "unsafe_cell_access", issue = "136327")]
2312+
#[allow(clippy::mut_from_ref)]
2313+
pub const unsafe fn as_mut_unchecked(&self) -> &mut T {
2314+
// SAFETY: pointer comes from `&self` so naturally satisfies ptr-to-ref invariants.
2315+
unsafe { self.get().as_mut_unchecked() }
2316+
}
22332317
}
22342318

22352319
#[stable(feature = "unsafe_cell_default", since = "1.10.0")]

core/src/marker.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1077,6 +1077,9 @@ marker_impls! {
10771077
}
10781078

10791079
/// A common trait implemented by all function pointers.
1080+
//
1081+
// Note that while the trait is internal and unstable it is nevertheless
1082+
// exposed as a public bound of the stable `core::ptr::fn_addr_eq` function.
10801083
#[unstable(
10811084
feature = "fn_ptr_trait",
10821085
issue = "none",

core/src/num/nonzero.rs

+64-2
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,7 @@ macro_rules! nonzero_integer {
474474
#[$stability:meta]
475475
Self = $Ty:ident,
476476
Primitive = $signedness:ident $Int:ident,
477+
SignedPrimitive = $Sint:ty,
477478
UnsignedPrimitive = $Uint:ty,
478479

479480
// Used in doc comments.
@@ -905,6 +906,7 @@ macro_rules! nonzero_integer {
905906

906907
nonzero_integer_signedness_dependent_methods! {
907908
Primitive = $signedness $Int,
909+
SignedPrimitive = $Sint,
908910
UnsignedPrimitive = $Uint,
909911
}
910912

@@ -1128,6 +1130,7 @@ macro_rules! nonzero_integer {
11281130
(
11291131
Self = $Ty:ident,
11301132
Primitive = unsigned $Int:ident,
1133+
SignedPrimitive = $Sint:ident,
11311134
rot = $rot:literal,
11321135
rot_op = $rot_op:literal,
11331136
rot_result = $rot_result:literal,
@@ -1140,6 +1143,7 @@ macro_rules! nonzero_integer {
11401143
#[stable(feature = "nonzero", since = "1.28.0")]
11411144
Self = $Ty,
11421145
Primitive = unsigned $Int,
1146+
SignedPrimitive = $Sint,
11431147
UnsignedPrimitive = $Int,
11441148
rot = $rot,
11451149
rot_op = $rot_op,
@@ -1154,7 +1158,7 @@ macro_rules! nonzero_integer {
11541158
(
11551159
Self = $Ty:ident,
11561160
Primitive = signed $Int:ident,
1157-
UnsignedPrimitive = $UInt:ident,
1161+
UnsignedPrimitive = $Uint:ident,
11581162
rot = $rot:literal,
11591163
rot_op = $rot_op:literal,
11601164
rot_result = $rot_result:literal,
@@ -1166,7 +1170,8 @@ macro_rules! nonzero_integer {
11661170
#[stable(feature = "signed_nonzero", since = "1.34.0")]
11671171
Self = $Ty,
11681172
Primitive = signed $Int,
1169-
UnsignedPrimitive = $UInt,
1173+
SignedPrimitive = $Int,
1174+
UnsignedPrimitive = $Uint,
11701175
rot = $rot,
11711176
rot_op = $rot_op,
11721177
rot_result = $rot_result,
@@ -1286,6 +1291,7 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
12861291
// Associated items for unsigned nonzero types only.
12871292
(
12881293
Primitive = unsigned $Int:ident,
1294+
SignedPrimitive = $Sint:ty,
12891295
UnsignedPrimitive = $Uint:ty,
12901296
) => {
12911297
/// The smallest value that can be represented by this non-zero
@@ -1620,11 +1626,35 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
16201626
// results will be sqrt(1), which is 1, so a result can't be zero.
16211627
unsafe { Self::new_unchecked(result) }
16221628
}
1629+
1630+
/// Returns the bit pattern of `self` reinterpreted as a signed integer of the same size.
1631+
///
1632+
/// # Examples
1633+
///
1634+
/// Basic usage:
1635+
///
1636+
/// ```
1637+
/// #![feature(integer_sign_cast)]
1638+
/// # use std::num::NonZero;
1639+
///
1640+
#[doc = concat!("let n = NonZero::<", stringify!($Int), ">::MAX;")]
1641+
///
1642+
#[doc = concat!("assert_eq!(n.cast_signed(), NonZero::new(-1", stringify!($Sint), ").unwrap());")]
1643+
/// ```
1644+
#[unstable(feature = "integer_sign_cast", issue = "125882")]
1645+
#[must_use = "this returns the result of the operation, \
1646+
without modifying the original"]
1647+
#[inline(always)]
1648+
pub const fn cast_signed(self) -> NonZero<$Sint> {
1649+
// SAFETY: `self.get()` can't be zero
1650+
unsafe { NonZero::new_unchecked(self.get().cast_signed()) }
1651+
}
16231652
};
16241653

16251654
// Associated items for signed nonzero types only.
16261655
(
16271656
Primitive = signed $Int:ident,
1657+
SignedPrimitive = $Sint:ty,
16281658
UnsignedPrimitive = $Uint:ty,
16291659
) => {
16301660
/// The smallest value that can be represented by this non-zero
@@ -2035,12 +2065,37 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
20352065
// SAFETY: negation of nonzero cannot yield zero values.
20362066
unsafe { Self::new_unchecked(result) }
20372067
}
2068+
2069+
/// Returns the bit pattern of `self` reinterpreted as an unsigned integer of the same size.
2070+
///
2071+
/// # Examples
2072+
///
2073+
/// Basic usage:
2074+
///
2075+
/// ```
2076+
/// #![feature(integer_sign_cast)]
2077+
/// # use std::num::NonZero;
2078+
///
2079+
#[doc = concat!("let n = NonZero::new(-1", stringify!($Int), ").unwrap();")]
2080+
///
2081+
#[doc = concat!("assert_eq!(n.cast_unsigned(), NonZero::<", stringify!($Uint), ">::MAX);")]
2082+
/// ```
2083+
#[unstable(feature = "integer_sign_cast", issue = "125882")]
2084+
#[must_use = "this returns the result of the operation, \
2085+
without modifying the original"]
2086+
#[inline(always)]
2087+
pub const fn cast_unsigned(self) -> NonZero<$Uint> {
2088+
// SAFETY: `self.get()` can't be zero
2089+
unsafe { NonZero::new_unchecked(self.get().cast_unsigned()) }
2090+
}
2091+
20382092
};
20392093
}
20402094

20412095
nonzero_integer! {
20422096
Self = NonZeroU8,
20432097
Primitive = unsigned u8,
2098+
SignedPrimitive = i8,
20442099
rot = 2,
20452100
rot_op = "0x82",
20462101
rot_result = "0xa",
@@ -2052,6 +2107,7 @@ nonzero_integer! {
20522107
nonzero_integer! {
20532108
Self = NonZeroU16,
20542109
Primitive = unsigned u16,
2110+
SignedPrimitive = i16,
20552111
rot = 4,
20562112
rot_op = "0xa003",
20572113
rot_result = "0x3a",
@@ -2063,6 +2119,7 @@ nonzero_integer! {
20632119
nonzero_integer! {
20642120
Self = NonZeroU32,
20652121
Primitive = unsigned u32,
2122+
SignedPrimitive = i32,
20662123
rot = 8,
20672124
rot_op = "0x10000b3",
20682125
rot_result = "0xb301",
@@ -2074,6 +2131,7 @@ nonzero_integer! {
20742131
nonzero_integer! {
20752132
Self = NonZeroU64,
20762133
Primitive = unsigned u64,
2134+
SignedPrimitive = i64,
20772135
rot = 12,
20782136
rot_op = "0xaa00000000006e1",
20792137
rot_result = "0x6e10aa",
@@ -2085,6 +2143,7 @@ nonzero_integer! {
20852143
nonzero_integer! {
20862144
Self = NonZeroU128,
20872145
Primitive = unsigned u128,
2146+
SignedPrimitive = i128,
20882147
rot = 16,
20892148
rot_op = "0x13f40000000000000000000000004f76",
20902149
rot_result = "0x4f7613f4",
@@ -2097,6 +2156,7 @@ nonzero_integer! {
20972156
nonzero_integer! {
20982157
Self = NonZeroUsize,
20992158
Primitive = unsigned usize,
2159+
SignedPrimitive = isize,
21002160
rot = 4,
21012161
rot_op = "0xa003",
21022162
rot_result = "0x3a",
@@ -2109,6 +2169,7 @@ nonzero_integer! {
21092169
nonzero_integer! {
21102170
Self = NonZeroUsize,
21112171
Primitive = unsigned usize,
2172+
SignedPrimitive = isize,
21122173
rot = 8,
21132174
rot_op = "0x10000b3",
21142175
rot_result = "0xb301",
@@ -2121,6 +2182,7 @@ nonzero_integer! {
21212182
nonzero_integer! {
21222183
Self = NonZeroUsize,
21232184
Primitive = unsigned usize,
2185+
SignedPrimitive = isize,
21242186
rot = 12,
21252187
rot_op = "0xaa00000000006e1",
21262188
rot_result = "0x6e10aa",

std/src/sys/pal/unix/fs.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -740,29 +740,27 @@ impl Iterator for ReadDir {
740740
// to `byte_offset` and thus does not require the full extent of `*entry_ptr`
741741
// to be in bounds of the same allocation, only the offset of the field
742742
// being referenced.
743-
macro_rules! entry_field_ptr {
744-
($field:ident) => {
745-
&raw const (*entry_ptr).$field
746-
};
747-
}
748743

749744
// d_name is guaranteed to be null-terminated.
750-
let name = CStr::from_ptr(entry_field_ptr!(d_name).cast());
745+
let name = CStr::from_ptr((&raw const (*entry_ptr).d_name).cast());
751746
let name_bytes = name.to_bytes();
752747
if name_bytes == b"." || name_bytes == b".." {
753748
continue;
754749
}
755750

751+
// When loading from a field, we can skip the `&raw const`; `(*entry_ptr).d_ino` as
752+
// a value expression will do the right thing: `byte_offset` to the field and then
753+
// only access those bytes.
756754
#[cfg(not(target_os = "vita"))]
757755
let entry = dirent64_min {
758-
d_ino: *entry_field_ptr!(d_ino) as u64,
756+
d_ino: (*entry_ptr).d_ino as u64,
759757
#[cfg(not(any(
760758
target_os = "solaris",
761759
target_os = "illumos",
762760
target_os = "aix",
763761
target_os = "nto",
764762
)))]
765-
d_type: *entry_field_ptr!(d_type) as u8,
763+
d_type: (*entry_ptr).d_type as u8,
766764
};
767765

768766
#[cfg(target_os = "vita")]

0 commit comments

Comments
 (0)