Skip to content

Commit d9c589c

Browse files
committed
Auto merge of rust-lang#116480 - GuillaumeGomez:rollup-s0lv33r, r=GuillaumeGomez
Rollup of 6 pull requests Successful merges: - rust-lang#111595 (`waitqueue` clarifications for SGX platform) - rust-lang#115454 (Clarify example in docs of str::char_slice) - rust-lang#115522 (Clarify ManuallyDrop bit validity) - rust-lang#115588 (Fix a comment in std::iter::successors) - rust-lang#116329 (update some comments around swap()) - rust-lang#116475 (rustdoc-search: fix bug with multi-item impl trait) r? `@ghost` `@rustbot` modify labels: rollup
2 parents d4ba2b4 + efd978a commit d9c589c

File tree

11 files changed

+57
-30
lines changed

11 files changed

+57
-30
lines changed

compiler/rustc_middle/src/mir/syntax.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -996,7 +996,7 @@ pub type AssertMessage<'tcx> = AssertKind<Operand<'tcx>>;
996996
///
997997
/// [UCG#319]: https://github.com/rust-lang/unsafe-code-guidelines/issues/319
998998
///
999-
/// Rust currently requires that every place obey those two rules. This is checked by MIRI and taken
999+
/// Rust currently requires that every place obey those two rules. This is checked by Miri and taken
10001000
/// advantage of by codegen (via `gep inbounds`). That is possibly subject to change.
10011001
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, HashStable, TypeFoldable, TypeVisitable)]
10021002
pub struct Place<'tcx> {

library/core/src/iter/sources/successors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ where
1717
F: FnMut(&T) -> Option<T>,
1818
{
1919
// If this function returned `impl Iterator<Item=T>`
20-
// it could be based on `unfold` and not need a dedicated type.
20+
// it could be based on `from_fn` and not need a dedicated type.
2121
// However having a named `Successors<T, F>` type allows it to be `Clone` when `T` and `F` are.
2222
Successors { next: first, succ }
2323
}

library/core/src/mem/manually_drop.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ use crate::ptr;
44
/// A wrapper to inhibit compiler from automatically calling `T`’s destructor.
55
/// This wrapper is 0-cost.
66
///
7-
/// `ManuallyDrop<T>` is guaranteed to have the same layout as `T`, and is subject
8-
/// to the same layout optimizations as `T`. As a consequence, it has *no effect*
9-
/// on the assumptions that the compiler makes about its contents. For example,
10-
/// initializing a `ManuallyDrop<&mut T>` with [`mem::zeroed`] is undefined
11-
/// behavior. If you need to handle uninitialized data, use [`MaybeUninit<T>`]
12-
/// instead.
7+
/// `ManuallyDrop<T>` is guaranteed to have the same layout and bit validity as
8+
/// `T`, and is subject to the same layout optimizations as `T`. As a consequence,
9+
/// it has *no effect* on the assumptions that the compiler makes about its
10+
/// contents. For example, initializing a `ManuallyDrop<&mut T>` with [`mem::zeroed`]
11+
/// is undefined behavior. If you need to handle uninitialized data, use
12+
/// [`MaybeUninit<T>`] instead.
1313
///
1414
/// Note that accessing the value inside a `ManuallyDrop<T>` is safe.
1515
/// This means that a `ManuallyDrop<T>` whose content has been dropped must not

