Skip to content

Commit f9a322a

Browse files
committed
Auto merge of #76678 - jonas-schievink:rollup-vzl9yhx, r=jonas-schievink
Rollup of 12 pull requests Successful merges: - #75559 (unions: test move behavior of non-Copy fields) - #76441 (Note that parallel-compiler = true causes tests to fail) - #76527 (Remove internal and unstable MaybeUninit::UNINIT.) - #76629 (Simplify iter zip struct doc) - #76640 (Simplify SyncOnceCell's `take` and `drop`.) - #76646 (Add mailmap entry) - #76651 (Remove Windows details from Unix and VmWorks symlink() docstrings) - #76663 (Simplify iter chain struct doc) - #76665 (slice::from_raw_parts: explicitly mention that data must be initialized) - #76667 (Fix CI LLVM to work on NixOS out of the box) - #76668 (Add visualization of rustc span in doc) - #76677 (note that test_stable_pointers does not reflect a stable guarantee) Failed merges: r? `@ghost`
2 parents 7402a39 + fe716d0 commit f9a322a

File tree

18 files changed

+148
-69
lines changed

18 files changed

+148
-69
lines changed

.mailmap

+3
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ Chris C Cerami <[email protected]> Chris C Cerami <chrisccer
5555
Chris Pressey <[email protected]>
5656
Chris Thorn <[email protected]> Chris Thorn <[email protected]>
5757
Chris Vittal <[email protected]> Christopher Vittal <[email protected]>
58+
59+
Christiaan Dirkx <[email protected]> CDirkx <[email protected]>
60+
Christiaan Dirkx <[email protected]> CDirkx <[email protected]>
5861
5962
6063

compiler/rustc_span/src/lib.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,12 @@ impl Span {
544544
}
545545

