about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/Cargo.toml24
-rw-r--r--src/libstd/backtrace.rs21
-rw-r--r--src/libstd/build.rs1
-rw-r--r--src/libstd/ffi/c_str.rs38
-rw-r--r--src/libstd/keyword_docs.rs183
-rw-r--r--src/libstd/lazy.rs844
-rw-r--r--src/libstd/lib.rs10
-rw-r--r--src/libstd/panicking.rs2
-rw-r--r--src/libstd/sync/once.rs21
-rw-r--r--src/libstd/sys_common/backtrace.rs3
10 files changed, 1117 insertions, 30 deletions
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index 29893bd12f1..136db6d5d32 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -25,11 +25,15 @@ profiler_builtins = { path = "../libprofiler_builtins", optional = true }
 unwind = { path = "../libunwind" }
 hashbrown = { version = "0.6.2", default-features = false, features = ['rustc-dep-of-std'] }
 
-[dependencies.backtrace_rs]
-package = "backtrace"
-version = "0.3.46"
-default-features = false # without the libstd `backtrace` feature, stub out everything
-features = [ "rustc-dep-of-std" ] # enable build support for integrating into libstd
+# Dependencies of the `backtrace` crate
+addr2line = { version = "0.13.0", optional = true, default-features = false }
+rustc-demangle = { version = "0.1.4", optional = true }
+miniz_oxide = { version = "0.4.0", optional = true, default-features = false }
+[dependencies.object]
+version = "0.20"
+optional = true
+default-features = false
+features = ['read_core', 'elf', 'macho', 'pe']
 
 [dev-dependencies]
 rand = "0.7"
@@ -48,11 +52,13 @@ wasi = { version = "0.9.0", features = ['rustc-dep-of-std'], default-features =
 
 [features]
 backtrace = [
-  "backtrace_rs/dbghelp",          # backtrace/symbolize on MSVC
-  "backtrace_rs/libbacktrace",     # symbolize on most platforms
-  "backtrace_rs/libunwind",        # backtrace on most platforms
-  "backtrace_rs/dladdr",           # symbolize on platforms w/o libbacktrace
+  "gimli-symbolize",
+  'addr2line/rustc-dep-of-std',
+  'object/rustc-dep-of-std',
+  'rustc-demangle/rustc-dep-of-std',
+  'miniz_oxide/rustc-dep-of-std',
 ]
+gimli-symbolize = []
 
 panic-unwind = ["panic_unwind"]
 profiler = ["profiler_builtins"]
diff --git a/src/libstd/backtrace.rs b/src/libstd/backtrace.rs
index e10d466030f..e65775c1ced 100644
--- a/src/libstd/backtrace.rs
+++ b/src/libstd/backtrace.rs
@@ -91,6 +91,7 @@
 // `Backtrace`, but that's a relatively small price to pay relative to capturing
 // a backtrace or actually symbolizing it.
 
+use crate::backtrace_rs::{self, BytesOrWideString};
 use crate::env;
 use crate::ffi::c_void;
 use crate::fmt;
@@ -98,8 +99,6 @@ use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst};
 use crate::sync::Mutex;
 use crate::sys_common::backtrace::{lock, output_filename};
 use crate::vec::Vec;
-use backtrace::BytesOrWideString;
-use backtrace_rs as backtrace;
 
 /// A captured OS thread stack backtrace.
 ///
@@ -150,7 +149,7 @@ struct BacktraceFrame {
 }
 
 enum RawFrame {
-    Actual(backtrace::Frame),
+    Actual(backtrace_rs::Frame),
     #[cfg(test)]
     Fake,
 }
@@ -197,7 +196,7 @@ 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)) {
+        if let Some(fn_name) = self.name.as_ref().map(|b| backtrace_rs::SymbolName::new(b)) {
             write!(fmt, "fn: \"{:#}\"", fn_name)?;
         } else {
             write!(fmt, "fn: <unknown>")?;
@@ -223,7 +222,7 @@ impl fmt::Debug for BytesOrWide {
                 BytesOrWide::Bytes(w) => BytesOrWideString::Bytes(w),
                 BytesOrWide::Wide(w) => BytesOrWideString::Wide(w),
             },
-            backtrace::PrintFmt::Short,
+            backtrace_rs::PrintFmt::Short,
             crate::env::current_dir().as_ref().ok(),
         )
     }
