about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-09-13 22:34:09 +0000
committerbors <bors@rust-lang.org>2020-09-13 22:34:09 +0000
commitf9a322a6fdd1e12fbe30441feaa4402e23efe303 (patch)
treea81dee2e5024531545a22108aabc1d7415776f49
parent7402a394471a6738a40fea7d4f1891666e5a80c5 (diff)
parentfe716d0447208825de8ddb815b31905d905950c7 (diff)
downloadrust-f9a322a6fdd1e12fbe30441feaa4402e23efe303.tar.gz
rust-f9a322a6fdd1e12fbe30441feaa4402e23efe303.zip
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`
-rw-r--r--.mailmap3
-rw-r--r--compiler/rustc_span/src/lib.rs20
-rw-r--r--config.toml.example1
-rw-r--r--library/alloc/src/collections/btree/node.rs6
-rw-r--r--library/alloc/src/lib.rs3
-rw-r--r--library/alloc/tests/vec.rs3
-rw-r--r--library/core/src/iter/adapters/chain.rs7
-rw-r--r--library/core/src/iter/adapters/zip.rs7
-rw-r--r--library/core/src/mem/maybe_uninit.rs8
-rw-r--r--library/core/src/slice/mod.rs4
-rw-r--r--library/std/src/lazy.rs39
-rw-r--r--library/std/src/sync/once.rs1
-rw-r--r--library/std/src/sys/unix/ext/fs.rs9
-rw-r--r--library/std/src/sys/vxworks/ext/fs.rs9
-rw-r--r--src/bootstrap/bootstrap.py2
-rw-r--r--src/test/ui/union/union-drop.rs7
-rw-r--r--src/test/ui/union/union-move.rs53
-rw-r--r--src/test/ui/union/union-move.stderr35
18 files changed, 148 insertions, 69 deletions
diff --git a/.mailmap b/.mailmap
index cc7b2a677ba..fa0728bd794 100644
--- a/.mailmap
+++ b/.mailmap
@@ -55,6 +55,9 @@ Chris C Cerami <chrisccerami@users.noreply.github.com> Chris C Cerami <chrisccer
 Chris Pressey <cpressey@gmail.com>
 Chris Thorn <chris@thorn.co> Chris Thorn <thorn@thoughtbot.com>
 Chris Vittal <christopher.vittal@gmail.com> Christopher Vittal <christopher.vittal@gmail.com>
+Christiaan Dirkx <christiaan@dirkx.email> <christiaan@dirkx.com>
+Christiaan Dirkx <christiaan@dirkx.email> CDirkx <christiaan@dirkx.com>
+Christiaan Dirkx <christiaan@dirkx.email> CDirkx <christiaan@dirkx.email>
 Christian Poveda <git@christianpoveda.xyz> <christianpoveda@protonmail.com>
 Christian Poveda <git@christianpoveda.xyz> <cn.poveda.ruiz@gmail.com>
 Christian Poveda <git@christianpoveda.xyz> <z1mvader@protonmail.com>
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index b478a1d15c5..e38cd516b91 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -544,6 +544,12 @@ impl Span {
     }
 
     /// Returns a `Span` that would enclose both `self` and `end`.
+    ///
+    /// ```text
+    ///     ____             ___
+    ///     self lorem ipsum end
+    ///     ^^^^^^^^^^^^^^^^^^^^
+    /// ```
     pub fn to(self, end: Span) -> Span {
         let span_data = self.data();
         let end_data = end.data();
@@ -567,6 +573,12 @@ impl Span {
     }
 
     /// Returns a `Span` between the end of `self` to the beginning of `end`.
+    ///
+    /// ```text
+    ///     ____             ___
+    ///     self lorem ipsum end
+    ///         ^^^^^^^^^^^^^
+    /// ```
     pub fn between(self, end: Span) -> Span {
         let span = self.data();
         let end = end.data();
@@ -577,7 +589,13 @@ impl Span {
         )
     }
 
-    /// Returns a `Span` between the beginning of `self` to the beginning of `end`.
+    /// Returns a `Span` from the beginning of `self` until the beginning of `end`.
+    ///
+    /// ```text
+    ///     ____             ___
+    ///     self lorem ipsum end
+    ///     ^^^^^^^^^^^^^^^^^
+    /// ```
     pub fn until(self, end: Span) -> Span {
         let span = self.data();
         let end = end.data();
diff --git a/config.toml.example b/config.toml.example
index 39c94d41e3a..9135843045a 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -393,6 +393,7 @@
 #incremental = false
 
 # Build a multi-threaded rustc
+# FIXME(#75760): Some UI tests fail when this option is enabled.
 #parallel-compiler = false
 
 # The default linker that will be hard-coded into the generated compiler for
diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs
index 8832619a404..6c343b17264 100644
--- a/library/alloc/src/collections/btree/node.rs
+++ b/library/alloc/src/collections/btree/node.rs
@@ -78,8 +78,8 @@ impl<K, V> LeafNode<K, V> {
         LeafNode {
             // As a general policy, we leave fields uninitialized if they can be, as this should
             // be both slightly faster and easier to track in Valgrind.
-            keys: [MaybeUninit::UNINIT; CAPACITY],
-            vals: [MaybeUninit::UNINIT; CAPACITY],
+            keys: MaybeUninit::uninit_array(),
+            vals: MaybeUninit::uninit_array(),
             parent: ptr::null(),
             parent_idx: MaybeUninit::uninit(),
             len: 0,
@@ -111,7 +111,7 @@ impl<K, V> InternalNode<K, V> {
     /// `len` of 0), there must be one initialized and valid edge. This function does not set up
     /// such an edge.
     unsafe fn new() -> Self {
-        InternalNode { data: unsafe { LeafNode::new() }, edges: [MaybeUninit::UNINIT; 2 * B] }
+        InternalNode { data: unsafe { LeafNode::new() }, edges: MaybeUninit::uninit_array() }
     }
 }
 
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 48313f9af98..5774ebb9b19 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -100,7 +100,6 @@
 #![feature(fn_traits)]
 #![feature(fundamental)]
 #![feature(inplace_iteration)]
-#![feature(internal_uninit_const)]
 #![feature(lang_items)]
 #![feature(layout_for_ptr)]
 #![feature(libc)]
@@ -135,7 +134,7 @@
 #![feature(unsized_locals)]
 #![feature(allocator_internals)]
 #![feature(slice_partition_dedup)]
-#![feature(maybe_uninit_extra, maybe_uninit_slice)]
+#![feature(maybe_uninit_extra, maybe_uninit_slice, maybe_uninit_uninit_array)]
 #![feature(alloc_layout_extra)]
 #![feature(trusted_random_access)]
 #![feature(try_trait)]
diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs
index 53b0d0a2718..5f7a9399453 100644
--- a/library/alloc/tests/vec.rs
+++ b/library/alloc/tests/vec.rs
@@ -1511,6 +1511,9 @@ fn test_stable_pointers() {
     // Test that, if we reserved enough space, adding and removing elements does not
     // invalidate references into the vector (such as `v0`).  This test also
     // runs in Miri, which would detect such problems.
+    // Note that this test does *not* constitute a stable guarantee that all these functions do not
+    // reallocate! Only what is explicitly documented at
+    // <https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#guarantees> is stably guaranteed.
     let mut v = Vec::with_capacity(128);
     v.push(13);
 
diff --git a/library/core/src/iter/adapters/chain.rs b/library/core/src/iter/adapters/chain.rs
index 6700ef017bd..13c6a75d58b 100644
--- a/library/core/src/iter/adapters/chain.rs
+++ b/library/core/src/iter/adapters/chain.rs
@@ -4,11 +4,8 @@ use crate::usize;
 
 /// An iterator that links two iterators together, in a chain.
 ///
-/// This `struct` is created by the [`chain`] method on [`Iterator`]. See its
-/// documentation for more.
-///
-/// [`chain`]: trait.Iterator.html#method.chain
-/// [`Iterator`]: trait.Iterator.html
+/// This `struct` is created by [`Iterator::chain`]. See its documentation
+/// for more.
 #[derive(Clone, Debug)]
 #[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/core/src/iter/adapters/zip.rs b/library/core/src/iter/adapters/zip.rs
index e02de0ce45d..a854f70dcd0 100644
--- a/library/core/src/iter/adapters/zip.rs
+++ b/library/core/src/iter/adapters/zip.rs
@@ -8,11 +8,8 @@ use super::super::{
 
 /// An iterator that iterates two other iterators simultaneously.
 ///
-/// This `struct` is created by the [`zip`] method on [`Iterator`]. See its
-/// documentation for more.
-///
-/// [`zip`]: trait.Iterator.html#method.zip
-/// [`Iterator`]: trait.Iterator.html
+/// This `struct` is created by [`Iterator::zip`]. See its documentation
+/// for more.
 #[derive(Clone)]
 #[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index b0ebaa6a12b..e629d28eae1 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -306,14 +306,6 @@ impl<T> MaybeUninit<T> {
         unsafe { MaybeUninit::<[MaybeUninit<T>; LEN]>::uninit().assume_init() }
     }
 
-    /// A promotable constant, equivalent to `uninit()`.
-    #[unstable(
-        feature = "internal_uninit_const",
-        issue = "none",
-        reason = "hack to work around promotability"
-    )]
-    pub const UNINIT: Self = Self::uninit();
-
     /// Creates a new `MaybeUninit<T>` in an uninitialized state, with the memory being
     /// filled with `0` bytes. It depends on `T` whether that already makes for
     /// proper initialization. For example, `MaybeUninit<usize>::zeroed()` is initialized,
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 4c027b23584..3ff33fab431 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -6680,6 +6680,8 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {
 ///       them from other data. You can obtain a pointer that is usable as `data`
 ///       for zero-length slices using [`NonNull::dangling()`].
 ///
+/// * `data` must point to `len` consecutive properly initialized values of type `T`.
+///
 /// * The memory referenced by the returned slice must not be mutated for the duration
 ///   of lifetime `'a`, except inside an `UnsafeCell`.
 ///
@@ -6767,6 +6769,8 @@ pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
 ///       them from other data. You can obtain a pointer that is usable as `data`
 ///       for zero-length slices using [`NonNull::dangling()`].
 ///
+/// * `data` must point to `len` consecutive properly initialized values of type `T`.
+///
 /// * The memory referenced by the returned slice must not be accessed through any other pointer
 ///   (not derived from the return value) for the duration of lifetime `'a`.
 ///   Both read and write accesses are forbidden.
diff --git a/library/std/src/lazy.rs b/library/std/src/lazy.rs
index 091e2091fb0..e0095e64faf 100644
--- a/library/std/src/lazy.rs
+++ b/library/std/src/lazy.rs
@@ -7,7 +7,7 @@ use crate::{
     cell::{Cell, UnsafeCell},
     fmt,
     marker::PhantomData,
-    mem::{self, MaybeUninit},
+    mem::MaybeUninit,
     ops::{Deref, Drop},
     panic::{RefUnwindSafe, UnwindSafe},
     sync::Once,
@@ -316,13 +316,7 @@ impl<T> SyncOnceCell<T> {
     /// ```
     #[unstable(feature = "once_cell", issue = "74465")]
     pub fn into_inner(mut self) -> Option<T> {
-        // SAFETY: Safe because we immediately free `self` without dropping
-        let inner = unsafe { self.take_inner() };
-
-        // Don't drop this `SyncOnceCell`. We just moved out one of the fields, but didn't set
-        // the state to uninitialized.
-        mem::forget(self);
-        inner
+        self.take()
     }
 
     /// Takes the value out of this `SyncOnceCell`, moving it back to an uninitialized state.
@@ -348,22 +342,12 @@ impl<T> SyncOnceCell<T> {
     /// ```
     #[unstable(feature = "once_cell", issue = "74465")]
     pub fn take(&mut self) -> Option<T> {
-        mem::take(self).into_inner()
-    }
-
-    /// Takes the wrapped value out of a `SyncOnceCell`.
-    /// Afterwards the cell is no longer initialized.
-    ///
-    /// Safety: The cell must now be free'd WITHOUT dropping. No other usages of the cell
-    /// are valid. Only used by `into_inner` and `drop`.
-    unsafe fn take_inner(&mut self) -> Option<T> {
-        // The mutable reference guarantees there are no other threads that can observe us
-        // taking out the wrapped value.
-        // Right after this function `self` is supposed to be freed, so it makes little sense
-        // to atomically set the state to uninitialized.
         if self.is_initialized() {
-            let value = mem::replace(&mut self.value, UnsafeCell::new(MaybeUninit::uninit()));
-            Some(value.into_inner().assume_init())
+            self.once = Once::new();
+            // SAFETY: `self.value` is initialized and contains a valid `T`.
+            // `self.once` is reset, so `is_initialized()` will be false again
+            // which prevents the value from being read twice.
+            unsafe { Some((&mut *self.value.get()).assume_init_read()) }
         } else {
             None
         }
@@ -416,9 +400,12 @@ impl<T> SyncOnceCell<T> {
 
 unsafe impl<#[may_dangle] T> Drop for SyncOnceCell<T> {
     fn drop(&mut self) {
-        // SAFETY: The cell is being dropped, so it can't be accessed again.
-        // We also don't touch the `T`, which validates our usage of #[may_dangle].
-        unsafe { self.take_inner() };
+        if self.is_initialized() {
+            // Safety: The cell is initialized and being dropped, so it can't
+            // be accessed again. We also don't touch the `T` other than
+            // dropping it, which validates our usage of #[may_dangle].
+            unsafe { (&mut *self.value.get()).assume_init_drop() };
+        }
     }
 }
 
diff --git a/library/std/src/sync/once.rs b/library/std/src/sync/once.rs
index 8fed369bffc..29ae338cb2e 100644
--- a/library/std/src/sync/once.rs
+++ b/library/std/src/sync/once.rs
@@ -191,6 +191,7 @@ struct WaiterQueue<'a> {
 
 impl Once {
     /// Creates a new `Once` value.
+    #[inline]
     #[stable(feature = "once_new", since = "1.2.0")]
     #[rustc_const_stable(feature = "const_once_new", since = "1.32.0")]
     pub const fn new() -> Once {
diff --git a/library/std/src/sys/unix/ext/fs.rs b/library/std/src/sys/unix/ext/fs.rs
index 487ac266ee9..4b9f4ceb29c 100644
--- a/library/std/src/sys/unix/ext/fs.rs
+++ b/library/std/src/sys/unix/ext/fs.rs
@@ -836,15 +836,6 @@ impl DirEntryExt for fs::DirEntry {
 ///
 /// The `dst` path will be a symbolic link pointing to the `src` path.
 ///
-/// # Note
-///
-/// On Windows, you must specify whether a symbolic link points to a file
-/// or directory. Use `os::windows::fs::symlink_file` to create a
-/// symbolic link to a file, or `os::windows::fs::symlink_dir` to create a
-/// symbolic link to a directory. Additionally, the process must have
-/// `SeCreateSymbolicLinkPrivilege` in order to be able to create a
-/// symbolic link.
-///
 /// # Examples
 ///
 /// ```no_run
diff --git a/library/std/src/sys/vxworks/ext/fs.rs b/library/std/src/sys/vxworks/ext/fs.rs
index 9b4c64bdb6d..68dc21b806c 100644
--- a/library/std/src/sys/vxworks/ext/fs.rs
+++ b/library/std/src/sys/vxworks/ext/fs.rs
@@ -774,15 +774,6 @@ impl DirEntryExt for fs::DirEntry {
 ///
 /// The `dst` path will be a symbolic link pointing to the `src` path.
 ///
-/// # Note
-///
-/// On Windows, you must specify whether a symbolic link points to a file
-/// or directory.  Use `os::windows::fs::symlink_file` to create a
-/// symbolic link to a file, or `os::windows::fs::symlink_dir` to create a
-/// symbolic link to a directory.  Additionally, the process must have
-/// `SeCreateSymbolicLinkPrivilege` in order to be able to create a
-/// symbolic link.
-///
 /// # Examples
 ///
 /// ```no_run
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 44a17f75451..5f78031e1c7 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -429,6 +429,8 @@ class RustBuild(object):
             llvm_assertions = self.get_toml('assertions', 'llvm') == 'true'
             if self.program_out_of_date(self.llvm_stamp(), llvm_sha + str(llvm_assertions)):
                 self._download_ci_llvm(llvm_sha, llvm_assertions)
+                for binary in ["llvm-config", "FileCheck"]:
+                    self.fix_bin_or_dylib("{}/bin/{}".format(self.llvm_root(), binary))
                 with output(self.llvm_stamp()) as llvm_stamp:
                     llvm_stamp.write(self.date + llvm_sha + str(llvm_assertions))
 
diff --git a/src/test/ui/union/union-drop.rs b/src/test/ui/union/union-drop.rs
index daa03ce6b6f..4df3ed50282 100644
--- a/src/test/ui/union/union-drop.rs
+++ b/src/test/ui/union/union-drop.rs
@@ -48,6 +48,11 @@ fn main() {
         {
             let y = Y { a: S };
         }
-        assert_eq!(CHECK, 2); // 2, dtor of Y is called
+        assert_eq!(CHECK, 2); // 2, Y has no dtor
+        {
+            let u2 = U { a: 1 };
+            std::mem::forget(u2);
+        }
+        assert_eq!(CHECK, 2); // 2, dtor of U *not* called for u2
     }
 }
diff --git a/src/test/ui/union/union-move.rs b/src/test/ui/union/union-move.rs
new file mode 100644
index 00000000000..a0a2d0d6598
--- /dev/null
+++ b/src/test/ui/union/union-move.rs
@@ -0,0 +1,53 @@
+//! Test the behavior of moving out of non-`Copy` union fields.
+//! Avoid types that `Drop`, we want to focus on moving.
+#![feature(untagged_unions)]
+
+use std::cell::RefCell;
+
+fn move_out<T>(x: T) {}
+
+union U1 {
+    f1_nocopy: RefCell<i32>,
+    f2_nocopy: RefCell<i32>,
+    f3_copy: i32,
+}
+
+union U2 {
+    f1_nocopy: RefCell<i32>,
+}
+impl Drop for U2 {
+    fn drop(&mut self) {}
+}
+
+fn test1(x: U1) {
+    // Moving out of a nocopy field prevents accessing other nocopy field.
+    unsafe {
+        move_out(x.f1_nocopy);
+        move_out(x.f2_nocopy); //~ ERROR use of moved value: `x`
+    }
+}
+
+fn test2(x: U1) {
+    // "Moving" out of copy field doesn't prevent later field accesses.
+    unsafe {
+        move_out(x.f3_copy);
+        move_out(x.f2_nocopy); // no error
+    }
+}
+
+fn test3(x: U1) {
+    // Moving out of a nocopy field prevents accessing other copy field.
+    unsafe {
+        move_out(x.f2_nocopy);
+        move_out(x.f3_copy); //~ ERROR use of moved value: `x`
+    }
+}
+
+fn test4(x: U2) {
+    // Cannot move out of union that implements `Drop`.
+    unsafe {
+        move_out(x.f1_nocopy); //~ ERROR cannot move out of type `U2`, which implements the `Drop`
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/union/union-move.stderr b/src/test/ui/union/union-move.stderr
new file mode 100644
index 00000000000..5679192b641
--- /dev/null
+++ b/src/test/ui/union/union-move.stderr
@@ -0,0 +1,35 @@
+error[E0382]: use of moved value: `x`
+  --> $DIR/union-move.rs:26:18
+   |
+LL | fn test1(x: U1) {
+   |          - move occurs because `x` has type `U1`, which does not implement the `Copy` trait
+...
+LL |         move_out(x.f1_nocopy);
+   |                  ----------- value moved here
+LL |         move_out(x.f2_nocopy);
+   |                  ^^^^^^^^^^^ value used here after move
+
+error[E0382]: use of moved value: `x`
+  --> $DIR/union-move.rs:42:18
+   |
+LL | fn test3(x: U1) {
+   |          - move occurs because `x` has type `U1`, which does not implement the `Copy` trait
+...
+LL |         move_out(x.f2_nocopy);
+   |                  ----------- value moved here
+LL |         move_out(x.f3_copy);
+   |                  ^^^^^^^^^ value used here after move
+
+error[E0509]: cannot move out of type `U2`, which implements the `Drop` trait
+  --> $DIR/union-move.rs:49:18
+   |
+LL |         move_out(x.f1_nocopy);
+   |                  ^^^^^^^^^^^
+   |                  |
+   |                  cannot move out of here
+   |                  move occurs because `x.f1_nocopy` has type `RefCell<i32>`, which does not implement the `Copy` trait
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0382, E0509.
+For more information about an error, try `rustc --explain E0382`.