546546
/// Returns a `Span` that would enclose both `self` and `end`.
547+
///
548+
/// ```text
549+
/// ____ ___
550+
/// self lorem ipsum end
551+
/// ^^^^^^^^^^^^^^^^^^^^
552+
/// ```
547553
pub fn to(self, end: Span) -> Span {
548554
let span_data = self.data();
549555
let end_data = end.data();
@@ -567,6 +573,12 @@ impl Span {
567573
}
568574

569575
/// Returns a `Span` between the end of `self` to the beginning of `end`.
576+
///
577+
/// ```text
578+
/// ____ ___
579+
/// self lorem ipsum end
580+
/// ^^^^^^^^^^^^^
581+
/// ```
570582
pub fn between(self, end: Span) -> Span {
571583
let span = self.data();
572584
let end = end.data();
@@ -577,7 +589,13 @@ impl Span {
577589
)
578590
}
579591

580-
/// Returns a `Span` between the beginning of `self` to the beginning of `end`.
592+
/// Returns a `Span` from the beginning of `self` until the beginning of `end`.
593+
///
594+
/// ```text
595+
/// ____ ___
596+
/// self lorem ipsum end
597+
/// ^^^^^^^^^^^^^^^^^
598+
/// ```
581599
pub fn until(self, end: Span) -> Span {
582600
let span = self.data();
583601
let end = end.data();

config.toml.example

+1
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@
393393
#incremental = false
394394

395395
# Build a multi-threaded rustc
396+
# FIXME(#75760): Some UI tests fail when this option is enabled.
396397
#parallel-compiler = false
397398

398399
# The default linker that will be hard-coded into the generated compiler for

library/alloc/src/collections/btree/node.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ impl<K, V> LeafNode<K, V> {
7878
LeafNode {
7979
// As a general policy, we leave fields uninitialized if they can be, as this should
8080
// be both slightly faster and easier to track in Valgrind.
81-
keys: [MaybeUninit::UNINIT; CAPACITY],
82-
vals: [MaybeUninit::UNINIT; CAPACITY],
81+
keys: MaybeUninit::uninit_array(),
82+
vals: MaybeUninit::uninit_array(),
8383
parent: ptr::null(),
8484
parent_idx: MaybeUninit::uninit(),
8585
len: 0,
@@ -111,7 +111,7 @@ impl<K, V> InternalNode<K, V> {
111111
/// `len` of 0), there must be one initialized and valid edge. This function does not set up
112112
/// such an edge.
113113
unsafe fn new() -> Self {
114-
InternalNode { data: unsafe { LeafNode::new() }, edges: [MaybeUninit::UNINIT; 2 * B] }
114+
InternalNode { data: unsafe { LeafNode::new() }, edges: MaybeUninit::uninit_array() }
115115
}
116116
}
117117

library/alloc/src/lib.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@
100100
#![feature(fn_traits)]
101101
#![feature(fundamental)]
102102
#![feature(inplace_iteration)]
103-
#![feature(internal_uninit_const)]
104103
#![feature(lang_items)]
105104
#![feature(layout_for_ptr)]
106105
#![feature(libc)]
@@ -135,7 +134,7 @@
135134
#![feature(unsized_locals)]
136135
#![feature(allocator_internals)]
137136
#![feature(slice_partition_dedup)]
138-
#![feature(maybe_uninit_extra, maybe_uninit_slice)]
137+
#![feature(maybe_uninit_extra, maybe_uninit_slice, maybe_uninit_uninit_array)]
139138
#![feature(alloc_layout_extra)]
140139
#![feature(trusted_random_access)]
141140
#![feature(try_trait)]

library/alloc/tests/vec.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1511,6 +1511,9 @@ fn test_stable_pointers() {
15111511
// Test that, if we reserved enough space, adding and removing elements does not
15121512
// invalidate references into the vector (such as `v0`). This test also
15131513
// runs in Miri, which would detect such problems.
1514+
// Note that this test does *not* constitute a stable guarantee that all these functions do not
1515+
// reallocate! Only what is explicitly documented at
1516+
// <https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#guarantees> is stably guaranteed.
15141517
let mut v = Vec::with_capacity(128);
15151518
v.push(13);
15161519

library/core/src/iter/adapters/chain.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,8 @@ use crate::usize;
44

55
/// An iterator that links two iterators together, in a chain.
66
///
7-
/// This `struct` is created by the [`chain`] method on [`Iterator`]. See its
8-
/// documentation for more.
9-
///
10-
/// [`chain`]: trait.Iterator.html#method.chain
11-
/// [`Iterator`]: trait.Iterator.html
7+
/// This `struct` is created by [`Iterator::chain`]. See its documentation
8+
/// for more.
129
#[derive(Clone, Debug)]
1310
#[must_use = "iterators are lazy and do nothing unless consumed"]
1411
#[stable(feature = "rust1", since = "1.0.0")]

library/core/src/iter/adapters/zip.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,8 @@ use super::super::{
88

99
/// An iterator that iterates two other iterators simultaneously.
1010
///
11-
/// This `struct` is created by the [`zip`] method on [`Iterator`]. See its
12-
/// documentation for more.
13-
///
14-
/// [`zip`]: trait.Iterator.html#method.zip
15-
/// [`Iterator`]: trait.Iterator.html
11+
/// This `struct` is created by [`Iterator::zip`]. See its documentation
12+
/// for more.
1613
#[derive(Clone)]
1714
#[must_use = "iterators are lazy and do nothing unless consumed"]
1815
#[stable(feature = "rust1", since = "1.0.0")]

library/core/src/mem/maybe_uninit.rs

-8
Original file line numberDiff line numberDiff line change
@@ -306,14 +306,6 @@ impl<T> MaybeUninit<T> {
306306
unsafe { MaybeUninit::<[MaybeUninit<T>; LEN]>::uninit().assume_init() }
307307
}
308308

309-
/// A promotable constant, equivalent to `uninit()`.
310-
#[unstable(
311-
feature = "internal_uninit_const",
312-
issue = "none",
313-
reason = "hack to work around promotability"
314-
)]
315-
pub const UNINIT: Self = Self::uninit();
316-
317309
/// Creates a new `MaybeUninit<T>` in an uninitialized state, with the memory being
318310
/// filled with `0` bytes. It depends on `T` whether that already makes for
319311
/// proper initialization. For example, `MaybeUninit<usize>::zeroed()` is initialized,

library/core/src/slice/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -6680,6 +6680,8 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {
66806680
/// them from other data. You can obtain a pointer that is usable as `data`
66816681
/// for zero-length slices using [`NonNull::dangling()`].
66826682
///
6683+
/// * `data` must point to `len` consecutive properly initialized values of type `T`.
6684+
///
66836685
/// * The memory referenced by the returned slice must not be mutated for the duration
66846686
/// of lifetime `'a`, except inside an `UnsafeCell`.
66856687
///
@@ -6767,6 +6769,8 @@ pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
67676769
/// them from other data. You can obtain a pointer that is usable as `data`
67686770
/// for zero-length slices using [`NonNull::dangling()`].
67696771
///
6772+
/// * `data` must point to `len` consecutive properly initialized values of type `T`.
6773+
///
67706774
/// * The memory referenced by the returned slice must not be accessed through any other pointer
67716775
/// (not derived from the return value) for the duration of lifetime `'a`.
67726776
/// Both read and write accesses are forbidden.

library/std/src/lazy.rs

+13-26
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::{
77
cell::{Cell, UnsafeCell},
88
fmt,
99
marker::PhantomData,
10-
mem::{self, MaybeUninit},
10+
mem::MaybeUninit,
1111
ops::{Deref, Drop},
1212
panic::{RefUnwindSafe, UnwindSafe},
1313
sync::Once,
@@ -316,13 +316,7 @@ impl<T> SyncOnceCell<T> {
316316
/// ```
317317
#[unstable(feature = "once_cell", issue = "74465")]
318318
pub fn into_inner(mut self) -> Option<T> {
319-
// SAFETY: Safe because we immediately free `self` without dropping
320-
let inner = unsafe { self.take_inner() };
321-
322-
// Don't drop this `SyncOnceCell`. We just moved out one of the fields, but didn't set
323-
// the state to uninitialized.
324-
mem::forget(self);
325-
inner
319+
self.take()
326320
}
327321

328322
/// Takes the value out of this `SyncOnceCell`, moving it back to an uninitialized state.
@@ -348,22 +342,12 @@ impl<T> SyncOnceCell<T> {
348342
/// ```
349343
#[unstable(feature = "once_cell", issue = "74465")]
350344
pub fn take(&mut self) -> Option<T> {
351-
mem::take(self).into_inner()
352-
}
353-
354-
/// Takes the wrapped value out of a `SyncOnceCell`.
355-
/// Afterwards the cell is no longer initialized.
356-
///
357-
/// Safety: The cell must now be free'd WITHOUT dropping. No other usages of the cell
358-
/// are valid. Only used by `into_inner` and `drop`.
359-
unsafe fn take_inner(&mut self) -> Option<T> {
360-
// The mutable reference guarantees there are no other threads that can observe us
361-
// taking out the wrapped value.
362-
// Right after this function `self` is supposed to be freed, so it makes little sense
363-
// to atomically set the state to uninitialized.
364345
if self.is_initialized() {
365-
let value = mem::replace(&mut self.value, UnsafeCell::new(MaybeUninit::uninit()));
366-
Some(value.into_inner().assume_init())
346+
self.once = Once::new();
347+
// SAFETY: `self.value` is initialized and contains a valid `T`.
348+
// `self.once` is reset, so `is_initialized()` will be false again
349+
// which prevents the value from being read twice.
350+
unsafe { Some((&mut *self.value.get()).assume_init_read()) }
367351
} else {
368352
None
369353
}
@@ -416,9 +400,12 @@ impl<T> SyncOnceCell<T> {
416400

417401
unsafe impl<#[may_dangle] T> Drop for SyncOnceCell<T> {
418402
fn drop(&mut self) {
419-
// SAFETY: The cell is being dropped, so it can't be accessed again.
420-
// We also don't touch the `T`, which validates our usage of #[may_dangle].
421-
unsafe { self.take_inner() };
403+
if self.is_initialized() {
404+
// Safety: The cell is initialized and being dropped, so it can't
405+
// be accessed again. We also don't touch the `T` other than
406+
// dropping it, which validates our usage of #[may_dangle].
407+
unsafe { (&mut *self.value.get()).assume_init_drop() };
408+
}
422409
}
423410
}
424411

library/std/src/sync/once.rs

+1
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ struct WaiterQueue<'a> {
191191

192192
impl Once {
193193
/// Creates a new `Once` value.
194+
#[inline]
194195
#[stable(feature = "once_new", since = "1.2.0")]
195196
#[rustc_const_stable(feature = "const_once_new", since = "1.32.0")]
196197
pub const fn new() -> Once {

library/std/src/sys/unix/ext/fs.rs

-9
Original file line numberDiff line numberDiff line change
@@ -836,15 +836,6 @@ impl DirEntryExt for fs::DirEntry {
836836
///
837837
/// The `dst` path will be a symbolic link pointing to the `src` path.
838838
///
839-
/// # Note
840-
///
841-
/// On Windows, you must specify whether a symbolic link points to a file
842-
/// or directory. Use `os::windows::fs::symlink_file` to create a
843-
/// symbolic link to a file, or `os::windows::fs::symlink_dir` to create a
844-
/// symbolic link to a directory. Additionally, the process must have
845-
/// `SeCreateSymbolicLinkPrivilege` in order to be able to create a
846-
/// symbolic link.
847-
///
848839
/// # Examples
849840
///
850841
/// ```no_run

library/std/src/sys/vxworks/ext/fs.rs

-9
Original file line numberDiff line numberDiff line change
@@ -774,15 +774,6 @@ impl DirEntryExt for fs::DirEntry {
774774
///
775775
/// The `dst` path will be a symbolic link pointing to the `src` path.
776776
///
777-
/// # Note
778-
///
779-
/// On Windows, you must specify whether a symbolic link points to a file
780-
/// or directory. Use `os::windows::fs::symlink_file` to create a
781-
/// symbolic link to a file, or `os::windows::fs::symlink_dir` to create a
782-
/// symbolic link to a directory. Additionally, the process must have
783-
/// `SeCreateSymbolicLinkPrivilege` in order to be able to create a
784-
/// symbolic link.
785-
///
786777
/// # Examples
787778
///
788779
/// ```no_run

src/bootstrap/bootstrap.py

+2
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,8 @@ def download_stage0(self):
429429
llvm_assertions = self.get_toml('assertions', 'llvm') == 'true'
430430
if self.program_out_of_date(self.llvm_stamp(), llvm_sha + str(llvm_assertions)):
431431
self._download_ci_llvm(llvm_sha, llvm_assertions)
432+
for binary in ["llvm-config", "FileCheck"]:
433+
self.fix_bin_or_dylib("{}/bin/{}".format(self.llvm_root(), binary))
432434
with output(self.llvm_stamp()) as llvm_stamp:
433435
llvm_stamp.write(self.date + llvm_sha + str(llvm_assertions))
434436

src/test/ui/union/union-drop.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ fn main() {
4848
{
4949
let y = Y { a: S };
5050
}
51-
assert_eq!(CHECK, 2); // 2, dtor of Y is called
51+
assert_eq!(CHECK, 2); // 2, Y has no dtor
52+
{
53+
let u2 = U { a: 1 };
54+
std::mem::forget(u2);
55+
}
56+
assert_eq!(CHECK, 2); // 2, dtor of U *not* called for u2
5257
}
5358
}

src/test/ui/union/union-move.rs

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//! Test the behavior of moving out of non-`Copy` union fields.
2+
//! Avoid types that `Drop`, we want to focus on moving.
3+
#![feature(untagged_unions)]
4+
5+
use std::cell::RefCell;
6+
7+
fn move_out<T>(x: T) {}
8+
9+
union U1 {
10+
f1_nocopy: RefCell<i32>,
11+
f2_nocopy: RefCell<i32>,
12+
f3_copy: i32,
13+
}
14+
15+
union U2 {
16+
f1_nocopy: RefCell<i32>,
17+
}
18+
impl Drop for U2 {
19+
fn drop(&mut self) {}
20+
}
21+
22+
fn test1(x: U1) {
23+
// Moving out of a nocopy field prevents accessing other nocopy field.
24+
unsafe {
25+
move_out(x.f1_nocopy);
26+
move_out(x.f2_nocopy); //~ ERROR use of moved value: `x`
27+
}
28+
}
29+
30+
fn test2(x: U1) {
31+
// "Moving" out of copy field doesn't prevent later field accesses.
32+
unsafe {
33+
move_out(x.f3_copy);
34+
move_out(x.f2_nocopy); // no error
35+
}
36+
}
37+
38+
fn test3(x: U1) {
39+
// Moving out of a nocopy field prevents accessing other copy field.
40+
unsafe {
41+
move_out(x.f2_nocopy);
42+
move_out(x.f3_copy); //~ ERROR use of moved value: `x`
43+
}
44+
}
45+
46+
fn test4(x: U2) {
47+
// Cannot move out of union that implements `Drop`.
48+
unsafe {
49+
move_out(x.f1_nocopy); //~ ERROR cannot move out of type `U2`, which implements the `Drop`
50+
}
51+
}
52+
53+
fn main() {}

src/test/ui/union/union-move.stderr

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
error[E0382]: use of moved value: `x`
2+
--> $DIR/union-move.rs:26:18
3+
|
4+
LL | fn test1(x: U1) {
5+
| - move occurs because `x` has type `U1`, which does not implement the `Copy` trait
6+
...
7+
LL | move_out(x.f1_nocopy);
8+
| ----------- value moved here
9+
LL | move_out(x.f2_nocopy);
10+
| ^^^^^^^^^^^ value used here after move
11+
12+
error[E0382]: use of moved value: `x`
13+
--> $DIR/union-move.rs:42:18
14+
|
15+
LL | fn test3(x: U1) {
16+
| - move occurs because `x` has type `U1`, which does not implement the `Copy` trait
17+
...
18+
LL | move_out(x.f2_nocopy);
19+
| ----------- value moved here
20+
LL | move_out(x.f3_copy);
21+
| ^^^^^^^^^ value used here after move
22+
23+
error[E0509]: cannot move out of type `U2`, which implements the `Drop` trait
24+
--> $DIR/union-move.rs:49:18
25+
|
26+
LL | move_out(x.f1_nocopy);
27+
| ^^^^^^^^^^^
28+
| |
29+
| cannot move out of here
30+
| move occurs because `x.f1_nocopy` has type `RefCell<i32>`, which does not implement the `Copy` trait
31+
32+
error: aborting due to 3 previous errors
33+
34+
Some errors have detailed explanations: E0382, E0509.
35+
For more information about an error, try `rustc --explain E0382`.

0 commit comments

Comments
 (0)