library/core/src/mem/mod.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -728,10 +728,6 @@ pub const fn swap<T>(x: &mut T, y: &mut T) {
728728
// reinterpretation of values as (chunkable) byte arrays, and the loop in the
729729
// block optimization in `swap_slice` is hard to rewrite back
730730
// into the (unoptimized) direct swapping implementation, so we disable it.
731-
// FIXME(eddyb) the block optimization also prevents MIR optimizations from
732-
// understanding `mem::replace`, `Option::take`, etc. - a better overall
733-
// solution might be to make `ptr::swap_nonoverlapping` into an intrinsic, which
734-
// a backend can choose to implement using the block optimization, or not.
735731
#[cfg(not(any(target_arch = "spirv")))]
736732
{
737733
// For types that are larger multiples of their alignment, the simple way
@@ -768,11 +764,14 @@ pub(crate) const fn swap_simple<T>(x: &mut T, y: &mut T) {
768764
// And LLVM actually optimizes it to 3×memcpy if called with
769765
// a type larger than it's willing to keep in a register.
770766
// Having typed reads and writes in MIR here is also good as
771-
// it lets MIRI and CTFE understand them better, including things
767+
// it lets Miri and CTFE understand them better, including things
772768
// like enforcing type validity for them.
773769
// Importantly, read+copy_nonoverlapping+write introduces confusing
774770
// asymmetry to the behaviour where one value went through read+write
775771
// whereas the other was copied over by the intrinsic (see #94371).
772+
// Furthermore, using only read+write here benefits limited backends
773+
// such as SPIR-V that work on an underlying *typed* view of memory,
774+
// and thus have trouble with Rust's untyped memory operations.
776775

777776
// SAFETY: exclusive references are always valid to read/write,
778777
// including being aligned, and nothing here panics so it's drop-safe.

library/core/src/str/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -808,7 +808,7 @@ impl str {
808808
/// assert_eq!(Some((0, 'y')), char_indices.next()); // not (0, 'y̆')
809809
/// assert_eq!(Some((1, '\u{0306}')), char_indices.next());
810810
///
811-
/// // note the 3 here - the last character took up two bytes
811+
/// // note the 3 here - the previous character took up two bytes
812812
/// assert_eq!(Some((3, 'e')), char_indices.next());
813813
/// assert_eq!(Some((4, 's')), char_indices.next());
814814
///

library/core/tests/array.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ fn array_mixed_equality_nans() {
663663

664664
#[test]
665665
fn array_into_iter_fold() {
666-
// Strings to help MIRI catch if we double-free or something
666+
// Strings to help Miri catch if we double-free or something
667667
let a = ["Aa".to_string(), "Bb".to_string(), "Cc".to_string()];
668668
let mut s = "s".to_string();
669669
a.into_iter().for_each(|b| s += &b);
@@ -679,7 +679,7 @@ fn array_into_iter_fold() {
679679

680680
#[test]
681681
fn array_into_iter_rfold() {
682-
// Strings to help MIRI catch if we double-free or something
682+
// Strings to help Miri catch if we double-free or something
683683
let a = ["Aa".to_string(), "Bb".to_string(), "Cc".to_string()];
684684
let mut s = "s".to_string();
685685
a.into_iter().rev().for_each(|b| s += &b);

library/std/src/sys/sgx/waitqueue/mod.rs

+19-7
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ mod unsafe_list;
1818

1919
use crate::num::NonZeroUsize;
2020
use crate::ops::{Deref, DerefMut};
21+
use crate::panic::{self, AssertUnwindSafe};
2122
use crate::time::Duration;
2223

2324
use super::abi::thread;
@@ -147,7 +148,8 @@ impl WaitQueue {
147148
/// Adds the calling thread to the `WaitVariable`'s wait queue, then wait
148149
/// until a wakeup event.
149150
///
150-
/// This function does not return until this thread has been awoken.
151+
/// This function does not return until this thread has been awoken. When `before_wait` panics,
152+
/// this function will abort.
151153
pub fn wait<T, F: FnOnce()>(mut guard: SpinMutexGuard<'_, WaitVariable<T>>, before_wait: F) {
152154
// very unsafe: check requirements of UnsafeList::push
153155
unsafe {
@@ -157,8 +159,13 @@ impl WaitQueue {
157159
}));
158160
let entry = guard.queue.inner.push(&mut entry);
159161
drop(guard);
160-
before_wait();
162+
if let Err(_e) = panic::catch_unwind(AssertUnwindSafe(|| before_wait())) {
163+
rtabort!("Panic before wait on wakeup event")
164+
}
161165
while !entry.lock().wake {
166+
// `entry.wake` is only set in `notify_one` and `notify_all` functions. Both ensure
167+
// the entry is removed from the queue _before_ setting this bool. There are no
168+
// other references to `entry`.
162169
// don't panic, this would invalidate `entry` during unwinding
163170
let eventset = rtunwrap!(Ok, usercalls::wait(EV_UNPARK, WAIT_INDEFINITE));
164171
rtassert!(eventset & EV_UNPARK == EV_UNPARK);
@@ -169,6 +176,7 @@ impl WaitQueue {
169176
/// Adds the calling thread to the `WaitVariable`'s wait queue, then wait
170177
/// until a wakeup event or timeout. If event was observed, returns true.
171178
/// If not, it will remove the calling thread from the wait queue.
179+
/// When `before_wait` panics, this function will abort.
172180
pub fn wait_timeout<T, F: FnOnce()>(
173181
lock: &SpinMutex<WaitVariable<T>>,
174182
timeout: Duration,
@@ -181,9 +189,13 @@ impl WaitQueue {
181189
wake: false,
182190
}));
183191
let entry_lock = lock.lock().queue.inner.push(&mut entry);
184-
before_wait();
192+
if let Err(_e) = panic::catch_unwind(AssertUnwindSafe(|| before_wait())) {
193+
rtabort!("Panic before wait on wakeup event or timeout")
194+
}
185195
usercalls::wait_timeout(EV_UNPARK, timeout, || entry_lock.lock().wake);
186-
// acquire the wait queue's lock first to avoid deadlock.
196+
// acquire the wait queue's lock first to avoid deadlock
197+
// and ensure no other function can simultaneously access the list
198+
// (e.g., `notify_one` or `notify_all`)
187199
let mut guard = lock.lock();
188200
let success = entry_lock.lock().wake;
189201
if !success {
@@ -204,8 +216,8 @@ impl WaitQueue {
204216
) -> Result<WaitGuard<'_, T>, SpinMutexGuard<'_, WaitVariable<T>>> {
205217
// SAFETY: lifetime of the pop() return value is limited to the map
206218
// closure (The closure return value is 'static). The underlying
207-
// stack frame won't be freed until after the WaitGuard created below
208-
// is dropped.
219+
// stack frame won't be freed until after the lock on the queue is released
220+
// (i.e., `guard` is dropped).
209221
unsafe {
210222
let tcs = guard.queue.inner.pop().map(|entry| -> Tcs {
211223
let mut entry_guard = entry.lock();
@@ -231,7 +243,7 @@ impl WaitQueue {
231243
) -> Result<WaitGuard<'_, T>, SpinMutexGuard<'_, WaitVariable<T>>> {
232244
// SAFETY: lifetime of the pop() return values are limited to the
233245
// while loop body. The underlying stack frames won't be freed until
234-
// after the WaitGuard created below is dropped.
246+
// after the lock on the queue is released (i.e., `guard` is dropped).
235247
unsafe {
236248
let mut count = 0;
237249
while let Some(entry) = guard.queue.inner.pop() {

src/librustdoc/html/static/js/search.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1555,7 +1555,7 @@ function initSearch(rawSearchIndex) {
15551555
return false;
15561556
}
15571557
}
1558-
} else if (fnType.id !== null) {
1558+
} else {
15591559
if (queryElem.id === typeNameIdOfArrayOrSlice &&
15601560
(fnType.id === typeNameIdOfSlice || fnType.id === typeNameIdOfArray)
15611561
) {

tests/rustdoc-js/impl-trait.js

+14-5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// exact-check
12
// ignore-order
23

34
const EXPECTED = [
@@ -20,9 +21,16 @@ const EXPECTED = [
2021
{
2122
'query': '-> Aaaaaaa',
2223
'others': [
23-
{ 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
24-
{ 'path': 'impl_trait::Ccccccc', 'name': 'ddddddd' },
2524
{ 'path': 'impl_trait', 'name': 'bbbbbbb' },
25+
{ 'path': 'impl_trait::Ccccccc', 'name': 'ddddddd' },
26+
{ 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
27+
{ 'path': 'impl_trait::Ccccccc', 'name': 'ggggggg' },
28+
],
29+
},
30+
{
31+
'query': '-> Bbbbbbb',
32+
'others': [
33+
{ 'path': 'impl_trait::Ccccccc', 'name': 'ggggggg' },
2634
],
2735
},
2836
{
@@ -31,13 +39,14 @@ const EXPECTED = [
3139
{ 'path': 'impl_trait', 'name': 'Aaaaaaa' },
3240
],
3341
'in_args': [
34-
{ 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
3542
{ 'path': 'impl_trait::Ccccccc', 'name': 'eeeeeee' },
43+
{ 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
3644
],
3745
'returned': [
38-
{ 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
39-
{ 'path': 'impl_trait::Ccccccc', 'name': 'ddddddd' },
4046
{ 'path': 'impl_trait', 'name': 'bbbbbbb' },
47+
{ 'path': 'impl_trait::Ccccccc', 'name': 'ddddddd' },
48+
{ 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
49+
{ 'path': 'impl_trait::Ccccccc', 'name': 'ggggggg' },
4150
],
4251
},
4352
];

tests/rustdoc-js/impl-trait.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
pub trait Aaaaaaa {}
22

3+
pub trait Bbbbbbb {}
4+
35
impl Aaaaaaa for () {}
6+
impl Bbbbbbb for () {}
47

58
pub fn bbbbbbb() -> impl Aaaaaaa {
69
()
@@ -18,4 +21,7 @@ impl Ccccccc {
1821
pub fn fffffff(&self, x: impl Aaaaaaa) -> impl Aaaaaaa {
1922
x
2023
}
24+
pub fn ggggggg(&self) -> impl Aaaaaaa + Bbbbbbb {
25+
()
26+
}
2127
}

tests/ui/consts/const-eval/nrvo.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
// run-pass
22

33
// When the NRVO is applied, the return place (`_0`) gets treated like a normal local. For example,
4-
// its address may be taken and it may be written to indirectly. Ensure that MIRI can handle this.
4+
// its address may be taken and it may be written to indirectly. Ensure that the const-eval
5+
// interpreter can handle this.
56

67
#![feature(const_mut_refs)]
78

0 commit comments

Comments
 (0)