about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorXAMPPRocky <4464295+XAMPPRocky@users.noreply.github.com>2020-02-26 21:39:30 +0100
committerGitHub <noreply@github.com>2020-02-26 21:39:30 +0100
commit526280a853f31bbc3120334dfe46e19ea4dbaa25 (patch)
treecd35561be4cdcd7591d98bae715726c0e40995b7 /src/libstd
parente7a344fb745a0a663e21be947b2619df05df6d31 (diff)
parentabc3073c92df034636a823c5382ece2186d22b9e (diff)
downloadrust-526280a853f31bbc3120334dfe46e19ea4dbaa25.tar.gz
rust-526280a853f31bbc3120334dfe46e19ea4dbaa25.zip
Merge branch 'master' into relnotes-1.42.0
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/Cargo.toml2
-rw-r--r--src/libstd/backtrace.rs69
-rw-r--r--src/libstd/collections/hash/map.rs126
-rw-r--r--src/libstd/collections/hash/set.rs20
-rw-r--r--src/libstd/ffi/c_str.rs27
-rw-r--r--src/libstd/fs.rs12
-rw-r--r--src/libstd/future.rs3
-rw-r--r--src/libstd/io/stdio.rs2
-rw-r--r--src/libstd/keyword_docs.rs49
-rw-r--r--src/libstd/lib.rs6
-rw-r--r--src/libstd/sync/once.rs11
-rw-r--r--src/libstd/sys/sgx/abi/entry.S40
-rw-r--r--src/libstd/sys/sgx/args.rs7
-rw-r--r--src/libstd/sys/sgx/rwlock.rs24
-rw-r--r--src/libstd/sys/unix/thread.rs5
-rw-r--r--src/libstd/sys/wasi/fd.rs12
-rw-r--r--src/libstd/sys/wasi/fs.rs10
-rw-r--r--src/libstd/sys_common/backtrace.rs1
18 files changed, 284 insertions, 142 deletions
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index c9ff93eac02..b147aa55b2a 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -27,7 +27,7 @@ hashbrown = { version = "0.6.2", default-features = false, features = ['rustc-de
 
 [dependencies.backtrace_rs]
 package = "backtrace"
-version = "0.3.37"
+version = "0.3.44"
 default-features = false # without the libstd `backtrace` feature, stub out everything
 features = [ "rustc-dep-of-std" ] # enable build support for integrating into libstd
 
diff --git a/src/libstd/backtrace.rs b/src/libstd/backtrace.rs
index 5ba1c940251..a1c9aa75d77 100644
--- a/src/libstd/backtrace.rs
+++ b/src/libstd/backtrace.rs
@@ -159,6 +159,69 @@ enum BytesOrWide {
     Wide(Vec<u16>),
 }
 
+impl fmt::Debug for Backtrace {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let mut capture = match &self.inner {
+            Inner::Unsupported => return fmt.write_str("unsupported backtrace"),
+            Inner::Disabled => return fmt.write_str("disabled backtrace"),
+            Inner::Captured(c) => c.lock().unwrap(),
+        };
+        capture.resolve();
+
+        let frames = &capture.frames[capture.actual_start..];
+
+        write!(fmt, "Backtrace ")?;
+
+        let mut dbg = fmt.debug_list();
+
+        for frame in frames {
+            if frame.frame.ip().is_null() {
+                continue;
+            }
+
+            dbg.entries(&frame.symbols);
+        }
+
+        dbg.finish()
+    }
+}
+
+impl fmt::Debug for BacktraceSymbol {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(fmt, "{{ ")?;
+
+        if let Some(fn_name) = self.name.as_ref().map(|b| backtrace::SymbolName::new(b)) {
+            write!(fmt, "fn: \"{:#}\"", fn_name)?;
+        } else {
+            write!(fmt, "fn: \"<unknown>\"")?;
+        }
+
+        if let Some(fname) = self.filename.as_ref() {
+            write!(fmt, ", file: {:?}", fname)?;
+        }
+
+        if let Some(line) = self.lineno.as_ref() {
+            write!(fmt, ", line: {:?}", line)?;
+        }
+
+        write!(fmt, " }}")
+    }
+}
+
+impl fmt::Debug for BytesOrWide {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        output_filename(
+            fmt,
+            match self {
+                BytesOrWide::Bytes(w) => BytesOrWideString::Bytes(w),
+                BytesOrWide::Wide(w) => BytesOrWideString::Wide(w),
+            },
+            backtrace::PrintFmt::Short,
+            crate::env::current_dir().as_ref().ok(),
+        )
+    }
+}
+
 impl Backtrace {
     /// Returns whether backtrace captures are enabled through environment
     /// variables.
@@ -268,12 +331,6 @@ impl Backtrace {
 
 impl fmt::Display for Backtrace {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Debug::fmt(self, fmt)
-    }
-}
-
-impl fmt::Debug for Backtrace {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
         let mut capture = match &self.inner {
             Inner::Unsupported => return fmt.write_str("unsupported backtrace"),
             Inner::Disabled => return fmt.write_str("disabled backtrace"),
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index fdc587ba5da..d0e1a01b006 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -203,7 +203,7 @@ pub struct HashMap<K, V, S = RandomState> {
     base: base::HashMap<K, V, S>,
 }
 
-impl<K: Hash + Eq, V> HashMap<K, V, RandomState> {
+impl<K, V> HashMap<K, V, RandomState> {
     /// Creates an empty `HashMap`.
     ///
     /// The hash map is initially created with a capacity of 0, so it will not allocate until it
@@ -240,6 +240,59 @@ impl<K: Hash + Eq, V> HashMap<K, V, RandomState> {
 }
 
 impl<K, V, S> HashMap<K, V, S> {
+    /// Creates an empty `HashMap` which will use the given hash builder to hash
+    /// keys.
+    ///
+    /// The created map has the default initial capacity.
+    ///
+    /// Warning: `hash_builder` is normally randomly generated, and
+    /// is designed to allow HashMaps to be resistant to attacks that
+    /// cause many collisions and very poor performance. Setting it
+    /// manually using this function can expose a DoS attack vector.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    /// use std::collections::hash_map::RandomState;
+    ///
+    /// let s = RandomState::new();
+    /// let mut map = HashMap::with_hasher(s);
+    /// map.insert(1, 2);
+    /// ```
+    #[inline]
+    #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
+    pub fn with_hasher(hash_builder: S) -> HashMap<K, V, S> {
+        HashMap { base: base::HashMap::with_hasher(hash_builder) }
+    }
+
+    /// Creates an empty `HashMap` with the specified capacity, using `hash_builder`
+    /// to hash the keys.
+    ///
+    /// The hash map will be able to hold at least `capacity` elements without
+    /// reallocating. If `capacity` is 0, the hash map will not allocate.
+    ///
+    /// Warning: `hash_builder` is normally randomly generated, and
+    /// is designed to allow HashMaps to be resistant to attacks that
+    /// cause many collisions and very poor performance. Setting it
+    /// manually using this function can expose a DoS attack vector.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    /// use std::collections::hash_map::RandomState;
+    ///
+    /// let s = RandomState::new();
+    /// let mut map = HashMap::with_capacity_and_hasher(10, s);
+    /// map.insert(1, 2);
+    /// ```
+    #[inline]
+    #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
+    pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> HashMap<K, V, S> {
+        HashMap { base: base::HashMap::with_capacity_and_hasher(capacity, hash_builder) }
+    }
+
     /// Returns the number of elements the map can hold without reallocating.
     ///
     /// This number is a lower bound; the `HashMap<K, V>` might be able to hold
@@ -457,65 +510,6 @@ impl<K, V, S> HashMap<K, V, S> {
     pub fn clear(&mut self) {
         self.base.clear();
     }
-}
-
-impl<K, V, S> HashMap<K, V, S>
-where
-    K: Eq + Hash,
-    S: BuildHasher,
-{
-    /// Creates an empty `HashMap` which will use the given hash builder to hash
-    /// keys.
-    ///
-    /// The created map has the default initial capacity.
-    ///
-    /// Warning: `hash_builder` is normally randomly generated, and
-    /// is designed to allow HashMaps to be resistant to attacks that
-    /// cause many collisions and very poor performance. Setting it
-    /// manually using this function can expose a DoS attack vector.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    /// use std::collections::hash_map::RandomState;
-    ///
-    /// let s = RandomState::new();
-    /// let mut map = HashMap::with_hasher(s);
-    /// map.insert(1, 2);
-    /// ```
-    #[inline]
-    #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
-    pub fn with_hasher(hash_builder: S) -> HashMap<K, V, S> {
-        HashMap { base: base::HashMap::with_hasher(hash_builder) }
-    }
-
-    /// Creates an empty `HashMap` with the specified capacity, using `hash_builder`
-    /// to hash the keys.
-    ///
-    /// The hash map will be able to hold at least `capacity` elements without
-    /// reallocating. If `capacity` is 0, the hash map will not allocate.
-    ///
-    /// Warning: `hash_builder` is normally randomly generated, and
-    /// is designed to allow HashMaps to be resistant to attacks that
-    /// cause many collisions and very poor performance. Setting it
-    /// manually using this function can expose a DoS attack vector.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    /// use std::collections::hash_map::RandomState;
-    ///
-    /// let s = RandomState::new();
-    /// let mut map = HashMap::with_capacity_and_hasher(10, s);
-    /// map.insert(1, 2);
-    /// ```
-    #[inline]
-    #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
-    pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> HashMap<K, V, S> {
-        HashMap { base: base::HashMap::with_capacity_and_hasher(capacity, hash_builder) }
-    }
 
     /// Returns a reference to the map's [`BuildHasher`].
     ///
@@ -536,7 +530,13 @@ where
     pub fn hasher(&self) -> &S {
         self.base.hasher()
     }
+}
 
+impl<K, V, S> HashMap<K, V, S>
+where
+    K: Eq + Hash,
+    S: BuildHasher,
+{
     /// Reserves capacity for at least `additional` more elements to be inserted
     /// in the `HashMap`. The collection may reserve more space to avoid
     /// frequent reallocations.
@@ -984,9 +984,8 @@ where
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K, V, S> Debug for HashMap<K, V, S>
 where
-    K: Eq + Hash + Debug,
+    K: Debug,
     V: Debug,
-    S: BuildHasher,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_map().entries(self.iter()).finish()
@@ -996,8 +995,7 @@ where
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K, V, S> Default for HashMap<K, V, S>
 where
-    K: Eq + Hash,
-    S: BuildHasher + Default,
+    S: Default,
 {
     /// Creates an empty `HashMap<K, V, S>`, with the `Default` value for the hasher.
     #[inline]
diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index b48700fb944..1ad99f03703 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -110,7 +110,7 @@ pub struct HashSet<T, S = RandomState> {
     map: HashMap<T, (), S>,
 }
 
-impl<T: Hash + Eq> HashSet<T, RandomState> {
+impl<T> HashSet<T, RandomState> {
     /// Creates an empty `HashSet`.
     ///
     /// The hash set is initially created with a capacity of 0, so it will not allocate until it
@@ -261,13 +261,7 @@ impl<T, S> HashSet<T, S> {
     pub fn clear(&mut self) {
         self.map.clear()
     }
-}
 
-impl<T, S> HashSet<T, S>
-where
-    T: Eq + Hash,
-    S: BuildHasher,
-{
     /// Creates a new empty hash set which will use the given hasher to hash
     /// keys.
     ///
@@ -340,7 +334,13 @@ where
     pub fn hasher(&self) -> &S {
         self.map.hasher()
     }
+}
 
+impl<T, S> HashSet<T, S>
+where
+    T: Eq + Hash,
+    S: BuildHasher,
+{
     /// Reserves capacity for at least `additional` more elements to be inserted
     /// in the `HashSet`. The collection may reserve more space to avoid
     /// frequent reallocations.
@@ -928,8 +928,7 @@ where
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T, S> fmt::Debug for HashSet<T, S>
 where
-    T: Eq + Hash + fmt::Debug,
-    S: BuildHasher,
+    T: fmt::Debug,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_set().entries(self.iter()).finish()
@@ -977,8 +976,7 @@ where
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T, S> Default for HashSet<T, S>
 where
-    T: Eq + Hash,
-    S: BuildHasher + Default,
+    S: Default,
 {
     /// Creates an empty `HashSet<T, S>` with the `Default` value for the hasher.
     #[inline]
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index 700e015b08e..04eaba515ff 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -6,6 +6,7 @@ use crate::fmt::{self, Write};
 use crate::io;
 use crate::mem;
 use crate::memchr;
+use crate::num::NonZeroU8;
 use crate::ops;
 use crate::os::raw::c_char;
 use crate::ptr;
@@ -741,6 +742,32 @@ impl From<Box<CStr>> for CString {
     }
 }
 
+#[stable(feature = "cstring_from_vec_of_nonzerou8", since = "1.43.0")]
+impl From<Vec<NonZeroU8>> for CString {
+    /// Converts a [`Vec`]`<`[`NonZeroU8`]`>` into a [`CString`] without
+    /// copying nor checking for inner null bytes.
+    ///
+    /// [`CString`]: ../ffi/struct.CString.html
+    /// [`NonZeroU8`]: ../num/struct.NonZeroU8.html
+    /// [`Vec`]: ../vec/struct.Vec.html
+    #[inline]
+    fn from(v: Vec<NonZeroU8>) -> CString {
+        unsafe {
+            // Transmute `Vec<NonZeroU8>` to `Vec<u8>`.
+            let v: Vec<u8> = {
+                // Safety:
+                //   - transmuting between `NonZeroU8` and `u8` is sound;
+                //   - `alloc::Layout<NonZeroU8> == alloc::Layout<u8>`.
+                let (ptr, len, cap): (*mut NonZeroU8, _, _) = Vec::into_raw_parts(v);
+                Vec::from_raw_parts(ptr.cast::<u8>(), len, cap)
+            };
+            // Safety: `v` cannot contain null bytes, given the type-level
+            // invariant of `NonZeroU8`.
+            CString::from_vec_unchecked(v)
+        }
+    }
+}
+
 #[stable(feature = "more_box_slice_clone", since = "1.29.0")]
 impl Clone for Box<CStr> {
     #[inline]
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index cff7bbe5ef1..09be3f13050 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -844,10 +844,7 @@ impl OpenOptions {
         self
     }
 
-    /// Sets the option for creating a new file.
-    ///
-    /// This option indicates whether a new file will be created if the file
-    /// does not yet already exist.
+    /// Sets the option to create a new file, or open it if it already exists.
     ///
     /// In order for the file to be created, [`write`] or [`append`] access must
     /// be used.
@@ -868,11 +865,10 @@ impl OpenOptions {
         self
     }
 
-    /// Sets the option to always create a new file.
+    /// Sets the option to create a new file, failing if it already exists.
     ///
-    /// This option indicates whether a new file will be created.
-    /// No file is allowed to exist at the target location, also no (dangling)
-    /// symlink.
+    /// No file is allowed to exist at the target location, also no (dangling) symlink. In this
+    /// way, if the call succeeds, the file returned is guaranteed to be new.
     ///
     /// This option is useful because it is atomic. Otherwise between checking
     /// whether a file exists and creating a new one, the file may have been
diff --git a/src/libstd/future.rs b/src/libstd/future.rs
index f74c84e6dfd..7b1beb1ecda 100644
--- a/src/libstd/future.rs
+++ b/src/libstd/future.rs
@@ -16,9 +16,10 @@ pub use core::future::*;
 ///
 /// This function returns a `GenFuture` underneath, but hides it in `impl Trait` to give
 /// better error messages (`impl Future` rather than `GenFuture<[closure.....]>`).
+// This is `const` to avoid extra errors after we recover from `const async fn`
 #[doc(hidden)]
 #[unstable(feature = "gen_future", issue = "50547")]
-pub fn from_generator<T: Generator<Yield = ()>>(x: T) -> impl Future<Output = T::Return> {
+pub const fn from_generator<T: Generator<Yield = ()>>(x: T) -> impl Future<Output = T::Return> {
     GenFuture(x)
 }
 
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index 6add644dcc2..d410faca30d 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -302,7 +302,7 @@ impl Stdin {
         StdinLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) }
     }
 
-    /// Locks this handle and reads a line of input into the specified buffer.
+    /// Locks this handle and reads a line of input, appending it to the specified buffer.
     ///
     /// For detailed semantics of this method, see the documentation on
     /// [`BufRead::read_line`].
diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs
index 5c7ee9bded9..58f4e76cd30 100644
--- a/src/libstd/keyword_docs.rs
+++ b/src/libstd/keyword_docs.rs
@@ -1100,10 +1100,28 @@ mod trait_keyword {}
 //
 /// A value of type [`bool`] representing logical **true**.
 ///
-/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+/// Logically `true` is not equal to [`false`].
+///
+/// ## Control structures that check for **true**
+///
+/// Several of Rust's control structures will check for a `bool` condition evaluating to **true**.
+///
+///   * The condition in an [`if`] expression must be of type `bool`.
+///     Whenever that condition evaluates to **true**, the `if` expression takes
+///     on the value of the first block. If however, the condition evaluates
+///     to `false`, the expression takes on value of the `else` block if there is one.
 ///
+///   * [`while`] is another control flow construct expecting a `bool`-typed condition.
+///     As long as the condition evaluates to **true**, the `while` loop will continually
+///     evaluate its associated block.
+///
+///   * [`match`] arms can have guard clauses on them.
+///
+/// [`if`]: keyword.if.html
+/// [`while`]: keyword.while.html
+/// [`match`]: ../reference/expressions/match-expr.html#match-guards
+/// [`false`]: keyword.false.html
 /// [`bool`]: primitive.bool.html
-/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
 mod true_keyword {}
 
 #[doc(keyword = "type")]
@@ -1186,12 +1204,33 @@ mod await_keyword {}
 
 #[doc(keyword = "dyn")]
 //
-/// Name the type of a [trait object].
+/// `dyn` is a prefix of a [trait object]'s type.
 ///
-/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+/// The `dyn` keyword is used to highlight that calls to methods on the associated `Trait`
+/// are dynamically dispatched. To use the trait this way, it must be 'object safe'.
+///
+/// Unlike generic parameters or `impl Trait`, the compiler does not know the concrete type that
+/// is being passed. That is, the type has been [erased].
+/// As such, a `dyn Trait` reference contains _two_ pointers.
+/// One pointer goes to the data (e.g., an instance of a struct).
+/// Another pointer goes to a map of method call names to function pointers
+/// (known as a virtual method table or vtable).
+///
+/// At run-time, when a method needs to be called on the `dyn Trait`, the vtable is consulted to get
+/// the function pointer and then that function pointer is called.
+///
+/// ## Trade-offs
+///
+/// The above indirection is the additional runtime cost of calling a function on a `dyn Trait`.
+/// Methods called by dynamic dispatch generally cannot be inlined by the compiler.
+///
+/// However, `dyn Trait` is likely to produce smaller code than `impl Trait` / generic parameters as
+/// the method won't be duplicated for each concrete type.
+///
+/// Read more about `object safety` and [trait object]s.
 ///
 /// [trait object]: ../book/ch17-02-trait-objects.html
-/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+/// [erased]: https://en.wikipedia.org/wiki/Type_erasure
 mod dyn_keyword {}
 
 #[doc(keyword = "union")]
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index f9c9f224730..7b3c702b929 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -233,12 +233,12 @@
 #![feature(allocator_internals)]
 #![feature(allow_internal_unsafe)]
 #![feature(allow_internal_unstable)]
-#![feature(atomic_mut_ptr)]
 #![feature(arbitrary_self_types)]
 #![feature(array_error_internals)]
 #![feature(asm)]
 #![feature(assoc_int_consts)]
 #![feature(associated_type_bounds)]
+#![feature(atomic_mut_ptr)]
 #![feature(box_syntax)]
 #![feature(c_variadic)]
 #![feature(cfg_target_has_atomic)]
@@ -309,6 +309,7 @@
 #![feature(unboxed_closures)]
 #![feature(untagged_unions)]
 #![feature(unwind_attributes)]
+#![feature(vec_into_raw_parts)]
 // NB: the above list is sorted to minimize merge conflicts.
 #![default_lib_allocator]
 
@@ -550,6 +551,9 @@ pub use core::{
     trace_macros,
 };
 
+#[stable(feature = "core_primitive", since = "1.43.0")]
+pub use core::primitive;
+
 // Include a number of private modules that exist solely to provide
 // the rustdoc documentation for primitive types. Using `include!`
 // because rustdoc only looks for these modules at the crate level.
diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs
index 61c4d0c2dbf..b99b4d8d9fd 100644
--- a/src/libstd/sync/once.rs
+++ b/src/libstd/sync/once.rs
@@ -331,14 +331,14 @@ impl Once {
     ///   * `call_once` was called, but has not yet completed,
     ///   * the `Once` instance is poisoned
     ///
-    /// It is also possible that immediately after `is_completed`
-    /// returns false, some other thread finishes executing
-    /// `call_once`.
+    /// This function returning `false` does not mean that `Once` has not been
+    /// executed. For example, it may have been executed in the time between
+    /// when `is_completed` starts executing and when it returns, in which case
+    /// the `false` return value would be stale (but still permissible).
     ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(once_is_completed)]
     /// use std::sync::Once;
     ///
     /// static INIT: Once = Once::new();
@@ -351,7 +351,6 @@ impl Once {
     /// ```
     ///
     /// ```
-    /// #![feature(once_is_completed)]
     /// use std::sync::Once;
     /// use std::thread;
     ///
@@ -364,7 +363,7 @@ impl Once {
     /// assert!(handle.join().is_err());
     /// assert_eq!(INIT.is_completed(), false);
     /// ```
-    #[unstable(feature = "once_is_completed", issue = "54890")]
+    #[stable(feature = "once_is_completed", since = "1.44.0")]
     #[inline]
     pub fn is_completed(&self) -> bool {
         // An `Acquire` load is enough because that makes all the initialization
diff --git a/src/libstd/sys/sgx/abi/entry.S b/src/libstd/sys/sgx/abi/entry.S
index a3e059e8131..1f06c9da3a9 100644
--- a/src/libstd/sys/sgx/abi/entry.S
+++ b/src/libstd/sys/sgx/abi/entry.S
@@ -30,6 +30,14 @@ IMAGE_BASE:
 
 /*  We can store a bunch of data in the gap between MXCSR and the XSAVE header */
 
+/* MXCSR initialization value for ABI */
+.Lmxcsr_init:
+    .int 0x1f80
+
+/* x87 FPU control word initialization value for ABI */
+.Lfpucw_init:
+    .int 0x037f
+
 /*  The following symbols point at read-only data that will be filled in by the */
 /*  post-linker. */
 
@@ -134,6 +142,20 @@ elf_entry:
     ud2                               /* should not be reached  */
 /*  end elf_entry */
 
+/* This code needs to be called *after* the enclave stack has been setup. */
+/* There are 3 places where this needs to happen, so this is put in a macro. */
+.macro entry_sanitize_final
+/*  Sanitize rflags received from user */
+/*    - DF flag: x86-64 ABI requires DF to be unset at function entry/exit */
+/*    - AC flag: AEX on misaligned memory accesses leaks side channel info */
+    pushfq
+    andq $~0x40400, (%rsp)
+    popfq
+/*  check for abort */
+    bt $0,.Laborted(%rip)
+    jc .Lreentry_panic
+.endm
+
 .text
 .global sgx_entry
 .type sgx_entry,function
@@ -150,25 +172,18 @@ sgx_entry:
     stmxcsr %gs:tcsls_user_mxcsr
     fnstcw %gs:tcsls_user_fcw
 
-/*  reset user state */
-/*    - DF flag: x86-64 ABI requires DF to be unset at function entry/exit */
-/*    - AC flag: AEX on misaligned memory accesses leaks side channel info */
-    pushfq
-    andq $~0x40400, (%rsp)
-    popfq
-
 /*  check for debug buffer pointer */
     testb  $0xff,DEBUG(%rip)
     jz .Lskip_debug_init
     mov %r10,%gs:tcsls_debug_panic_buf_ptr
 .Lskip_debug_init:
-/*  check for abort */
-    bt $0,.Laborted(%rip)
-    jc .Lreentry_panic
 /*  check if returning from usercall */
     mov %gs:tcsls_last_rsp,%r11
     test %r11,%r11
     jnz .Lusercall_ret
+/*  reset user state */
+    ldmxcsr .Lmxcsr_init(%rip)
+    fldcw .Lfpucw_init(%rip)
 /*  setup stack */
     mov %gs:tcsls_tos,%rsp /*  initially, RSP is not set to the correct value */
                            /*  here. This is fixed below under "adjust stack". */
@@ -179,6 +194,7 @@ sgx_entry:
     lea IMAGE_BASE(%rip),%rax
     add %rax,%rsp
     mov %rsp,%gs:tcsls_tos
+    entry_sanitize_final
 /*  call tcs_init */
 /*  store caller-saved registers in callee-saved registers */
     mov %rdi,%rbx
@@ -194,7 +210,10 @@ sgx_entry:
     mov %r13,%rdx
     mov %r14,%r8
     mov %r15,%r9
+    jmp .Lafter_init
 .Lskip_init:
+    entry_sanitize_final
+.Lafter_init:
 /*  call into main entry point */
     load_tcsls_flag_secondary_bool cx /* RCX = entry() argument: secondary: bool */
     call entry /* RDI, RSI, RDX, R8, R9 passed in from userspace */
@@ -295,6 +314,7 @@ usercall:
     ldmxcsr (%rsp)
     fldcw 4(%rsp)
     add $8, %rsp
+    entry_sanitize_final
     pop %rbx
     pop %rbp
     pop %r12
diff --git a/src/libstd/sys/sgx/args.rs b/src/libstd/sys/sgx/args.rs
index b47a48e752c..5a53695a846 100644
--- a/src/libstd/sys/sgx/args.rs
+++ b/src/libstd/sys/sgx/args.rs
@@ -22,12 +22,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) {
     }
 }
 
-pub unsafe fn cleanup() {
-    let args = ARGS.swap(0, Ordering::Relaxed);
-    if args != 0 {
-        drop(Box::<ArgsStore>::from_raw(args as _))
-    }
-}
+pub unsafe fn cleanup() {}
 
 pub fn args() -> Args {
     let args = unsafe { (ARGS.load(Ordering::Relaxed) as *const ArgsStore).as_ref() };
diff --git a/src/libstd/sys/sgx/rwlock.rs b/src/libstd/sys/sgx/rwlock.rs
index fda2bb504d4..722b4f5e0ba 100644
--- a/src/libstd/sys/sgx/rwlock.rs
+++ b/src/libstd/sys/sgx/rwlock.rs
@@ -10,10 +10,10 @@ pub struct RWLock {
     writer: SpinMutex<WaitVariable<bool>>,
 }
 
-// Below is to check at compile time, that RWLock has size of 128 bytes.
+// Check at compile time that RWLock size matches C definition (see test_c_rwlock_initializer below)
 #[allow(dead_code)]
 unsafe fn rw_lock_size_assert(r: RWLock) {
-    mem::transmute::<RWLock, [u8; 128]>(r);
+    mem::transmute::<RWLock, [u8; 144]>(r);
 }
 
 impl RWLock {
@@ -210,15 +210,17 @@ mod tests {
     // be changed too.
     #[test]
     fn test_c_rwlock_initializer() {
+        #[rustfmt::skip]
         const RWLOCK_INIT: &[u8] = &[
-            0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0,
-            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
-            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0,
-            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            /* 0x00 */ 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            /* 0x10 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            /* 0x20 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            /* 0x30 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            /* 0x40 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            /* 0x50 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            /* 0x60 */ 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            /* 0x70 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            /* 0x80 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
         ];
 
         #[inline(never)]
@@ -239,7 +241,7 @@ mod tests {
             zero_stack();
             let mut init = MaybeUninit::<RWLock>::zeroed();
             rwlock_new(&mut init);
-            assert_eq!(mem::transmute::<_, [u8; 128]>(init.assume_init()).as_slice(), RWLOCK_INIT)
+            assert_eq!(mem::transmute::<_, [u8; 144]>(init.assume_init()).as_slice(), RWLOCK_INIT)
         };
     }
 }
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index 3ca778354e4..674d4c71138 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -255,8 +255,9 @@ pub mod guard {
 
     #[cfg(target_os = "macos")]
     unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
-        let stackaddr = libc::pthread_get_stackaddr_np(libc::pthread_self()) as usize
-            - libc::pthread_get_stacksize_np(libc::pthread_self());
+        let th = libc::pthread_self();
+        let stackaddr =
+            libc::pthread_get_stackaddr_np(th) as usize - libc::pthread_get_stacksize_np(th);
         Some(stackaddr as *mut libc::c_void)
     }
 
diff --git a/src/libstd/sys/wasi/fd.rs b/src/libstd/sys/wasi/fd.rs
index 00327c1743c..8458ded5db0 100644
--- a/src/libstd/sys/wasi/fd.rs
+++ b/src/libstd/sys/wasi/fd.rs
@@ -13,19 +13,15 @@ pub struct WasiFd {
 fn iovec<'a>(a: &'a mut [IoSliceMut<'_>]) -> &'a [wasi::Iovec] {
     assert_eq!(mem::size_of::<IoSliceMut<'_>>(), mem::size_of::<wasi::Iovec>());
     assert_eq!(mem::align_of::<IoSliceMut<'_>>(), mem::align_of::<wasi::Iovec>());
-    /// SAFETY: `IoSliceMut` and `IoVec` have exactly the same memory layout
-    unsafe {
-        mem::transmute(a)
-    }
+    // SAFETY: `IoSliceMut` and `IoVec` have exactly the same memory layout
+    unsafe { mem::transmute(a) }
 }
 
 fn ciovec<'a>(a: &'a [IoSlice<'_>]) -> &'a [wasi::Ciovec] {
     assert_eq!(mem::size_of::<IoSlice<'_>>(), mem::size_of::<wasi::Ciovec>());
     assert_eq!(mem::align_of::<IoSlice<'_>>(), mem::align_of::<wasi::Ciovec>());
-    /// SAFETY: `IoSlice` and `CIoVec` have exactly the same memory layout
-    unsafe {
-        mem::transmute(a)
-    }
+    // SAFETY: `IoSlice` and `CIoVec` have exactly the same memory layout
+    unsafe { mem::transmute(a) }
 }
 
 impl WasiFd {
diff --git a/src/libstd/sys/wasi/fs.rs b/src/libstd/sys/wasi/fs.rs
index 04bfdf67e12..a11f61fdd69 100644
--- a/src/libstd/sys/wasi/fs.rs
+++ b/src/libstd/sys/wasi/fs.rs
@@ -12,7 +12,6 @@ use crate::sys::time::SystemTime;
 use crate::sys::unsupported;
 use crate::sys_common::FromInner;
 
-pub use crate::sys_common::fs::copy;
 pub use crate::sys_common::fs::remove_dir_all;
 
 pub struct File {
@@ -647,3 +646,12 @@ fn open_parent(p: &Path) -> io::Result<(ManuallyDrop<WasiFd>, PathBuf)> {
 pub fn osstr2str(f: &OsStr) -> io::Result<&str> {
     f.to_str().ok_or_else(|| io::Error::new(io::ErrorKind::Other, "input must be utf-8"))
 }
+
+pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
+    use crate::fs::File;
+
+    let mut reader = File::open(from)?;
+    let mut writer = File::create(to)?;
+
+    io::copy(&mut reader, &mut writer)
+}
diff --git a/src/libstd/sys_common/backtrace.rs b/src/libstd/sys_common/backtrace.rs
index 191add2c31b..289ee07babf 100644
--- a/src/libstd/sys_common/backtrace.rs
+++ b/src/libstd/sys_common/backtrace.rs
@@ -70,6 +70,7 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::
     let mut print_path = move |fmt: &mut fmt::Formatter<'_>, bows: BytesOrWideString<'_>| {
         output_filename(fmt, bows, print_fmt, cwd.as_ref())
     };
+    write!(fmt, "stack backtrace:\n")?;
     let mut bt_fmt = BacktraceFmt::new(fmt, print_fmt, &mut print_path);
     bt_fmt.add_context()?;
     let mut idx = 0;