Skip to content

Commit 024bd26

Browse files
committed
Auto merge of rust-lang#83864 - Dylan-DPC:rollup-78an86n, r=Dylan-DPC
Rollup of 7 pull requests Successful merges: - rust-lang#80525 (wasm64 support) - rust-lang#83019 (core: disable `ptr::swap_nonoverlapping_one`'s block optimization on SPIR-V.) - rust-lang#83717 (rustdoc: Separate filter-empty-string out into its own function) - rust-lang#83807 (Tests: Remove redundant `ignore-tidy-linelength` annotations) - rust-lang#83815 (ptr::addr_of documentation improvements) - rust-lang#83820 (Remove attribute `#[link_args]`) - rust-lang#83841 (Allow clobbering unsupported registers in asm!) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents b4a2415 + b0c02ac commit 024bd26

File tree

3 files changed

+59
-14
lines changed

3 files changed

+59
-14
lines changed

core/src/mem/maybe_uninit.rs

+2
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ use crate::ptr;
190190
/// let ptr = uninit.as_mut_ptr();
191191
///
192192
/// // Initializing the `name` field
193+
/// // Using `write` instead of assignment via `=` to not call `drop` on the
194+
/// // old, uninitialized value.
193195
/// unsafe { addr_of_mut!((*ptr).name).write("Bob".to_string()); }
194196
///
195197
/// // Initializing the `list` field

core/src/ptr/mod.rs

+57-13
Original file line numberDiff line numberDiff line change
@@ -428,19 +428,32 @@ pub const unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
428428
#[inline]
429429
#[rustc_const_unstable(feature = "const_swap", issue = "83163")]
430430
pub(crate) const unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
431-
// For types smaller than the block optimization below,
432-
// just swap directly to avoid pessimizing codegen.
433-
if mem::size_of::<T>() < 32 {
434-
// SAFETY: the caller must guarantee that `x` and `y` are valid
435-
// for writes, properly aligned, and non-overlapping.
436-
unsafe {
437-
let z = read(x);
438-
copy_nonoverlapping(y, x, 1);
439-
write(y, z);
431+
// NOTE(eddyb) SPIR-V's Logical addressing model doesn't allow for arbitrary
432+
// reinterpretation of values as (chunkable) byte arrays, and the loop in the
433+
// block optimization in `swap_nonoverlapping_bytes` is hard to rewrite back
434+
// into the (unoptimized) direct swapping implementation, so we disable it.
435+
// FIXME(eddyb) the block optimization also prevents MIR optimizations from
436+
// understanding `mem::replace`, `Option::take`, etc. - a better overall
437+
// solution might be to make `swap_nonoverlapping` into an intrinsic, which
438+
// a backend can choose to implement using the block optimization, or not.
439+
#[cfg(not(target_arch = "spirv"))]
440+
{
441+
// Only apply the block optimization in `swap_nonoverlapping_bytes` for types
442+
// at least as large as the block size, to avoid pessimizing codegen.
443+
if mem::size_of::<T>() >= 32 {
444+
// SAFETY: the caller must uphold the safety contract for `swap_nonoverlapping`.
445+
unsafe { swap_nonoverlapping(x, y, 1) };
446+
return;
440447
}
441-
} else {
442-
// SAFETY: the caller must uphold the safety contract for `swap_nonoverlapping`.
443-
unsafe { swap_nonoverlapping(x, y, 1) };
448+
}
449+
450+
// Direct swapping, for the cases not going through the block optimization.
451+
// SAFETY: the caller must guarantee that `x` and `y` are valid
452+
// for writes, properly aligned, and non-overlapping.
453+
unsafe {
454+
let z = read(x);
455+
copy_nonoverlapping(y, x, 1);
456+
write(y, z);
444457
}
445458
}
446459

@@ -1479,6 +1492,10 @@ fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K, L }
14791492
/// as all other references. This macro can create a raw pointer *without* creating
14801493
/// a reference first.
14811494
///
1495+
/// Note, however, that the `expr` in `addr_of!(expr)` is still subject to all
1496+
/// the usual rules. In particular, `addr_of!(*ptr::null())` is Undefined
1497+
/// Behavior because it dereferences a NULL pointer.
1498+
///
14821499
/// # Example
14831500
///
14841501
/// ```
@@ -1495,6 +1512,10 @@ fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K, L }
14951512
/// let raw_f2 = ptr::addr_of!(packed.f2);
14961513
/// assert_eq!(unsafe { raw_f2.read_unaligned() }, 2);
14971514
/// ```
1515+
///
1516+
/// See [`addr_of_mut`] for how to create a pointer to unininitialized data.
1517+
/// Doing that with `addr_of` would not make much sense since one could only
1518+
/// read the data, and that would be Undefined Behavior.
14981519
#[stable(feature = "raw_ref_macros", since = "1.51.0")]
14991520
#[rustc_macro_transparency = "semitransparent"]
15001521
#[allow_internal_unstable(raw_ref_op)]
@@ -1511,7 +1532,13 @@ pub macro addr_of($place:expr) {
15111532
/// as all other references. This macro can create a raw pointer *without* creating
15121533
/// a reference first.
15131534
///
1514-
/// # Example
1535+
/// Note, however, that the `expr` in `addr_of_mut!(expr)` is still subject to all
1536+
/// the usual rules. In particular, `addr_of_mut!(*ptr::null_mut())` is Undefined
1537+
/// Behavior because it dereferences a NULL pointer.
1538+
///
1539+
/// # Examples
1540+
///
1541+
/// **Creating a pointer to unaligned data:**
15151542
///
15161543
/// ```
15171544
/// use std::ptr;
@@ -1528,6 +1555,23 @@ pub macro addr_of($place:expr) {
15281555
/// unsafe { raw_f2.write_unaligned(42); }
15291556
/// assert_eq!({packed.f2}, 42); // `{...}` forces copying the field instead of creating a reference.
15301557
/// ```
1558+
///
1559+
/// **Creating a pointer to uninitialized data:**
1560+
///
1561+
/// ```rust
1562+
/// use std::{ptr, mem::MaybeUninit};
1563+
///
1564+
/// struct Demo {
1565+
/// field: bool,
1566+
/// }
1567+
///
1568+
/// let mut uninit = MaybeUninit::<Demo>::uninit();
1569+
/// // `&uninit.as_mut().field` would create a reference to an uninitialized `bool`,
1570+
/// // and thus be Undefined Behavior!
1571+
/// let f1_ptr = unsafe { ptr::addr_of_mut!((*uninit.as_mut_ptr()).field) };
1572+
/// unsafe { f1_ptr.write(true); }
1573+
/// let init = unsafe { uninit.assume_init() };
1574+
/// ```
15311575
#[stable(feature = "raw_ref_macros", since = "1.51.0")]
15321576
#[rustc_macro_transparency = "semitransparent"]
15331577
#[allow_internal_unstable(raw_ref_op)]

std/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,6 @@
282282
#![feature(intra_doc_pointers)]
283283
#![feature(iter_zip)]
284284
#![feature(lang_items)]
285-
#![feature(link_args)]
286285
#![feature(linkage)]
287286
#![feature(llvm_asm)]
288287
#![feature(log_syntax)]

0 commit comments

Comments
 (0)