Rollup merge of #126213 - zachs18:atomicbool-u8-i8-from-ptr-alignment, r=Nilstrieb

Update docs for AtomicBool/U8/I8 with regard to alignment

Fixes #126084.

Since `AtomicBool`/`AtomicU8`/`AtomicI8` are guaranteed to have size == 1, and Rust guarantees that `size % align == 0`, they also must have alignment equal to 1, so some current docs are contradictory/confusing when describing their alignment requirements.

Specifically:

* Fix `AtomicBool::from_ptr` claiming that `align_of::<AtomicBool>() > align_of::<bool>()` on some platforms. (same for `AtomicU8::from_ptr`/`AtomicI8::from_ptr`)
* Explicitly state that `AtomicU8`/`AtomicI8` have the same alignment as `u8`/`i8` (in addition to size and bit validity)
* (internal) Change the `if_not_8_bit` macro to be `if_8_bit` and to allow an "if-else"-like structure, instead of just "if"-like.

---

I opted to leave the "`ptr` must be aligned" wording in `from_ptr`'s docs and just clarify that it is always satsified, instead of just removing the wording entirely. If that is instead preferred I can do that.
This commit is contained in:
Matthias Krüger 2024-06-24 15:06:21 +02:00 committed by GitHub
commit 94b9ea417d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -443,8 +443,8 @@ impl AtomicBool {
///
/// # Safety
///
/// * `ptr` must be aligned to `align_of::<AtomicBool>()` (note that on some platforms this can
/// be bigger than `align_of::<bool>()`).
/// * `ptr` must be aligned to `align_of::<AtomicBool>()` (note that this is always true, since
/// `align_of::<AtomicBool>() == 1`).
/// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
/// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not
/// allowed to mix atomic and non-atomic accesses, or atomic accesses of different sizes,
@ -2091,10 +2091,10 @@ impl<T> From<*mut T> for AtomicPtr<T> {
}
#[allow(unused_macros)] // This macro ends up being unused on some architectures.
macro_rules! if_not_8_bit {
(u8, $($tt:tt)*) => { "" };
(i8, $($tt:tt)*) => { "" };
($_:ident, $($tt:tt)*) => { $($tt)* };
macro_rules! if_8_bit {
(u8, $( yes = [$($yes:tt)*], )? $( no = [$($no:tt)*], )? ) => { concat!("", $($($yes)*)?) };
(i8, $( yes = [$($yes:tt)*], )? $( no = [$($no:tt)*], )? ) => { concat!("", $($($yes)*)?) };
($_:ident, $( yes = [$($yes:tt)*], )? $( no = [$($no:tt)*], )? ) => { concat!("", $($($no)*)?) };
}
#[cfg(target_has_atomic_load_store)]
@ -2116,18 +2116,24 @@ macro_rules! atomic_int {
$int_type:ident $atomic_type:ident) => {
/// An integer type which can be safely shared between threads.
///
/// This type has the same size and bit validity as the underlying
/// integer type, [`
/// This type has the same
#[doc = if_8_bit!(
$int_type,
yes = ["size, alignment, and bit validity"],
no = ["size and bit validity"],
)]
/// as the underlying integer type, [`
#[doc = $s_int_type]
/// `].
#[doc = if_not_8_bit! {
#[doc = if_8_bit! {
$int_type,
concat!(
no = [
"However, the alignment of this type is always equal to its ",
"size, even on targets where [`", $s_int_type, "`] has a ",
"lesser alignment."
)
],
}]
///
/// For more about the differences between atomic types and
/// non-atomic types as well as information about the portability of
/// this type, please see the [module-level documentation].
@ -2220,9 +2226,19 @@ macro_rules! atomic_int {
///
/// # Safety
///
#[doc = concat!(" * `ptr` must be aligned to \
`align_of::<", stringify!($atomic_type), ">()` (note that on some platforms this \
can be bigger than `align_of::<", stringify!($int_type), ">()`).")]
/// * `ptr` must be aligned to
#[doc = concat!(" `align_of::<", stringify!($atomic_type), ">()`")]
#[doc = if_8_bit!{
$int_type,
yes = [
" (note that this is always true, since `align_of::<",
stringify!($atomic_type), ">() == 1`)."
],
no = [
" (note that on some platforms this can be bigger than `align_of::<",
stringify!($int_type), ">()`)."
],
}]
/// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
/// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not
/// allowed to mix atomic and non-atomic accesses, or atomic accesses of different sizes,
@ -2261,12 +2277,12 @@ macro_rules! atomic_int {
#[doc = concat!("Get atomic access to a `&mut ", stringify!($int_type), "`.")]
///
#[doc = if_not_8_bit! {
#[doc = if_8_bit! {
$int_type,
concat!(
no = [
"**Note:** This function is only available on targets where `",
stringify!($int_type), "` has an alignment of ", $align, " bytes."
)
],
}]
///
/// # Examples