@@ -299,7 +298,7 @@ impl Backtrace {
         let mut frames = Vec::new();
         let mut actual_start = None;
         unsafe {
-            backtrace::trace_unsynchronized(|frame| {
+            backtrace_rs::trace_unsynchronized(|frame| {
                 frames.push(BacktraceFrame {
                     frame: RawFrame::Actual(frame.clone()),
                     symbols: Vec::new(),
@@ -350,9 +349,9 @@ impl fmt::Display for Backtrace {
 
         let full = fmt.alternate();
         let (frames, style) = if full {
-            (&capture.frames[..], backtrace::PrintFmt::Full)
+            (&capture.frames[..], backtrace_rs::PrintFmt::Full)
         } else {
-            (&capture.frames[capture.actual_start..], backtrace::PrintFmt::Short)
+            (&capture.frames[capture.actual_start..], backtrace_rs::PrintFmt::Short)
         };
 
         // When printing paths we try to strip the cwd if it exists, otherwise
@@ -364,7 +363,7 @@ impl fmt::Display for Backtrace {
             output_filename(fmt, path, style, cwd.as_ref().ok())
         };
 
-        let mut f = backtrace::BacktraceFmt::new(fmt, style, &mut print_path);
+        let mut f = backtrace_rs::BacktraceFmt::new(fmt, style, &mut print_path);
         f.add_context()?;
         for frame in frames {
             let mut f = f.frame();
@@ -374,7 +373,7 @@ impl fmt::Display for Backtrace {
                 for symbol in frame.symbols.iter() {
                     f.print_raw(
                         frame.frame.ip(),
-                        symbol.name.as_ref().map(|b| backtrace::SymbolName::new(b)),
+                        symbol.name.as_ref().map(|b| backtrace_rs::SymbolName::new(b)),
                         symbol.filename.as_ref().map(|b| match b {
                             BytesOrWide::Bytes(w) => BytesOrWideString::Bytes(w),
                             BytesOrWide::Wide(w) => BytesOrWideString::Wide(w),
@@ -409,7 +408,7 @@ impl Capture {
                 RawFrame::Fake => unimplemented!(),
             };
             unsafe {
-                backtrace::resolve_frame_unsynchronized(frame, |symbol| {
+                backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| {
                     symbols.push(BacktraceSymbol {
                         name: symbol.name().map(|m| m.as_bytes().to_vec()),
                         filename: symbol.filename_raw().map(|b| match b {
diff --git a/src/libstd/build.rs b/src/libstd/build.rs
index eb2753d6245..58fb6fda19a 100644
--- a/src/libstd/build.rs
+++ b/src/libstd/build.rs
@@ -87,4 +87,5 @@ fn main() {
         println!("cargo:rustc-cfg=feature=\"restricted-std\"");
     }
     println!("cargo:rustc-env=STD_ENV_ARCH={}", env::var("CARGO_CFG_TARGET_ARCH").unwrap());
+    println!("cargo:rustc-cfg=backtrace_in_libstd");
 }
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index dca1fdde482..da25a0ede72 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -1551,6 +1551,27 @@ impl ops::Index<ops::RangeFull> for CString {
     }
 }
 
+#[stable(feature = "cstr_range_from", since = "1.47.0")]
+impl ops::Index<ops::RangeFrom<usize>> for CStr {
+    type Output = CStr;
+
+    fn index(&self, index: ops::RangeFrom<usize>) -> &CStr {
+        let bytes = self.to_bytes_with_nul();
+        // we need to manually check the starting index to account for the null
+        // byte, since otherwise we could get an empty string that doesn't end
+        // in a null.
+        if index.start < bytes.len() {
+            unsafe { CStr::from_bytes_with_nul_unchecked(&bytes[index.start..]) }
+        } else {
+            panic!(
+                "index out of bounds: the len is {} but the index is {}",
+                bytes.len(),
+                index.start
+            );
+        }
+    }
+}
+
 #[stable(feature = "cstring_asref", since = "1.7.0")]
 impl AsRef<CStr> for CStr {
     #[inline]
@@ -1747,4 +1768,21 @@ mod tests {
 
         assert_eq!(CSTR.to_str().unwrap(), "Hello, world!");
     }
+
+    #[test]
+    fn cstr_index_from() {
+        let original = b"Hello, world!\0";
+        let cstr = CStr::from_bytes_with_nul(original).unwrap();
+        let result = CStr::from_bytes_with_nul(&original[7..]).unwrap();
+
+        assert_eq!(&cstr[7..], result);
+    }
+
+    #[test]
+    #[should_panic]
+    fn cstr_index_from_empty() {
+        let original = b"Hello, world!\0";
+        let cstr = CStr::from_bytes_with_nul(original).unwrap();
+        let _ = &cstr[original.len()..];
+    }
 }
diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs
index a53e7f5cf57..d985f10ccb4 100644
--- a/src/libstd/keyword_docs.rs
+++ b/src/libstd/keyword_docs.rs
@@ -1497,11 +1497,188 @@ mod super_keyword {}
 
 #[doc(keyword = "trait")]
 //
-/// A common interface for a class of types.
+/// A common interface for a group of types.
 ///
-/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+/// A `trait` is like an interface that data types can implement. When a type
+/// implements a trait it can be treated abstractly as that trait using generics
+/// or trait objects.
 ///
-/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+/// Traits can be made up of three varieties of associated items:
+///
+/// - functions and methods
+/// - types
+/// - constants
+///
+/// Traits may also contain additional type parameters. Those type parameters
+/// or the trait itself can be constrained by other traits.
+///
+/// Traits can serve as markers or carry other logical semantics that
+/// aren't expressed through their items. When a type implements that
+/// trait it is promising to uphold its contract. [`Send`] and [`Sync`] are two
+/// such marker traits present in the standard library.
+///
+/// See the [Reference][Ref-Traits] for a lot more information on traits.
+///
+/// # Examples
+///
+/// Traits are declared using the `trait` keyword. Types can implement them
+/// using [`impl`] `Trait` [`for`] `Type`:
+///
+/// ```rust
+/// trait Zero {
+///     const ZERO: Self;
+///     fn is_zero(&self) -> bool;
+/// }
+///
+/// impl Zero for i32 {
+///     const ZERO: Self = 0;
+///
+///     fn is_zero(&self) -> bool {
+///         *self == Self::ZERO
+///     }
+/// }
+///
+/// assert_eq!(i32::ZERO, 0);
+/// assert!(i32::ZERO.is_zero());
+/// assert!(!4.is_zero());
+/// ```
+///
+/// With an associated type:
+///
+/// ```rust
+/// trait Builder {
+///     type Built;
+///
+///     fn build(&self) -> Self::Built;
+/// }
+/// ```
+///
+/// Traits can be generic, with constraints or without:
+///
+/// ```rust
+/// trait MaybeFrom<T> {
+///     fn maybe_from(value: T) -> Option<Self>
+///     where
+///         Self: Sized;
+/// }
+/// ```
+///
+/// Traits can build upon the requirements of other traits. In the example
+/// below `Iterator` is a **supertrait** and `ThreeIterator` is a **subtrait**:
+///
+/// ```rust
+/// trait ThreeIterator: std::iter::Iterator {
+///     fn next_three(&mut self) -> Option<[Self::Item; 3]>;
+/// }
+/// ```
+///
+/// Traits can be used in functions, as parameters:
+///
+/// ```rust
+/// # #![allow(dead_code)]
+/// fn debug_iter<I: Iterator>(it: I) where I::Item: std::fmt::Debug {
+///     for elem in it {
+///         println!("{:#?}", elem);
+///     }
+/// }
+///
+/// // u8_len_1, u8_len_2 and u8_len_3 are equivalent
+///
+/// fn u8_len_1(val: impl Into<Vec<u8>>) -> usize {
+///     val.into().len()
+/// }
+///
+/// fn u8_len_2<T: Into<Vec<u8>>>(val: T) -> usize {
+///     val.into().len()
+/// }
+///
+/// fn u8_len_3<T>(val: T) -> usize
+/// where
+///     T: Into<Vec<u8>>,
+/// {
+///     val.into().len()
+/// }
+/// ```
+///
+/// Or as return types:
+///
+/// ```rust
+/// # #![allow(dead_code)]
+/// fn from_zero_to(v: u8) -> impl Iterator<Item = u8> {
+///     (0..v).into_iter()
+/// }
+/// ```
+///
+/// The use of the [`impl`] keyword in this position allows the function writer
+/// to hide the concrete type as an implementation detail which can change
+/// without breaking user's code.
+///
+/// # Trait objects
+///
+/// A *trait object* is an opaque value of another type that implements a set of
+/// traits. A trait object implements all specified traits as well as their
+/// supertraits (if any).
+///
+/// The syntax is the following: `dyn BaseTrait + AutoTrait1 + ... AutoTraitN`.
+/// Only one `BaseTrait` can be used so this will not compile:
+///
+/// ```rust,compile_fail,E0225
+/// trait A {}
+/// trait B {}
+///
+/// let _: Box<dyn A + B>;
+/// ```
+///
+/// Neither will this, which is a syntax error:
+///
+/// ```rust,compile_fail
+/// trait A {}
+/// trait B {}
+///
+/// let _: Box<dyn A + dyn B>;
+/// ```
+///
+/// On the other hand, this is correct:
+///
+/// ```rust
+/// trait A {}
+///
+/// let _: Box<dyn A + Send + Sync>;
+/// ```
+///
+/// The [Reference][Ref-Trait-Objects] has more information about trait objects,
+/// their limitations and the differences between editions.
+///
+/// # Unsafe traits
+///
+/// Some traits may be unsafe to implement. Using the [`unsafe`] keyword in
+/// front of the trait's declaration is used to mark this:
+///
+/// ```rust
+/// unsafe trait UnsafeTrait {}
+///
+/// unsafe impl UnsafeTrait for i32 {}
+/// ```
+///
+/// # Differences between the 2015 and 2018 editions
+///
+/// In the 2015 edition parameters pattern where not needed for traits:
+///
+/// ```rust,edition2015
+/// trait Tr {
+///     fn f(i32);
+/// }
+/// ```
+///
+/// This behavior is no longer valid in edition 2018.
+///
+/// [`for`]: keyword.for.html
+/// [`impl`]: keyword.impl.html
+/// [`unsafe`]: keyword.unsafe.html
+/// [`Send`]: marker/trait.Send.html
+/// [`Sync`]: marker/trait.Sync.html
+/// [Ref-Traits]: ../reference/items/traits.html
+/// [Ref-Trait-Objects]: ../reference/types/trait-object.html
 mod trait_keyword {}
 
 #[doc(keyword = "true")]
diff --git a/src/libstd/lazy.rs b/src/libstd/lazy.rs
new file mode 100644
index 00000000000..86e1cfae582
--- /dev/null
+++ b/src/libstd/lazy.rs
@@ -0,0 +1,844 @@
+//! Lazy values and one-time initialization of static data.
+
+use crate::{
+    cell::{Cell, UnsafeCell},
+    fmt,
+    mem::{self, MaybeUninit},
+    ops::{Deref, Drop},
+    panic::{RefUnwindSafe, UnwindSafe},
+    sync::Once,
+};
+
+#[doc(inline)]
+#[unstable(feature = "once_cell", issue = "74465")]
+pub use core::lazy::*;
+
+/// A synchronization primitive which can be written to only once.
+///
+/// This type is a thread-safe `OnceCell`.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(once_cell)]
+///
+/// use std::lazy::SyncOnceCell;
+///
+/// static CELL: SyncOnceCell<String> = SyncOnceCell::new();
+/// assert!(CELL.get().is_none());
+///
+/// std::thread::spawn(|| {
+///     let value: &String = CELL.get_or_init(|| {
+///         "Hello, World!".to_string()
+///     });
+///     assert_eq!(value, "Hello, World!");
+/// }).join().unwrap();
+///
+/// let value: Option<&String> = CELL.get();
+/// assert!(value.is_some());
+/// assert_eq!(value.unwrap().as_str(), "Hello, World!");
+/// ```
+#[unstable(feature = "once_cell", issue = "74465")]
+pub struct SyncOnceCell<T> {
+    once: Once,
+    // Whether or not the value is initialized is tracked by `state_and_queue`.
+    value: UnsafeCell<MaybeUninit<T>>,
+}
+
+// Why do we need `T: Send`?
+// Thread A creates a `SyncOnceCell` and shares it with
+// scoped thread B, which fills the cell, which is
+// then destroyed by A. That is, destructor observes
+// a sent value.
+#[unstable(feature = "once_cell", issue = "74465")]
+unsafe impl<T: Sync + Send> Sync for SyncOnceCell<T> {}
+#[unstable(feature = "once_cell", issue = "74465")]
+unsafe impl<T: Send> Send for SyncOnceCell<T> {}
+
+#[unstable(feature = "once_cell", issue = "74465")]
+impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for SyncOnceCell<T> {}
+#[unstable(feature = "once_cell", issue = "74465")]
+impl<T: UnwindSafe> UnwindSafe for SyncOnceCell<T> {}
+
+#[unstable(feature = "once_cell", issue = "74465")]
+impl<T> Default for SyncOnceCell<T> {
+    fn default() -> SyncOnceCell<T> {
+        SyncOnceCell::new()
+    }
+}
+
+#[unstable(feature = "once_cell", issue = "74465")]
+impl<T: fmt::Debug> fmt::Debug for SyncOnceCell<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self.get() {
+            Some(v) => f.debug_tuple("Once").field(v).finish(),
+            None => f.write_str("Once(Uninit)"),
+        }
+    }
+}
+
+#[unstable(feature = "once_cell", issue = "74465")]
+impl<T: Clone> Clone for SyncOnceCell<T> {
+    fn clone(&self) -> SyncOnceCell<T> {
+        let cell = Self::new();
+        if let Some(value) = self.get() {
+            match cell.set(value.clone()) {
+                Ok(()) => (),
+                Err(_) => unreachable!(),
+            }
+        }
+        cell
+    }
+}
+
+#[unstable(feature = "once_cell", issue = "74465")]
+impl<T> From<T> for SyncOnceCell<T> {
+    fn from(value: T) -> Self {
+        let cell = Self::new();
+        match cell.set(value) {
+            Ok(()) => cell,
+            Err(_) => unreachable!(),
+        }
+    }
+}
+
+#[unstable(feature = "once_cell", issue = "74465")]
+impl<T: PartialEq> PartialEq for SyncOnceCell<T> {
+    fn eq(&self, other: &SyncOnceCell<T>) -> bool {
+        self.get() == other.get()
+    }
+}
+
+#[unstable(feature = "once_cell", issue = "74465")]
+impl<T: Eq> Eq for SyncOnceCell<T> {}
+
+impl<T> SyncOnceCell<T> {
+    /// Creates a new empty cell.
+    #[unstable(feature = "once_cell", issue = "74465")]
+    pub const fn new() -> SyncOnceCell<T> {
+        SyncOnceCell { once: Once::new(), value: UnsafeCell::new(MaybeUninit::uninit()) }
+    }
+
+    /// Gets the reference to the underlying value.
+    ///
+    /// Returns `None` if the cell is empty, or being initialized. This
+    /// method never blocks.
+    #[unstable(feature = "once_cell", issue = "74465")]
+    pub fn get(&self) -> Option<&T> {
+        if self.is_initialized() {
+            // Safe b/c checked is_initialized
+            Some(unsafe { self.get_unchecked() })
+        } else {
+            None
+        }
+    }
+
+    /// Gets the mutable reference to the underlying value.
+    ///
+    /// Returns `None` if the cell is empty. This method never blocks.
+    #[unstable(feature = "once_cell", issue = "74465")]
+    pub fn get_mut(&mut self) -> Option<&mut T> {
+        if self.is_initialized() {
+            // Safe b/c checked is_initialized and we have a unique access
+            Some(unsafe { self.get_unchecked_mut() })
+        } else {
+            None
+        }
+    }
+
+    /// Sets the contents of this cell to `value`.
+    ///
+    /// Returns `Ok(())` if the cell's value was updated.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(once_cell)]
+    ///
+    /// use std::lazy::SyncOnceCell;
+    ///
+    /// static CELL: SyncOnceCell<i32> = SyncOnceCell::new();
+    ///
+    /// fn main() {
+    ///     assert!(CELL.get().is_none());
+    ///
+    ///     std::thread::spawn(|| {
+    ///         assert_eq!(CELL.set(92), Ok(()));
+    ///     }).join().unwrap();
+    ///
+    ///     assert_eq!(CELL.set(62), Err(62));
+    ///     assert_eq!(CELL.get(), Some(&92));
+    /// }
+    /// ```
+    #[unstable(feature = "once_cell", issue = "74465")]
+    pub fn set(&self, value: T) -> Result<(), T> {
+        let mut value = Some(value);
+        self.get_or_init(|| value.take().unwrap());
+        match value {
+            None => Ok(()),
+            Some(value) => Err(value),
+        }
+    }
+
+    /// Gets the contents of the cell, initializing it with `f` if the cell
+    /// was empty.
+    ///
+    /// Many threads may call `get_or_init` concurrently with different
+    /// initializing functions, but it is guaranteed that only one function
+    /// will be executed.
+    ///
+    /// # Panics
+    ///
+    /// If `f` panics, the panic is propagated to the caller, and the cell
+    /// remains uninitialized.
+    ///
+    /// It is an error to reentrantly initialize the cell from `f`. The
+    /// exact outcome is unspecified. Current implementation deadlocks, but
+    /// this may be changed to a panic in the future.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(once_cell)]
+    ///
+    /// use std::lazy::SyncOnceCell;
+    ///
+    /// let cell = SyncOnceCell::new();
+    /// let value = cell.get_or_init(|| 92);
+    /// assert_eq!(value, &92);
+    /// let value = cell.get_or_init(|| unreachable!());
+    /// assert_eq!(value, &92);
+    /// ```
+    #[unstable(feature = "once_cell", issue = "74465")]
+    pub fn get_or_init<F>(&self, f: F) -> &T
+    where
+        F: FnOnce() -> T,
+    {
+        match self.get_or_try_init(|| Ok::<T, !>(f())) {
+            Ok(val) => val,
+        }
+    }
+
+    /// Gets the contents of the cell, initializing it with `f` if
+    /// the cell was empty. If the cell was empty and `f` failed, an
+    /// error is returned.
+    ///
+    /// # Panics
+    ///
+    /// If `f` panics, the panic is propagated to the caller, and
+    /// the cell remains uninitialized.
+    ///
+    /// It is an error to reentrantly initialize the cell from `f`.
+    /// The exact outcome is unspecified. Current implementation
+    /// deadlocks, but this may be changed to a panic in the future.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(once_cell)]
+    ///
+    /// use std::lazy::SyncOnceCell;
+    ///
+    /// let cell = SyncOnceCell::new();
+    /// assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
+    /// assert!(cell.get().is_none());
+    /// let value = cell.get_or_try_init(|| -> Result<i32, ()> {
+    ///     Ok(92)
+    /// });
+    /// assert_eq!(value, Ok(&92));
+    /// assert_eq!(cell.get(), Some(&92))
+    /// ```
+    #[unstable(feature = "once_cell", issue = "74465")]
+    pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
+    where
+        F: FnOnce() -> Result<T, E>,
+    {
+        // Fast path check
+        // NOTE: We need to perform an acquire on the state in this method
+        // in order to correctly synchronize `SyncLazy::force`. This is
+        // currently done by calling `self.get()`, which in turn calls
+        // `self.is_initialized()`, which in turn performs the acquire.
+        if let Some(value) = self.get() {
+            return Ok(value);
+        }
+        self.initialize(f)?;
+
+        debug_assert!(self.is_initialized());
+
+        // Safety: The inner value has been initialized
+        Ok(unsafe { self.get_unchecked() })
+    }
+
+    /// Consumes the `SyncOnceCell`, returning the wrapped value. Returns
+    /// `None` if the cell was empty.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(once_cell)]
+    ///
+    /// use std::lazy::SyncOnceCell;
+    ///
+    /// let cell: SyncOnceCell<String> = SyncOnceCell::new();
+    /// assert_eq!(cell.into_inner(), None);
+    ///
+    /// let cell = SyncOnceCell::new();
+    /// cell.set("hello".to_string()).unwrap();
+    /// assert_eq!(cell.into_inner(), Some("hello".to_string()));
+    /// ```
+    #[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::ManuallyDrop::new(self);
+        inner
+    }
+
+    /// Takes the value out of this `SyncOnceCell`, moving it back to an uninitialized state.
+    ///
+    /// Has no effect and returns `None` if the `SyncOnceCell` hasn't been initialized.
+    ///
+    /// Safety is guaranteed by requiring a mutable reference.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(once_cell)]
+    ///
+    /// use std::lazy::SyncOnceCell;
+    ///
+    /// let mut cell: SyncOnceCell<String> = SyncOnceCell::new();
+    /// assert_eq!(cell.take(), None);
+    ///
+    /// let mut cell = SyncOnceCell::new();
+    /// cell.set("hello".to_string()).unwrap();
+    /// assert_eq!(cell.take(), Some("hello".to_string()));
+    /// assert_eq!(cell.get(), None);
+    /// ```
+    #[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())
+        } else {
+            None
+        }
+    }
+
+    #[inline]
+    fn is_initialized(&self) -> bool {
+        self.once.is_completed()
+    }
+
+    #[cold]
+    fn initialize<F, E>(&self, f: F) -> Result<(), E>
+    where
+        F: FnOnce() -> Result<T, E>,
+    {
+        let mut res: Result<(), E> = Ok(());
+        let slot = &self.value;
+
+        // Ignore poisoning from other threads
+        // If another thread panics, then we'll be able to run our closure
+        self.once.call_once_force(|p| {
+            match f() {
+                Ok(value) => {
+                    unsafe { (&mut *slot.get()).write(value) };
+                }
+                Err(e) => {
+                    res = Err(e);
+
+                    // Treat the underlying `Once` as poisoned since we
+                    // failed to initialize our value. Calls
+                    p.poison();
+                }
+            }
+        });
+        res
+    }
+
+    /// Safety: The value must be initialized
+    unsafe fn get_unchecked(&self) -> &T {
+        debug_assert!(self.is_initialized());
+        (&*self.value.get()).get_ref()
+    }
+
+    /// Safety: The value must be initialized
+    unsafe fn get_unchecked_mut(&mut self) -> &mut T {
+        debug_assert!(self.is_initialized());
+        (&mut *self.value.get()).get_mut()
+    }
+}
+
+impl<T> Drop for SyncOnceCell<T> {
+    fn drop(&mut self) {
+        // Safety: The cell is being dropped, so it can't be accessed again
+        unsafe { self.take_inner() };
+    }
+}
+
+/// A value which is initialized on the first access.
+///
+/// This type is a thread-safe `Lazy`, and can be used in statics.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(once_cell)]
+///
+/// use std::collections::HashMap;
+///
+/// use std::lazy::SyncLazy;
+///
+/// static HASHMAP: SyncLazy<HashMap<i32, String>> = SyncLazy::new(|| {
+///     println!("initializing");
+///     let mut m = HashMap::new();
+///     m.insert(13, "Spica".to_string());
+///     m.insert(74, "Hoyten".to_string());
+///     m
+/// });
+///
+/// fn main() {
+///     println!("ready");
+///     std::thread::spawn(|| {
+///         println!("{:?}", HASHMAP.get(&13));
+///     }).join().unwrap();
+///     println!("{:?}", HASHMAP.get(&74));
+///
+///     // Prints:
+///     //   ready
+///     //   initializing
+///     //   Some("Spica")
+///     //   Some("Hoyten")
+/// }
+/// ```
+#[unstable(feature = "once_cell", issue = "74465")]
+pub struct SyncLazy<T, F = fn() -> T> {
+    cell: SyncOnceCell<T>,
+    init: Cell<Option<F>>,
+}
+
+#[unstable(feature = "once_cell", issue = "74465")]
+impl<T: fmt::Debug, F> fmt::Debug for SyncLazy<T, F> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish()
+    }
+}
+
+// We never create a `&F` from a `&SyncLazy<T, F>` so it is fine
+// to not impl `Sync` for `F`
+// we do create a `&mut Option<F>` in `force`, but this is
+// properly synchronized, so it only happens once
+// so it also does not contribute to this impl.
+#[unstable(feature = "once_cell", issue = "74465")]
+unsafe impl<T, F: Send> Sync for SyncLazy<T, F> where SyncOnceCell<T>: Sync {}
+// auto-derived `Send` impl is OK.
+
+#[unstable(feature = "once_cell", issue = "74465")]
+impl<T, F: RefUnwindSafe> RefUnwindSafe for SyncLazy<T, F> where SyncOnceCell<T>: RefUnwindSafe {}
+
+impl<T, F> SyncLazy<T, F> {
+    /// Creates a new lazy value with the given initializing
+    /// function.
+    #[unstable(feature = "once_cell", issue = "74465")]
+    pub const fn new(f: F) -> SyncLazy<T, F> {
+        SyncLazy { cell: SyncOnceCell::new(), init: Cell::new(Some(f)) }
+    }
+}
+
+impl<T, F: FnOnce() -> T> SyncLazy<T, F> {
+    /// Forces the evaluation of this lazy value and
+    /// returns a reference to result. This is equivalent
+    /// to the `Deref` impl, but is explicit.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(once_cell)]
+    ///
+    /// use std::lazy::SyncLazy;
+    ///
+    /// let lazy = SyncLazy::new(|| 92);
+    ///
+    /// assert_eq!(SyncLazy::force(&lazy), &92);
+    /// assert_eq!(&*lazy, &92);
+    /// ```
+    #[unstable(feature = "once_cell", issue = "74465")]
+    pub fn force(this: &SyncLazy<T, F>) -> &T {
+        this.cell.get_or_init(|| match this.init.take() {
+            Some(f) => f(),
+            None => panic!("Lazy instance has previously been poisoned"),
+        })
+    }
+}
+
+#[unstable(feature = "once_cell", issue = "74465")]
+impl<T, F: FnOnce() -> T> Deref for SyncLazy<T, F> {
+    type Target = T;
+    fn deref(&self) -> &T {
+        SyncLazy::force(self)
+    }
+}
+
+#[unstable(feature = "once_cell", issue = "74465")]
+impl<T: Default> Default for SyncLazy<T> {
+    /// Creates a new lazy value using `Default` as the initializing function.
+    fn default() -> SyncLazy<T> {
+        SyncLazy::new(T::default)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::{
+        lazy::{Lazy, SyncLazy, SyncOnceCell},
+        panic,
+        sync::{
+            atomic::{AtomicUsize, Ordering::SeqCst},
+            mpsc::channel,
+            Mutex,
+        },
+    };
+
+    #[test]
+    fn lazy_default() {
+        static CALLED: AtomicUsize = AtomicUsize::new(0);
+
+        struct Foo(u8);
+        impl Default for Foo {
+            fn default() -> Self {
+                CALLED.fetch_add(1, SeqCst);
+                Foo(42)
+            }
+        }
+
+        let lazy: Lazy<Mutex<Foo>> = <_>::default();
+
+        assert_eq!(CALLED.load(SeqCst), 0);
+
+        assert_eq!(lazy.lock().unwrap().0, 42);
+        assert_eq!(CALLED.load(SeqCst), 1);
+
+        lazy.lock().unwrap().0 = 21;
+
+        assert_eq!(lazy.lock().unwrap().0, 21);
+        assert_eq!(CALLED.load(SeqCst), 1);
+    }
+
+    #[test]
+    fn lazy_poisoning() {
+        let x: Lazy<String> = Lazy::new(|| panic!("kaboom"));
+        for _ in 0..2 {
+            let res = panic::catch_unwind(panic::AssertUnwindSafe(|| x.len()));
+            assert!(res.is_err());
+        }
+    }
+
+    // miri doesn't support threads
+    #[cfg(not(miri))]
+    fn spawn_and_wait<R: Send + 'static>(f: impl FnOnce() -> R + Send + 'static) -> R {
+        crate::thread::spawn(f).join().unwrap()
+    }
+
+    #[cfg(not(miri))]
+    fn spawn(f: impl FnOnce() + Send + 'static) {
+        let _ = crate::thread::spawn(f);
+    }
+
+    // "stub threads" for Miri
+    #[cfg(miri)]
+    fn spawn_and_wait<R: Send + 'static>(f: impl FnOnce() -> R + Send + 'static) -> R {
+        f(())
+    }
+
+    #[cfg(miri)]
+    fn spawn(f: impl FnOnce() + Send + 'static) {
+        f(())
+    }
+
+    #[test]
+    fn sync_once_cell() {
+        static ONCE_CELL: SyncOnceCell<i32> = SyncOnceCell::new();
+
+        assert!(ONCE_CELL.get().is_none());
+
+        spawn_and_wait(|| {
+            ONCE_CELL.get_or_init(|| 92);
+            assert_eq!(ONCE_CELL.get(), Some(&92));
+        });
+
+        ONCE_CELL.get_or_init(|| panic!("Kabom!"));
+        assert_eq!(ONCE_CELL.get(), Some(&92));
+    }
+
+    #[test]
+    fn sync_once_cell_get_mut() {
+        let mut c = SyncOnceCell::new();
+        assert!(c.get_mut().is_none());
+        c.set(90).unwrap();
+        *c.get_mut().unwrap() += 2;
+        assert_eq!(c.get_mut(), Some(&mut 92));
+    }
+
+    #[test]
+    fn sync_once_cell_get_unchecked() {
+        let c = SyncOnceCell::new();
+        c.set(92).unwrap();
+        unsafe {
+            assert_eq!(c.get_unchecked(), &92);
+        }
+    }
+
+    #[test]
+    fn sync_once_cell_drop() {
+        static DROP_CNT: AtomicUsize = AtomicUsize::new(0);
+        struct Dropper;
+        impl Drop for Dropper {
+            fn drop(&mut self) {
+                DROP_CNT.fetch_add(1, SeqCst);
+            }
+        }
+
+        let x = SyncOnceCell::new();
+        spawn_and_wait(move || {
+            x.get_or_init(|| Dropper);
+            assert_eq!(DROP_CNT.load(SeqCst), 0);
+            drop(x);
+        });
+
+        assert_eq!(DROP_CNT.load(SeqCst), 1);
+    }
+
+    #[test]
+    fn sync_once_cell_drop_empty() {
+        let x = SyncOnceCell::<String>::new();
+        drop(x);
+    }
+
+    #[test]
+    fn clone() {
+        let s = SyncOnceCell::new();
+        let c = s.clone();
+        assert!(c.get().is_none());
+
+        s.set("hello".to_string()).unwrap();
+        let c = s.clone();
+        assert_eq!(c.get().map(String::as_str), Some("hello"));
+    }
+
+    #[test]
+    fn get_or_try_init() {
+        let cell: SyncOnceCell<String> = SyncOnceCell::new();
+        assert!(cell.get().is_none());
+
+        let res = panic::catch_unwind(|| cell.get_or_try_init(|| -> Result<_, ()> { panic!() }));
+        assert!(res.is_err());
+        assert!(!cell.is_initialized());
+        assert!(cell.get().is_none());
+
+        assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
+
+        assert_eq!(
+            cell.get_or_try_init(|| Ok::<_, ()>("hello".to_string())),
+            Ok(&"hello".to_string())
+        );
+        assert_eq!(cell.get(), Some(&"hello".to_string()));
+    }
+
+    #[test]
+    fn from_impl() {
+        assert_eq!(SyncOnceCell::from("value").get(), Some(&"value"));
+        assert_ne!(SyncOnceCell::from("foo").get(), Some(&"bar"));
+    }
+
+    #[test]
+    fn partialeq_impl() {
+        assert!(SyncOnceCell::from("value") == SyncOnceCell::from("value"));
+        assert!(SyncOnceCell::from("foo") != SyncOnceCell::from("bar"));
+
+        assert!(SyncOnceCell::<String>::new() == SyncOnceCell::new());
+        assert!(SyncOnceCell::<String>::new() != SyncOnceCell::from("value".to_owned()));
+    }
+
+    #[test]
+    fn into_inner() {
+        let cell: SyncOnceCell<String> = SyncOnceCell::new();
+        assert_eq!(cell.into_inner(), None);
+        let cell = SyncOnceCell::new();
+        cell.set("hello".to_string()).unwrap();
+        assert_eq!(cell.into_inner(), Some("hello".to_string()));
+    }
+
+    #[test]
+    fn sync_lazy_new() {
+        static CALLED: AtomicUsize = AtomicUsize::new(0);
+        static SYNC_LAZY: SyncLazy<i32> = SyncLazy::new(|| {
+            CALLED.fetch_add(1, SeqCst);
+            92
+        });
+
+        assert_eq!(CALLED.load(SeqCst), 0);
+
+        spawn_and_wait(|| {
+            let y = *SYNC_LAZY - 30;
+            assert_eq!(y, 62);
+            assert_eq!(CALLED.load(SeqCst), 1);
+        });
+
+        let y = *SYNC_LAZY - 30;
+        assert_eq!(y, 62);
+        assert_eq!(CALLED.load(SeqCst), 1);
+    }
+
+    #[test]
+    fn sync_lazy_default() {
+        static CALLED: AtomicUsize = AtomicUsize::new(0);
+
+        struct Foo(u8);
+        impl Default for Foo {
+            fn default() -> Self {
+                CALLED.fetch_add(1, SeqCst);
+                Foo(42)
+            }
+        }
+
+        let lazy: SyncLazy<Mutex<Foo>> = <_>::default();
+
+        assert_eq!(CALLED.load(SeqCst), 0);
+
+        assert_eq!(lazy.lock().unwrap().0, 42);
+        assert_eq!(CALLED.load(SeqCst), 1);
+
+        lazy.lock().unwrap().0 = 21;
+
+        assert_eq!(lazy.lock().unwrap().0, 21);
+        assert_eq!(CALLED.load(SeqCst), 1);
+    }
+
+    #[test]
+    #[cfg_attr(miri, ignore)] // leaks memory
+    fn static_sync_lazy() {
+        static XS: SyncLazy<Vec<i32>> = SyncLazy::new(|| {
+            let mut xs = Vec::new();
+            xs.push(1);
+            xs.push(2);
+            xs.push(3);
+            xs
+        });
+
+        spawn_and_wait(|| {
+            assert_eq!(&*XS, &vec![1, 2, 3]);
+        });
+
+        assert_eq!(&*XS, &vec![1, 2, 3]);
+    }
+
+    #[test]
+    #[cfg_attr(miri, ignore)] // leaks memory
+    fn static_sync_lazy_via_fn() {
+        fn xs() -> &'static Vec<i32> {
+            static XS: SyncOnceCell<Vec<i32>> = SyncOnceCell::new();
+            XS.get_or_init(|| {
+                let mut xs = Vec::new();
+                xs.push(1);
+                xs.push(2);
+                xs.push(3);
+                xs
+            })
+        }
+        assert_eq!(xs(), &vec![1, 2, 3]);
+    }
+
+    #[test]
+    fn sync_lazy_poisoning() {
+        let x: SyncLazy<String> = SyncLazy::new(|| panic!("kaboom"));
+        for _ in 0..2 {
+            let res = panic::catch_unwind(|| x.len());
+            assert!(res.is_err());
+        }
+    }
+
+    #[test]
+    fn is_sync_send() {
+        fn assert_traits<T: Send + Sync>() {}
+        assert_traits::<SyncOnceCell<String>>();
+        assert_traits::<SyncLazy<String>>();
+    }
+
+    #[test]
+    fn eval_once_macro() {
+        macro_rules! eval_once {
+            (|| -> $ty:ty {
+                $($body:tt)*
+            }) => {{
+                static ONCE_CELL: SyncOnceCell<$ty> = SyncOnceCell::new();
+                fn init() -> $ty {
+                    $($body)*
+                }
+                ONCE_CELL.get_or_init(init)
+            }};
+        }
+
+        let fib: &'static Vec<i32> = eval_once! {
+            || -> Vec<i32> {
+                let mut res = vec![1, 1];
+                for i in 0..10 {
+                    let next = res[i] + res[i + 1];
+                    res.push(next);
+                }
+                res
+            }
+        };
+        assert_eq!(fib[5], 8)
+    }
+
+    #[test]
+    #[cfg_attr(miri, ignore)] // deadlocks without real threads
+    fn sync_once_cell_does_not_leak_partially_constructed_boxes() {
+        static ONCE_CELL: SyncOnceCell<String> = SyncOnceCell::new();
+
+        let n_readers = 10;
+        let n_writers = 3;
+        const MSG: &str = "Hello, World";
+
+        let (tx, rx) = channel();
+
+        for _ in 0..n_readers {
+            let tx = tx.clone();
+            spawn(move || {
+                loop {
+                    if let Some(msg) = ONCE_CELL.get() {
+                        tx.send(msg).unwrap();
+                        break;
+                    }
+                }
+            });
+        }
+        for _ in 0..n_writers {
+            spawn(move || {
+                let _ = ONCE_CELL.set(MSG.to_owned());
+            });
+        }
+
+        for _ in 0..n_readers {
+            let msg = rx.recv().unwrap();
+            assert_eq!(msg, MSG);
+        }
+    }
+}
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 54fc35b20f7..11b8f953be4 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -287,6 +287,7 @@
 #![feature(linkage)]
 #![feature(llvm_asm)]
 #![feature(log_syntax)]
+#![feature(maybe_uninit_extra)]
 #![feature(maybe_uninit_ref)]
 #![feature(maybe_uninit_slice)]
 #![feature(min_specialization)]
@@ -294,6 +295,7 @@
 #![feature(negative_impls)]
 #![feature(never_type)]
 #![feature(nll)]
+#![feature(once_cell)]
 #![feature(optin_builtin_traits)]
 #![feature(or_patterns)]
 #![feature(panic_info_message)]
@@ -303,6 +305,7 @@
 #![feature(ptr_internals)]
 #![feature(raw)]
 #![feature(raw_ref_macros)]
+#![feature(ready_macro)]
 #![feature(renamed_spin_loop)]
 #![feature(rustc_attrs)]
 #![feature(rustc_private)]
@@ -477,6 +480,9 @@ pub mod process;
 pub mod sync;
 pub mod time;
 
+#[unstable(feature = "once_cell", issue = "74465")]
+pub mod lazy;
+
 #[stable(feature = "futures_api", since = "1.36.0")]
 pub mod task {
     //! Types and Traits for working with asynchronous tasks.
@@ -508,6 +514,10 @@ mod panicking;
 // compiler
 pub mod rt;
 
+#[path = "../backtrace/src/lib.rs"]
+#[allow(dead_code, unused_attributes)]
+mod backtrace_rs;
+
 // Pull in the `std_detect` crate directly into libstd. The contents of
 // `std_detect` are in a different repository: rust-lang/stdarch.
 //
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index 9542e7209b4..ab2a6010306 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -171,7 +171,7 @@ fn default_hook(info: &PanicInfo<'_>) {
     // If this is a double panic, make sure that we print a backtrace
     // for this panic. Otherwise only print it if logging is enabled.
     let backtrace_env = if panic_count::get() >= 2 {
-        RustBacktrace::Print(backtrace_rs::PrintFmt::Full)
+        RustBacktrace::Print(crate::backtrace_rs::PrintFmt::Full)
     } else {
         backtrace::rust_backtrace_env()
     };
diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs
index 7dc822db3d0..64260990824 100644
--- a/src/libstd/sync/once.rs
+++ b/src/libstd/sync/once.rs
@@ -132,6 +132,7 @@ unsafe impl Send for Once {}
 #[derive(Debug)]
 pub struct OnceState {
     poisoned: bool,
+    set_state_on_drop_to: Cell<usize>,
 }
 
 /// Initialization value for static [`Once`] values.
@@ -321,7 +322,7 @@ impl Once {
         }
 
         let mut f = Some(f);
-        self.call_inner(true, &mut |p| f.take().unwrap()(&OnceState { poisoned: p }));
+        self.call_inner(true, &mut |p| f.take().unwrap()(p));
     }
 
     /// Returns `true` if some `call_once` call has completed
@@ -385,7 +386,7 @@ impl Once {
     // currently no way to take an `FnOnce` and call it via virtual dispatch
     // without some allocation overhead.
     #[cold]
-    fn call_inner(&self, ignore_poisoning: bool, init: &mut dyn FnMut(bool)) {
+    fn call_inner(&self, ignore_poisoning: bool, init: &mut dyn FnMut(&OnceState)) {
         let mut state_and_queue = self.state_and_queue.load(Ordering::Acquire);
         loop {
             match state_and_queue {
@@ -413,8 +414,12 @@ impl Once {
                     };
                     // Run the initialization function, letting it know if we're
                     // poisoned or not.
-                    init(state_and_queue == POISONED);
-                    waiter_queue.set_state_on_drop_to = COMPLETE;
+                    let init_state = OnceState {
+                        poisoned: state_and_queue == POISONED,
+                        set_state_on_drop_to: Cell::new(COMPLETE),
+                    };
+                    init(&init_state);
+                    waiter_queue.set_state_on_drop_to = init_state.set_state_on_drop_to.get();
                     break;
                 }
                 _ => {
@@ -554,6 +559,14 @@ impl OnceState {
     pub fn poisoned(&self) -> bool {
         self.poisoned
     }
+
+    /// Poison the associated [`Once`] without explicitly panicking.
+    ///
+    /// [`Once`]: struct.Once.html
+    // NOTE: This is currently only exposed for the `lazy` module
+    pub(crate) fn poison(&self) {
+        self.set_state_on_drop_to.set(POISONED);
+    }
 }
 
 #[cfg(all(test, not(target_os = "emscripten")))]
diff --git a/src/libstd/sys_common/backtrace.rs b/src/libstd/sys_common/backtrace.rs
index e9b1e86d7ae..d386a656e4f 100644
--- a/src/libstd/sys_common/backtrace.rs
+++ b/src/libstd/sys_common/backtrace.rs
@@ -1,3 +1,4 @@
+use crate::backtrace_rs::{self, BacktraceFmt, BytesOrWideString, PrintFmt};
 use crate::borrow::Cow;
 /// Common code for printing the backtrace in the same way across the different
 /// supported platforms.
@@ -9,8 +10,6 @@ use crate::path::{self, Path, PathBuf};
 use crate::sync::atomic::{self, Ordering};
 use crate::sys::mutex::Mutex;
 
-use backtrace_rs::{BacktraceFmt, BytesOrWideString, PrintFmt};
-
 /// Max number of frames to print.
 const MAX_NB_FRAMES: usize = 100;