about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2015-05-27 11:18:36 +0300
committerEduard Burtescu <edy.burt@gmail.com>2015-05-27 11:19:03 +0300
commit377b0900aede976b2d37a499bbd7b62c2e39b358 (patch)
treeb4a5a4431d36ed1a4e0a39c7d2ef2563ecac9bf4 /src/libstd
parent6e8e4f847c2ea02fec021ea15dfb2de6beac797a (diff)
downloadrust-377b0900aede976b2d37a499bbd7b62c2e39b358.tar.gz
rust-377b0900aede976b2d37a499bbd7b62c2e39b358.zip
Use `const fn` to abstract away the contents of UnsafeCell & friends.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/dynamic_lib.rs4
-rw-r--r--src/libstd/env.rs8
-rw-r--r--src/libstd/io/lazy.rs32
-rw-r--r--src/libstd/io/mod.rs3
-rw-r--r--src/libstd/io/stdio.rs6
-rw-r--r--src/libstd/lib.rs1
-rw-r--r--src/libstd/net/test.rs4
-rw-r--r--src/libstd/rand/os.rs8
-rw-r--r--src/libstd/rt/args.rs4
-rw-r--r--src/libstd/rt/at_exit_imp.rs4
-rw-r--r--src/libstd/rt/backtrace.rs2
-rw-r--r--src/libstd/rt/unwind/mod.rs22
-rw-r--r--src/libstd/rt/util.rs2
-rw-r--r--src/libstd/sync/condvar.rs47
-rw-r--r--src/libstd/sync/mpsc/blocking.rs4
-rw-r--r--src/libstd/sync/mutex.rs25
-rw-r--r--src/libstd/sync/once.rs26
-rw-r--r--src/libstd/sync/rwlock.rs25
-rw-r--r--src/libstd/sys/common/condvar.rs6
-rw-r--r--src/libstd/sys/common/mutex.rs9
-rw-r--r--src/libstd/sys/common/poison.rs18
-rw-r--r--src/libstd/sys/common/remutex.rs2
-rw-r--r--src/libstd/sys/common/rwlock.rs9
-rw-r--r--src/libstd/sys/common/thread_local.rs43
-rw-r--r--src/libstd/sys/unix/backtrace.rs6
-rw-r--r--src/libstd/sys/unix/condvar.rs7
-rw-r--r--src/libstd/sys/unix/mutex.rs9
-rw-r--r--src/libstd/sys/unix/os.rs4
-rw-r--r--src/libstd/sys/unix/rwlock.rs7
-rw-r--r--src/libstd/sys/unix/thread.rs4
-rw-r--r--src/libstd/sys/unix/thread_local.rs2
-rw-r--r--src/libstd/sys/unix/time.rs4
-rw-r--r--src/libstd/sys/windows/backtrace.rs4
-rw-r--r--src/libstd/sys/windows/c.rs4
-rw-r--r--src/libstd/sys/windows/condvar.rs9
-rw-r--r--src/libstd/sys/windows/mutex.rs7
-rw-r--r--src/libstd/sys/windows/net.rs4
-rw-r--r--src/libstd/sys/windows/process.rs4
-rw-r--r--src/libstd/sys/windows/rwlock.rs7
-rw-r--r--src/libstd/sys/windows/thread_local.rs4
-rw-r--r--src/libstd/sys/windows/time.rs4
-rw-r--r--src/libstd/thread/local.rs246
-rw-r--r--src/libstd/thread/mod.rs3
-rw-r--r--src/libstd/thread/scoped_tls.rs91
44 files changed, 320 insertions, 424 deletions
diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs
index 8b90fce6fc4..ebdc049bc7f 100644
--- a/src/libstd/dynamic_lib.rs
+++ b/src/libstd/dynamic_lib.rs
@@ -211,8 +211,8 @@ mod dl {
     pub fn check_for_errors_in<T, F>(f: F) -> Result<T, String> where
         F: FnOnce() -> T,
     {
-        use sync::{StaticMutex, MUTEX_INIT};
-        static LOCK: StaticMutex = MUTEX_INIT;
+        use sync::StaticMutex;
+        static LOCK: StaticMutex = StaticMutex::new();
         unsafe {
             // dlerror isn't thread safe, so we need to lock around this entire
             // sequence
diff --git a/src/libstd/env.rs b/src/libstd/env.rs
index 126ef38b918..0b9c659ea2e 100644
--- a/src/libstd/env.rs
+++ b/src/libstd/env.rs
@@ -23,8 +23,8 @@ use ffi::{OsStr, OsString};
 use fmt;
 use io;
 use path::{Path, PathBuf};
-use sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT, Ordering};
-use sync::{StaticMutex, MUTEX_INIT};
+use sync::atomic::{AtomicIsize, Ordering};
+use sync::StaticMutex;
 use sys::os as os_imp;
 
 /// Returns the current working directory as a `PathBuf`.
@@ -70,7 +70,7 @@ pub fn set_current_dir<P: AsRef<Path>>(p: P) -> io::Result<()> {
     os_imp::chdir(p.as_ref())
 }
 
-static ENV_LOCK: StaticMutex = MUTEX_INIT;
+static ENV_LOCK: StaticMutex = StaticMutex::new();
 
 /// An iterator over a snapshot of the environment variables of this process.
 ///
@@ -475,7 +475,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
     os_imp::current_exe()
 }
 
-static EXIT_STATUS: AtomicIsize = ATOMIC_ISIZE_INIT;
+static EXIT_STATUS: AtomicIsize = AtomicIsize::new(0);
 
 /// Sets the process exit code
 ///
diff --git a/src/libstd/io/lazy.rs b/src/libstd/io/lazy.rs
index df280dab37d..d398cb88af4 100644
--- a/src/libstd/io/lazy.rs
+++ b/src/libstd/io/lazy.rs
@@ -11,31 +11,31 @@
 use prelude::v1::*;
 
 use boxed;
-use cell::UnsafeCell;
+use cell::Cell;
 use rt;
 use sync::{StaticMutex, Arc};
 
 pub struct Lazy<T> {
-    pub lock: StaticMutex,
-    pub ptr: UnsafeCell<*mut Arc<T>>,
-    pub init: fn() -> Arc<T>,
+    lock: StaticMutex,
+    ptr: Cell<*mut Arc<T>>,
+    init: fn() -> Arc<T>,
 }
 
 unsafe impl<T> Sync for Lazy<T> {}
 
-macro_rules! lazy_init {
-    ($init:expr) => (::io::lazy::Lazy {
-        lock: ::sync::MUTEX_INIT,
-        ptr: ::cell::UnsafeCell { value: 0 as *mut _ },
-        init: $init,
-    })
-}
-
 impl<T: Send + Sync + 'static> Lazy<T> {
+    pub const fn new(init: fn() -> Arc<T>) -> Lazy<T> {
+        Lazy {
+            lock: StaticMutex::new(),
+            ptr: Cell::new(0 as *mut _),
+            init: init
+        }
+    }
+
     pub fn get(&'static self) -> Option<Arc<T>> {
         let _g = self.lock.lock();
+        let ptr = self.ptr.get();
         unsafe {
-            let ptr = *self.ptr.get();
             if ptr.is_null() {
                 Some(self.init())
             } else if ptr as usize == 1 {
@@ -53,14 +53,14 @@ impl<T: Send + Sync + 'static> Lazy<T> {
         // `Arc`.
         let registered = rt::at_exit(move || {
             let g = self.lock.lock();
-            let ptr = *self.ptr.get();
-            *self.ptr.get() = 1 as *mut _;
+            let ptr = self.ptr.get();
+            self.ptr.set(1 as *mut _);
             drop(g);
             drop(Box::from_raw(ptr))
         });
         let ret = (self.init)();
         if registered.is_ok() {
-            *self.ptr.get() = boxed::into_raw(Box::new(ret.clone()));
+            self.ptr.set(boxed::into_raw(Box::new(ret.clone())));
         }
         return ret
     }
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index c9da279810b..c664def304e 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -36,13 +36,12 @@ pub use self::stdio::{StdoutLock, StderrLock, StdinLock};
 #[doc(no_inline, hidden)]
 pub use self::stdio::{set_panic, set_print};
 
-#[macro_use] mod lazy;
-
 pub mod prelude;
 mod buffered;
 mod cursor;
 mod error;
 mod impls;
+mod lazy;
 mod util;
 mod stdio;
 
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index a14c472333c..9885ccfaae0 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -122,7 +122,7 @@ pub struct StdinLock<'a> {
 /// locked version, `StdinLock`, implements both `Read` and `BufRead`, however.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn stdin() -> Stdin {
-    static INSTANCE: Lazy<Mutex<BufReader<StdinRaw>>> = lazy_init!(stdin_init);
+    static INSTANCE: Lazy<Mutex<BufReader<StdinRaw>>> = Lazy::new(stdin_init);
     return Stdin {
         inner: INSTANCE.get().expect("cannot access stdin during shutdown"),
     };
@@ -236,7 +236,7 @@ pub struct StdoutLock<'a> {
 /// The returned handle implements the `Write` trait.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn stdout() -> Stdout {
-    static INSTANCE: Lazy<ReentrantMutex<RefCell<LineWriter<StdoutRaw>>>> = lazy_init!(stdout_init);
+    static INSTANCE: Lazy<ReentrantMutex<RefCell<LineWriter<StdoutRaw>>>> = Lazy::new(stdout_init);
     return Stdout {
         inner: INSTANCE.get().expect("cannot access stdout during shutdown"),
     };
@@ -308,7 +308,7 @@ pub struct StderrLock<'a> {
 /// The returned handle implements the `Write` trait.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn stderr() -> Stderr {
-    static INSTANCE: Lazy<ReentrantMutex<RefCell<StderrRaw>>> = lazy_init!(stderr_init);
+    static INSTANCE: Lazy<ReentrantMutex<RefCell<StderrRaw>>> = Lazy::new(stderr_init);
     return Stderr {
         inner: INSTANCE.get().expect("cannot access stderr during shutdown"),
     };
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 17bd27337ac..8305088057c 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -109,6 +109,7 @@
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(core)]
+#![feature(const_fn)]
 #![feature(into_cow)]
 #![feature(lang_items)]
 #![feature(libc)]
diff --git a/src/libstd/net/test.rs b/src/libstd/net/test.rs
index d77d6f1d6de..c6d839d55a8 100644
--- a/src/libstd/net/test.rs
+++ b/src/libstd/net/test.rs
@@ -12,9 +12,9 @@ use prelude::v1::*;
 
 use env;
 use net::{SocketAddr, SocketAddrV4, SocketAddrV6, Ipv4Addr, Ipv6Addr, ToSocketAddrs};
-use sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
+use sync::atomic::{AtomicUsize, Ordering};
 
-static PORT: AtomicUsize = ATOMIC_USIZE_INIT;
+static PORT: AtomicUsize = AtomicUsize::new(0);
 
 pub fn next_test_ip4() -> SocketAddr {
     let port = PORT.fetch_add(1, Ordering::SeqCst) as u16 + base_port();
diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs
index 885adf19ca1..a2e6915a6a6 100644
--- a/src/libstd/rand/os.rs
+++ b/src/libstd/rand/os.rs
@@ -96,11 +96,11 @@ mod imp {
                   target_arch = "aarch64",
                   target_arch = "powerpc")))]
     fn is_getrandom_available() -> bool {
-        use sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
-        use sync::{Once, ONCE_INIT};
+        use sync::atomic::{AtomicBool, Ordering};
+        use sync::Once;
 
-        static CHECKER: Once = ONCE_INIT;
-        static AVAILABLE: AtomicBool = ATOMIC_BOOL_INIT;
+        static CHECKER: Once = Once::new();
+        static AVAILABLE: AtomicBool = AtomicBool::new(false);
 
         CHECKER.call_once(|| {
             let mut buf: [u8; 0] = [];
diff --git a/src/libstd/rt/args.rs b/src/libstd/rt/args.rs
index 2329861f29b..d23a124a6ec 100644
--- a/src/libstd/rt/args.rs
+++ b/src/libstd/rt/args.rs
@@ -52,10 +52,10 @@ mod imp {
     use mem;
     use ffi::CStr;
 
-    use sync::{StaticMutex, MUTEX_INIT};
+    use sync::StaticMutex;
 
     static mut GLOBAL_ARGS_PTR: usize = 0;
-    static LOCK: StaticMutex = MUTEX_INIT;
+    static LOCK: StaticMutex = StaticMutex::new();
 
     pub unsafe fn init(argc: isize, argv: *const *const u8) {
         let args = load_argc_and_argv(argc, argv);
diff --git a/src/libstd/rt/at_exit_imp.rs b/src/libstd/rt/at_exit_imp.rs
index beb2870807a..19a17be4ccf 100644
--- a/src/libstd/rt/at_exit_imp.rs
+++ b/src/libstd/rt/at_exit_imp.rs
@@ -20,7 +20,7 @@ use boxed;
 use boxed::Box;
 use vec::Vec;
 use thunk::Thunk;
-use sys_common::mutex::{Mutex, MUTEX_INIT};
+use sys_common::mutex::Mutex;
 
 type Queue = Vec<Thunk<'static>>;
 
@@ -28,7 +28,7 @@ type Queue = Vec<Thunk<'static>>;
 // on poisoning and this module needs to operate at a lower level than requiring
 // the thread infrastructure to be in place (useful on the borders of
 // initialization/destruction).
-static LOCK: Mutex = MUTEX_INIT;
+static LOCK: Mutex = Mutex::new();
 static mut QUEUE: *mut Queue = 0 as *mut Queue;
 
 // The maximum number of times the cleanup routines will be run. While running
diff --git a/src/libstd/rt/backtrace.rs b/src/libstd/rt/backtrace.rs
index 72cbe2b533b..2eadf36a6b4 100644
--- a/src/libstd/rt/backtrace.rs
+++ b/src/libstd/rt/backtrace.rs
@@ -22,7 +22,7 @@ pub use sys::backtrace::write;
 // For now logging is turned off by default, and this function checks to see
 // whether the magical environment variable is present to see if it's turned on.
 pub fn log_enabled() -> bool {
-    static ENABLED: atomic::AtomicIsize = atomic::ATOMIC_ISIZE_INIT;
+    static ENABLED: atomic::AtomicIsize = atomic::AtomicIsize::new(0);
     match ENABLED.load(Ordering::SeqCst) {
         1 => return false,
         2 => return true,
diff --git a/src/libstd/rt/unwind/mod.rs b/src/libstd/rt/unwind/mod.rs
index 576035ffe9a..c403976745a 100644
--- a/src/libstd/rt/unwind/mod.rs
+++ b/src/libstd/rt/unwind/mod.rs
@@ -72,7 +72,7 @@ use intrinsics;
 use libc::c_void;
 use mem;
 use sync::atomic::{self, Ordering};
-use sys_common::mutex::{Mutex, MUTEX_INIT};
+use sys_common::mutex::Mutex;
 
 // The actual unwinding implementation is cfg'd here, and we've got two current
 // implementations. One goes through SEH on Windows and the other goes through
@@ -89,15 +89,15 @@ pub type Callback = fn(msg: &(Any + Send), file: &'static str, line: u32);
 // For more information, see below.
 const MAX_CALLBACKS: usize = 16;
 static CALLBACKS: [atomic::AtomicUsize; MAX_CALLBACKS] =
-        [atomic::ATOMIC_USIZE_INIT, atomic::ATOMIC_USIZE_INIT,
-         atomic::ATOMIC_USIZE_INIT, atomic::ATOMIC_USIZE_INIT,
-         atomic::ATOMIC_USIZE_INIT, atomic::ATOMIC_USIZE_INIT,
-         atomic::ATOMIC_USIZE_INIT, atomic::ATOMIC_USIZE_INIT,
-         atomic::ATOMIC_USIZE_INIT, atomic::ATOMIC_USIZE_INIT,
-         atomic::ATOMIC_USIZE_INIT, atomic::ATOMIC_USIZE_INIT,
-         atomic::ATOMIC_USIZE_INIT, atomic::ATOMIC_USIZE_INIT,
-         atomic::ATOMIC_USIZE_INIT, atomic::ATOMIC_USIZE_INIT];
-static CALLBACK_CNT: atomic::AtomicUsize = atomic::ATOMIC_USIZE_INIT;
+        [atomic::AtomicUsize::new(0), atomic::AtomicUsize::new(0),
+         atomic::AtomicUsize::new(0), atomic::AtomicUsize::new(0),
+         atomic::AtomicUsize::new(0), atomic::AtomicUsize::new(0),
+         atomic::AtomicUsize::new(0), atomic::AtomicUsize::new(0),
+         atomic::AtomicUsize::new(0), atomic::AtomicUsize::new(0),
+         atomic::AtomicUsize::new(0), atomic::AtomicUsize::new(0),
+         atomic::AtomicUsize::new(0), atomic::AtomicUsize::new(0),
+         atomic::AtomicUsize::new(0), atomic::AtomicUsize::new(0)];
+static CALLBACK_CNT: atomic::AtomicUsize = atomic::AtomicUsize::new(0);
 
 thread_local! { static PANICKING: Cell<bool> = Cell::new(false) }
 
@@ -243,7 +243,7 @@ fn begin_unwind_inner(msg: Box<Any + Send>,
     // `std::sync` one as accessing TLS can cause weird recursive problems (and
     // we don't need poison checking).
     unsafe {
-        static LOCK: Mutex = MUTEX_INIT;
+        static LOCK: Mutex = Mutex::new();
         static mut INIT: bool = false;
         LOCK.lock();
         if !INIT {
diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs
index 31e970a9550..b53219db245 100644
--- a/src/libstd/rt/util.rs
+++ b/src/libstd/rt/util.rs
@@ -42,7 +42,7 @@ pub fn limit_thread_creation_due_to_osx_and_valgrind() -> bool {
 }
 
 pub fn min_stack() -> usize {
-    static MIN: atomic::AtomicUsize = atomic::ATOMIC_USIZE_INIT;
+    static MIN: atomic::AtomicUsize = atomic::AtomicUsize::new(0);
     match MIN.load(Ordering::SeqCst) {
         0 => {}
         n => return n - 1,
diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs
index 8da917916e5..f2c389f9426 100644
--- a/src/libstd/sync/condvar.rs
+++ b/src/libstd/sync/condvar.rs
@@ -10,7 +10,7 @@
 
 use prelude::v1::*;
 
-use sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
+use sync::atomic::{AtomicUsize, Ordering};
 use sync::{mutex, MutexGuard, PoisonError};
 use sys_common::condvar as sys;
 use sys_common::mutex as sys_mutex;
@@ -84,10 +84,7 @@ pub struct StaticCondvar {
 /// Constant initializer for a statically allocated condition variable.
 #[unstable(feature = "static_condvar",
            reason = "may be merged with Condvar in the future")]
-pub const CONDVAR_INIT: StaticCondvar = StaticCondvar {
-    inner: sys::CONDVAR_INIT,
-    mutex: ATOMIC_USIZE_INIT,
-};
+pub const CONDVAR_INIT: StaticCondvar = StaticCondvar::new();
 
 impl Condvar {
     /// Creates a new condition variable which is ready to be waited on and
@@ -96,7 +93,7 @@ impl Condvar {
     pub fn new() -> Condvar {
         Condvar {
             inner: box StaticCondvar {
-                inner: unsafe { sys::Condvar::new() },
+                inner: sys::Condvar::new(),
                 mutex: AtomicUsize::new(0),
             }
         }
@@ -234,6 +231,16 @@ impl Drop for Condvar {
 }
 
 impl StaticCondvar {
+    /// Creates a new condition variable
+    #[unstable(feature = "static_condvar",
+               reason = "may be merged with Condvar in the future")]
+    pub const fn new() -> StaticCondvar {
+        StaticCondvar {
+            inner: sys::Condvar::new(),
+            mutex: AtomicUsize::new(0),
+        }
+    }
+
     /// Blocks the current thread until this condition variable receives a
     /// notification.
     ///
@@ -388,10 +395,10 @@ impl StaticCondvar {
 mod tests {
     use prelude::v1::*;
 
-    use super::{StaticCondvar, CONDVAR_INIT};
+    use super::StaticCondvar;
     use sync::mpsc::channel;
-    use sync::{StaticMutex, MUTEX_INIT, Condvar, Mutex, Arc};
-    use sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
+    use sync::{StaticMutex, Condvar, Mutex, Arc};
+    use sync::atomic::{AtomicUsize, Ordering};
     use thread;
     use time::Duration;
     use u32;
@@ -405,7 +412,7 @@ mod tests {
 
     #[test]
     fn static_smoke() {
-        static C: StaticCondvar = CONDVAR_INIT;
+        static C: StaticCondvar = StaticCondvar::new();
         C.notify_one();
         C.notify_all();
         unsafe { C.destroy(); }
@@ -413,8 +420,8 @@ mod tests {
 
     #[test]
     fn notify_one() {
-        static C: StaticCondvar = CONDVAR_INIT;
-        static M: StaticMutex = MUTEX_INIT;
+        static C: StaticCondvar = StaticCondvar::new();
+        static M: StaticMutex = StaticMutex::new();
 
         let g = M.lock().unwrap();
         let _t = thread::spawn(move|| {
@@ -464,8 +471,8 @@ mod tests {
 
     #[test]
     fn wait_timeout_ms() {
-        static C: StaticCondvar = CONDVAR_INIT;
-        static M: StaticMutex = MUTEX_INIT;
+        static C: StaticCondvar = StaticCondvar::new();
+        static M: StaticMutex = StaticMutex::new();
 
         let g = M.lock().unwrap();
         let (g, _no_timeout) = C.wait_timeout_ms(g, 1).unwrap();
@@ -483,9 +490,9 @@ mod tests {
 
     #[test]
     fn wait_timeout_with() {
-        static C: StaticCondvar = CONDVAR_INIT;
-        static M: StaticMutex = MUTEX_INIT;
-        static S: AtomicUsize = ATOMIC_USIZE_INIT;
+        static C: StaticCondvar = StaticCondvar::new();
+        static M: StaticMutex = StaticMutex::new();
+        static S: AtomicUsize = AtomicUsize::new(0);
 
         let g = M.lock().unwrap();
         let (g, success) = C.wait_timeout_with(g, Duration::new(0, 1000), |_| {
@@ -530,9 +537,9 @@ mod tests {
     #[test]
     #[should_panic]
     fn two_mutexes() {
-        static M1: StaticMutex = MUTEX_INIT;
-        static M2: StaticMutex = MUTEX_INIT;
-        static C: StaticCondvar = CONDVAR_INIT;
+        static M1: StaticMutex = StaticMutex::new();
+        static M2: StaticMutex = StaticMutex::new();
+        static C: StaticCondvar = StaticCondvar::new();
 
         let mut g = M1.lock().unwrap();
         let _t = thread::spawn(move|| {
diff --git a/src/libstd/sync/mpsc/blocking.rs b/src/libstd/sync/mpsc/blocking.rs
index 2e4155ea351..0e5a9859116 100644
--- a/src/libstd/sync/mpsc/blocking.rs
+++ b/src/libstd/sync/mpsc/blocking.rs
@@ -11,7 +11,7 @@
 //! Generic support for building blocking abstractions.
 
 use thread::{self, Thread};
-use sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
+use sync::atomic::{AtomicBool, Ordering};
 use sync::Arc;
 use marker::{Sync, Send};
 use mem;
@@ -41,7 +41,7 @@ impl !Sync for WaitToken {}
 pub fn tokens() -> (WaitToken, SignalToken) {
     let inner = Arc::new(Inner {
         thread: thread::current(),
-        woken: ATOMIC_BOOL_INIT,
+        woken: AtomicBool::new(false),
     });
     let wait_token = WaitToken {
         inner: inner.clone(),
diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs
index f9ed7c863d1..fd22d723ebd 100644
--- a/src/libstd/sync/mutex.rs
+++ b/src/libstd/sync/mutex.rs
@@ -178,17 +178,14 @@ impl<'a, T: ?Sized> !marker::Send for MutexGuard<'a, T> {}
 /// other mutex constants.
 #[unstable(feature = "std_misc",
            reason = "may be merged with Mutex in the future")]
-pub const MUTEX_INIT: StaticMutex = StaticMutex {
-    lock: sys::MUTEX_INIT,
-    poison: poison::FLAG_INIT,
-};
+pub const MUTEX_INIT: StaticMutex = StaticMutex::new();
 
 impl<T> Mutex<T> {
     /// Creates a new mutex in an unlocked state ready for use.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(t: T) -> Mutex<T> {
         Mutex {
-            inner: box MUTEX_INIT,
+            inner: box StaticMutex::new(),
             data: UnsafeCell::new(t),
         }
     }
@@ -271,9 +268,19 @@ impl<T: ?Sized + fmt::Debug + 'static> fmt::Debug for Mutex<T> {
 
 struct Dummy(UnsafeCell<()>);
 unsafe impl Sync for Dummy {}
-static DUMMY: Dummy = Dummy(UnsafeCell { value: () });
+static DUMMY: Dummy = Dummy(UnsafeCell::new(()));
 
 impl StaticMutex {
+    /// Creates a new mutex in an unlocked state ready for use.
+    #[unstable(feature = "std_misc",
+               reason = "may be merged with Mutex in the future")]
+    pub const fn new() -> StaticMutex {
+        StaticMutex {
+            lock: sys::Mutex::new(),
+            poison: poison::Flag::new(),
+        }
+    }
+
     /// Acquires this lock, see `Mutex::lock`
     #[inline]
     #[unstable(feature = "std_misc",
@@ -365,7 +372,7 @@ mod tests {
     use prelude::v1::*;
 
     use sync::mpsc::channel;
-    use sync::{Arc, Mutex, StaticMutex, MUTEX_INIT, Condvar};
+    use sync::{Arc, Mutex, StaticMutex, Condvar};
     use thread;
 
     struct Packet<T: Send>(Arc<(Mutex<T>, Condvar)>);
@@ -382,7 +389,7 @@ mod tests {
 
     #[test]
     fn smoke_static() {
-        static M: StaticMutex = MUTEX_INIT;
+        static M: StaticMutex = StaticMutex::new();
         unsafe {
             drop(M.lock().unwrap());
             drop(M.lock().unwrap());
@@ -392,7 +399,7 @@ mod tests {
 
     #[test]
     fn lots_and_lots() {
-        static M: StaticMutex = MUTEX_INIT;
+        static M: StaticMutex = StaticMutex::new();
         static mut CNT: u32 = 0;
         const J: u32 = 1000;
         const K: u32 = 3;
diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs
index 57baedaad9c..269affff208 100644
--- a/src/libstd/sync/once.rs
+++ b/src/libstd/sync/once.rs
@@ -16,8 +16,8 @@
 use prelude::v1::*;
 
 use isize;
-use sync::atomic::{AtomicIsize, Ordering, ATOMIC_ISIZE_INIT};
-use sync::{StaticMutex, MUTEX_INIT};
+use sync::atomic::{AtomicIsize, Ordering};
+use sync::StaticMutex;
 
 /// A synchronization primitive which can be used to run a one-time global
 /// initialization. Useful for one-time initialization for FFI or related
@@ -44,13 +44,19 @@ pub struct Once {
 
 /// Initialization value for static `Once` values.
 #[stable(feature = "rust1", since = "1.0.0")]
-pub const ONCE_INIT: Once = Once {
-    mutex: MUTEX_INIT,
-    cnt: ATOMIC_ISIZE_INIT,
-    lock_cnt: ATOMIC_ISIZE_INIT,
-};
+pub const ONCE_INIT: Once = Once::new();
 
 impl Once {
+    /// Creates a new `Once` value.
+    #[unstable(feature = "std_misc")]
+    pub const fn new() -> Once {
+        Once {
+            mutex: StaticMutex::new(),
+            cnt: AtomicIsize::new(0),
+            lock_cnt: AtomicIsize::new(0),
+        }
+    }
+
     /// Performs an initialization routine once and only once. The given closure
     /// will be executed if this is the first time `call_once` has been called,
     /// and otherwise the routine will *not* be invoked.
@@ -129,12 +135,12 @@ mod tests {
     use prelude::v1::*;
 
     use thread;
-    use super::{ONCE_INIT, Once};
+    use super::Once;
     use sync::mpsc::channel;
 
     #[test]
     fn smoke_once() {
-        static O: Once = ONCE_INIT;
+        static O: Once = Once::new();
         let mut a = 0;
         O.call_once(|| a += 1);
         assert_eq!(a, 1);
@@ -144,7 +150,7 @@ mod tests {
 
     #[test]
     fn stampede_once() {
-        static O: Once = ONCE_INIT;
+        static O: Once = Once::new();
         static mut run: bool = false;
 
         let (tx, rx) = channel();
diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs
index 36f6fbf3b72..e7c3d744c17 100644
--- a/src/libstd/sync/rwlock.rs
+++ b/src/libstd/sync/rwlock.rs
@@ -102,10 +102,7 @@ pub struct StaticRwLock {
 /// Constant initialization for a statically-initialized rwlock.
 #[unstable(feature = "std_misc",
            reason = "may be merged with RwLock in the future")]
-pub const RW_LOCK_INIT: StaticRwLock = StaticRwLock {
-    lock: sys::RWLOCK_INIT,
-    poison: poison::FLAG_INIT,
-};
+pub const RW_LOCK_INIT: StaticRwLock = StaticRwLock::new();
 
 /// RAII structure used to release the shared read access of a lock when
 /// dropped.
@@ -142,7 +139,7 @@ impl<T> RwLock<T> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(t: T) -> RwLock<T> {
-        RwLock { inner: box RW_LOCK_INIT, data: UnsafeCell::new(t) }
+        RwLock { inner: box StaticRwLock::new(), data: UnsafeCell::new(t) }
     }
 }
 
@@ -280,9 +277,19 @@ impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLock<T> {
 
 struct Dummy(UnsafeCell<()>);
 unsafe impl Sync for Dummy {}
-static DUMMY: Dummy = Dummy(UnsafeCell { value: () });
+static DUMMY: Dummy = Dummy(UnsafeCell::new(()));
 
 impl StaticRwLock {
+    /// Creates a new rwlock.
+    #[unstable(feature = "std_misc",
+               reason = "may be merged with RwLock in the future")]
+    pub const fn new() -> StaticRwLock {
+        StaticRwLock {
+            lock: sys::RWLock::new(),
+            poison: poison::Flag::new(),
+        }
+    }
+
     /// Locks this rwlock with shared read access, blocking the current thread
     /// until it can be acquired.
     ///
@@ -420,7 +427,7 @@ mod tests {
     use rand::{self, Rng};
     use sync::mpsc::channel;
     use thread;
-    use sync::{Arc, RwLock, StaticRwLock, TryLockError, RW_LOCK_INIT};
+    use sync::{Arc, RwLock, StaticRwLock, TryLockError};
 
     #[test]
     fn smoke() {
@@ -433,7 +440,7 @@ mod tests {
 
     #[test]
     fn static_smoke() {
-        static R: StaticRwLock = RW_LOCK_INIT;
+        static R: StaticRwLock = StaticRwLock::new();
         drop(R.read().unwrap());
         drop(R.write().unwrap());
         drop((R.read().unwrap(), R.read().unwrap()));
@@ -443,7 +450,7 @@ mod tests {
 
     #[test]
     fn frob() {
-        static R: StaticRwLock = RW_LOCK_INIT;
+        static R: StaticRwLock = StaticRwLock::new();
         const N: usize = 10;
         const M: usize = 1000;
 
diff --git a/src/libstd/sys/common/condvar.rs b/src/libstd/sys/common/condvar.rs
index 9f46b0c3824..33734a88cf3 100644
--- a/src/libstd/sys/common/condvar.rs
+++ b/src/libstd/sys/common/condvar.rs
@@ -20,16 +20,12 @@ use sys::condvar as imp;
 /// this type.
 pub struct Condvar(imp::Condvar);
 
-/// Static initializer for condition variables.
-pub const CONDVAR_INIT: Condvar = Condvar(imp::CONDVAR_INIT);
-
 impl Condvar {
     /// Creates a new condition variable for use.
     ///
     /// Behavior is undefined if the condition variable is moved after it is
     /// first used with any of the functions below.
-    #[inline]
-    pub unsafe fn new() -> Condvar { Condvar(imp::Condvar::new()) }
+    pub const fn new() -> Condvar { Condvar(imp::Condvar::new()) }
 
     /// Signals one waiter on this condition variable to wake up.
     #[inline]
diff --git a/src/libstd/sys/common/mutex.rs b/src/libstd/sys/common/mutex.rs
index 1f9dd54192c..5a6dfe7fb1a 100644
--- a/src/libstd/sys/common/mutex.rs
+++ b/src/libstd/sys/common/mutex.rs
@@ -20,10 +20,13 @@ pub struct Mutex(imp::Mutex);
 
 unsafe impl Sync for Mutex {}
 
-/// Constant initializer for statically allocated mutexes.
-pub const MUTEX_INIT: Mutex = Mutex(imp::MUTEX_INIT);
-
 impl Mutex {
+    /// Creates a new mutex for use.
+    ///
+    /// Behavior is undefined if the mutex is moved after it is
+    /// first used with any of the functions below.
+    pub const fn new() -> Mutex { Mutex(imp::Mutex::new()) }
+
     /// Locks the mutex blocking the current thread until it is available.
     ///
     /// Behavior is undefined if the mutex has been moved between this and any
diff --git a/src/libstd/sys/common/poison.rs b/src/libstd/sys/common/poison.rs
index 67679c11a98..48c81982725 100644
--- a/src/libstd/sys/common/poison.rs
+++ b/src/libstd/sys/common/poison.rs
@@ -10,26 +10,28 @@
 
 use prelude::v1::*;
 
-use marker::Reflect;
-use cell::UnsafeCell;
+use cell::Cell;
 use error::{Error};
 use fmt;
+use marker::Reflect;
 use thread;
 
-pub struct Flag { failed: UnsafeCell<bool> }
+pub struct Flag { failed: Cell<bool> }
 
 // This flag is only ever accessed with a lock previously held. Note that this
 // a totally private structure.
 unsafe impl Send for Flag {}
 unsafe impl Sync for Flag {}
 
-pub const FLAG_INIT: Flag = Flag { failed: UnsafeCell { value: false } };
-
 impl Flag {
+    pub const fn new() -> Flag {
+        Flag { failed: Cell::new(false) }
+    }
+
     #[inline]
     pub fn borrow(&self) -> LockResult<Guard> {
         let ret = Guard { panicking: thread::panicking() };
-        if unsafe { *self.failed.get() } {
+        if self.get() {
             Err(PoisonError::new(ret))
         } else {
             Ok(ret)
@@ -39,13 +41,13 @@ impl Flag {
     #[inline]
     pub fn done(&self, guard: &Guard) {
         if !guard.panicking && thread::panicking() {
-            unsafe { *self.failed.get() = true; }
+            self.failed.set(true);
         }
     }
 
     #[inline]
     pub fn get(&self) -> bool {
-        unsafe { *self.failed.get() }
+        self.failed.get()
     }
 }
 
diff --git a/src/libstd/sys/common/remutex.rs b/src/libstd/sys/common/remutex.rs
index 1a467580672..72f8453233a 100644
--- a/src/libstd/sys/common/remutex.rs
+++ b/src/libstd/sys/common/remutex.rs
@@ -54,7 +54,7 @@ impl<T> ReentrantMutex<T> {
         unsafe {
             let mut mutex = ReentrantMutex {
                 inner: box sys::ReentrantMutex::uninitialized(),
-                poison: poison::FLAG_INIT,
+                poison: poison::Flag::new(),
                 data: t,
             };
             mutex.inner.init();
diff --git a/src/libstd/sys/common/rwlock.rs b/src/libstd/sys/common/rwlock.rs
index 725a09bcc86..71a4f01ec4c 100644
--- a/src/libstd/sys/common/rwlock.rs
+++ b/src/libstd/sys/common/rwlock.rs
@@ -17,10 +17,13 @@ use sys::rwlock as imp;
 /// safer types at the top level of this crate instead of this type.
 pub struct RWLock(imp::RWLock);
 
-/// Constant initializer for static RWLocks.
-pub const RWLOCK_INIT: RWLock = RWLock(imp::RWLOCK_INIT);
-
 impl RWLock {
+    /// Creates a new reader-writer lock for use.
+    ///
+    /// Behavior is undefined if the reader-writer lock is moved after it is
+    /// first used with any of the functions below.
+    pub const fn new() -> RWLock { RWLock(imp::RWLock::new()) }
+
     /// Acquires shared access to the underlying lock, blocking the current
     /// thread to do so.
     ///
diff --git a/src/libstd/sys/common/thread_local.rs b/src/libstd/sys/common/thread_local.rs
index 618a389110a..eb4cbfcfbcd 100644
--- a/src/libstd/sys/common/thread_local.rs
+++ b/src/libstd/sys/common/thread_local.rs
@@ -86,19 +86,13 @@ use sys::thread_local as imp;
 /// }
 /// ```
 pub struct StaticKey {
-    /// Inner static TLS key (internals), created with by `INIT_INNER` in this
-    /// module.
-    pub inner: StaticKeyInner,
+    /// Inner static TLS key (internals).
+    key: AtomicUsize,
     /// Destructor for the TLS value.
     ///
     /// See `Key::new` for information about when the destructor runs and how
     /// it runs.
-    pub dtor: Option<unsafe extern fn(*mut u8)>,
-}
-
-/// Inner contents of `StaticKey`, created by the `INIT_INNER` constant.
-pub struct StaticKeyInner {
-    key: AtomicUsize,
+    dtor: Option<unsafe extern fn(*mut u8)>,
 }
 
 /// A type for a safely managed OS-based TLS slot.
@@ -129,19 +123,16 @@ pub struct Key {
 /// Constant initialization value for static TLS keys.
 ///
 /// This value specifies no destructor by default.
-pub const INIT: StaticKey = StaticKey {
-    inner: INIT_INNER,
-    dtor: None,
-};
-
-/// Constant initialization value for the inner part of static TLS keys.
-///
-/// This value allows specific configuration of the destructor for a TLS key.
-pub const INIT_INNER: StaticKeyInner = StaticKeyInner {
-    key: atomic::ATOMIC_USIZE_INIT,
-};
+pub const INIT: StaticKey = StaticKey::new(None);
 
 impl StaticKey {
+    pub const fn new(dtor: Option<unsafe extern fn(*mut u8)>) -> StaticKey {
+        StaticKey {
+            key: atomic::AtomicUsize::new(0),
+            dtor: dtor
+        }
+    }
+
     /// Gets the value associated with this TLS key
     ///
     /// This will lazily allocate a TLS key from the OS if one has not already
@@ -164,7 +155,7 @@ impl StaticKey {
     /// Note that this does *not* run the user-provided destructor if one was
     /// specified at definition time. Doing so must be done manually.
     pub unsafe fn destroy(&self) {
-        match self.inner.key.swap(0, Ordering::SeqCst) {
+        match self.key.swap(0, Ordering::SeqCst) {
             0 => {}
             n => { imp::destroy(n as imp::Key) }
         }
@@ -172,7 +163,7 @@ impl StaticKey {
 
     #[inline]
     unsafe fn key(&self) -> imp::Key {
-        match self.inner.key.load(Ordering::Relaxed) {
+        match self.key.load(Ordering::Relaxed) {
             0 => self.lazy_init() as imp::Key,
             n => n as imp::Key
         }
@@ -197,7 +188,7 @@ impl StaticKey {
             key2
         };
         assert!(key != 0);
-        match self.inner.key.compare_and_swap(0, key as usize, Ordering::SeqCst) {
+        match self.key.compare_and_swap(0, key as usize, Ordering::SeqCst) {
             // The CAS succeeded, so we've created the actual key
             0 => key as usize,
             // If someone beat us to the punch, use their key instead
@@ -245,7 +236,7 @@ impl Drop for Key {
 #[cfg(test)]
 mod tests {
     use prelude::v1::*;
-    use super::{Key, StaticKey, INIT_INNER};
+    use super::{Key, StaticKey};
 
     fn assert_sync<T: Sync>() {}
     fn assert_send<T: Send>() {}
@@ -267,8 +258,8 @@ mod tests {
 
     #[test]
     fn statik() {
-        static K1: StaticKey = StaticKey { inner: INIT_INNER, dtor: None };
-        static K2: StaticKey = StaticKey { inner: INIT_INNER, dtor: None };
+        static K1: StaticKey = StaticKey::new(None);
+        static K2: StaticKey = StaticKey::new(None);
 
         unsafe {
             assert!(K1.get().is_null());
diff --git a/src/libstd/sys/unix/backtrace.rs b/src/libstd/sys/unix/backtrace.rs
index 135ae1bf916..b23a3eee1a1 100644
--- a/src/libstd/sys/unix/backtrace.rs
+++ b/src/libstd/sys/unix/backtrace.rs
@@ -91,7 +91,7 @@ use io;
 use libc;
 use mem;
 use str;
-use sync::{StaticMutex, MUTEX_INIT};
+use sync::StaticMutex;
 
 use sys_common::backtrace::*;
 
@@ -117,7 +117,7 @@ pub fn write(w: &mut Write) -> io::Result<()> {
     // while it doesn't requires lock for work as everything is
     // local, it still displays much nicer backtraces when a
     // couple of threads panic simultaneously
-    static LOCK: StaticMutex = MUTEX_INIT;
+    static LOCK: StaticMutex = StaticMutex::new();
     let _g = LOCK.lock();
 
     try!(writeln!(w, "stack backtrace:"));
@@ -148,7 +148,7 @@ pub fn write(w: &mut Write) -> io::Result<()> {
     // is semi-reasonable in terms of printing anyway, and we know that all
     // I/O done here is blocking I/O, not green I/O, so we don't have to
     // worry about this being a native vs green mutex.
-    static LOCK: StaticMutex = MUTEX_INIT;
+    static LOCK: StaticMutex = StaticMutex::new();
     let _g = LOCK.lock();
 
     try!(writeln!(w, "stack backtrace:"));
diff --git a/src/libstd/sys/unix/condvar.rs b/src/libstd/sys/unix/condvar.rs
index 29a13cc6be7..c8708190a2e 100644
--- a/src/libstd/sys/unix/condvar.rs
+++ b/src/libstd/sys/unix/condvar.rs
@@ -23,13 +23,8 @@ pub struct Condvar { inner: UnsafeCell<ffi::pthread_cond_t> }
 unsafe impl Send for Condvar {}
 unsafe impl Sync for Condvar {}
 
-pub const CONDVAR_INIT: Condvar = Condvar {
-    inner: UnsafeCell { value: ffi::PTHREAD_COND_INITIALIZER },
-};
-
 impl Condvar {
-    #[inline]
-    pub unsafe fn new() -> Condvar {
+    pub const fn new() -> Condvar {
         // Might be moved and address is changing it is better to avoid
         // initialization of potentially opaque OS data before it landed
         Condvar { inner: UnsafeCell::new(ffi::PTHREAD_COND_INITIALIZER) }
diff --git a/src/libstd/sys/unix/mutex.rs b/src/libstd/sys/unix/mutex.rs
index 70d14f63dbc..6eed403dfc0 100644
--- a/src/libstd/sys/unix/mutex.rs
+++ b/src/libstd/sys/unix/mutex.rs
@@ -21,20 +21,15 @@ pub unsafe fn raw(m: &Mutex) -> *mut ffi::pthread_mutex_t {
     m.inner.get()
 }
 
-pub const MUTEX_INIT: Mutex = Mutex {
-    inner: UnsafeCell { value: ffi::PTHREAD_MUTEX_INITIALIZER },
-};
-
 unsafe impl Send for Mutex {}
 unsafe impl Sync for Mutex {}
 
 #[allow(dead_code)] // sys isn't exported yet
 impl Mutex {
-    #[inline]
-    pub unsafe fn new() -> Mutex {
+    pub const fn new() -> Mutex {
         // Might be moved and address is changing it is better to avoid
         // initialization of potentially opaque OS data before it landed
-        MUTEX_INIT
+        Mutex { inner: UnsafeCell::new(ffi::PTHREAD_MUTEX_INITIALIZER) }
     }
     #[inline]
     pub unsafe fn lock(&self) {
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs
index 5919502abde..5178d7b8fb1 100644
--- a/src/libstd/sys/unix/os.rs
+++ b/src/libstd/sys/unix/os.rs
@@ -216,8 +216,8 @@ pub fn current_exe() -> io::Result<PathBuf> {
 
 #[cfg(any(target_os = "bitrig", target_os = "openbsd"))]
 pub fn current_exe() -> io::Result<PathBuf> {
-    use sync::{StaticMutex, MUTEX_INIT};
-    static LOCK: StaticMutex = MUTEX_INIT;
+    use sync::StaticMutex;
+    static LOCK: StaticMutex = StaticMutex::new();
 
     extern {
         fn rust_current_exe() -> *const c_char;
diff --git a/src/libstd/sys/unix/rwlock.rs b/src/libstd/sys/unix/rwlock.rs
index 7bb9fb68c14..ee687f350f0 100644
--- a/src/libstd/sys/unix/rwlock.rs
+++ b/src/libstd/sys/unix/rwlock.rs
@@ -16,14 +16,13 @@ use sys::sync as ffi;
 
 pub struct RWLock { inner: UnsafeCell<ffi::pthread_rwlock_t> }
 
-pub const RWLOCK_INIT: RWLock = RWLock {
-    inner: UnsafeCell { value: ffi::PTHREAD_RWLOCK_INITIALIZER },
-};
-
 unsafe impl Send for RWLock {}
 unsafe impl Sync for RWLock {}
 
 impl RWLock {
+    pub const fn new() -> RWLock {
+        RWLock { inner: UnsafeCell::new(ffi::PTHREAD_RWLOCK_INITIALIZER) }
+    }
     #[inline]
     pub unsafe fn read(&self) {
         let r = ffi::pthread_rwlock_rdlock(self.inner.get());
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index 0cb5a06e6b6..bb0e12e8df8 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -330,10 +330,10 @@ pub mod guard {
 #[cfg(target_os = "linux")]
 fn min_stack_size(attr: *const libc::pthread_attr_t) -> usize {
     use dynamic_lib::DynamicLibrary;
-    use sync::{Once, ONCE_INIT};
+    use sync::Once;
 
     type F = unsafe extern "C" fn(*const libc::pthread_attr_t) -> libc::size_t;
-    static INIT: Once = ONCE_INIT;
+    static INIT: Once = Once::new();
     static mut __pthread_get_minstack: Option<F> = None;
 
     INIT.call_once(|| {
diff --git a/src/libstd/sys/unix/thread_local.rs b/src/libstd/sys/unix/thread_local.rs
index 9b7079ee108..3afe84b2580 100644
--- a/src/libstd/sys/unix/thread_local.rs
+++ b/src/libstd/sys/unix/thread_local.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![allow(dead_code)] // sys isn't exported yet
+
 use prelude::v1::*;
 use libc::c_int;
 
diff --git a/src/libstd/sys/unix/time.rs b/src/libstd/sys/unix/time.rs
index 16dfd3eebd0..6b84baeca7d 100644
--- a/src/libstd/sys/unix/time.rs
+++ b/src/libstd/sys/unix/time.rs
@@ -17,7 +17,7 @@ mod inner {
     use libc;
     use time::Duration;
     use ops::Sub;
-    use sync::{Once, ONCE_INIT};
+    use sync::Once;
     use super::NSEC_PER_SEC;
 
     pub struct SteadyTime {
@@ -42,7 +42,7 @@ mod inner {
             numer: 0,
             denom: 0,
         };
-        static ONCE: Once = ONCE_INIT;
+        static ONCE: Once = Once::new();
 
         unsafe {
             ONCE.call_once(|| {
diff --git a/src/libstd/sys/windows/backtrace.rs b/src/libstd/sys/windows/backtrace.rs
index d94dfdeeea4..3f595762fc7 100644
--- a/src/libstd/sys/windows/backtrace.rs
+++ b/src/libstd/sys/windows/backtrace.rs
@@ -36,7 +36,7 @@ use mem;
 use path::Path;
 use ptr;
 use str;
-use sync::{StaticMutex, MUTEX_INIT};
+use sync::StaticMutex;
 
 use sys_common::backtrace::*;
 
@@ -295,7 +295,7 @@ impl Drop for Cleanup {
 pub fn write(w: &mut Write) -> io::Result<()> {
     // According to windows documentation, all dbghelp functions are
     // single-threaded.
-    static LOCK: StaticMutex = MUTEX_INIT;
+    static LOCK: StaticMutex = StaticMutex::new();
     let _g = LOCK.lock();
 
     // Open up dbghelp.dll, we don't link to it explicitly because it can't
diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs
index e9b850856e1..3c9b2ef1b98 100644
--- a/src/libstd/sys/windows/c.rs
+++ b/src/libstd/sys/windows/c.rs
@@ -340,10 +340,10 @@ pub mod compat {
                                       -> $rettype:ty { $fallback:expr }) => (
             #[inline(always)]
             pub unsafe fn $symbol($($argname: $argtype),*) -> $rettype {
-                use sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
+                use sync::atomic::{AtomicUsize, Ordering};
                 use mem;
 
-                static PTR: AtomicUsize = ATOMIC_USIZE_INIT;
+                static PTR: AtomicUsize = AtomicUsize::new(0);
 
                 fn load() -> usize {
                     ::sys::c::compat::store_func(&PTR,
diff --git a/src/libstd/sys/windows/condvar.rs b/src/libstd/sys/windows/condvar.rs
index 8bb2326e4d6..baa7d1ceea3 100644
--- a/src/libstd/sys/windows/condvar.rs
+++ b/src/libstd/sys/windows/condvar.rs
@@ -22,13 +22,10 @@ pub struct Condvar { inner: UnsafeCell<ffi::CONDITION_VARIABLE> }
 unsafe impl Send for Condvar {}
 unsafe impl Sync for Condvar {}
 
-pub const CONDVAR_INIT: Condvar = Condvar {
-    inner: UnsafeCell { value: ffi::CONDITION_VARIABLE_INIT }
-};
-
 impl Condvar {
-    #[inline]
-    pub unsafe fn new() -> Condvar { CONDVAR_INIT }
+    pub const fn new() -> Condvar {
+        Condvar { inner: UnsafeCell::new(ffi::CONDITION_VARIABLE_INIT) }
+    }
 
     #[inline]
     pub unsafe fn wait(&self, mutex: &Mutex) {
diff --git a/src/libstd/sys/windows/mutex.rs b/src/libstd/sys/windows/mutex.rs
index 9d2624f9418..29e370698ad 100644
--- a/src/libstd/sys/windows/mutex.rs
+++ b/src/libstd/sys/windows/mutex.rs
@@ -16,10 +16,6 @@ use mem;
 
 pub struct Mutex { inner: UnsafeCell<ffi::SRWLOCK> }
 
-pub const MUTEX_INIT: Mutex = Mutex {
-    inner: UnsafeCell { value: ffi::SRWLOCK_INIT }
-};
-
 unsafe impl Send for Mutex {}
 unsafe impl Sync for Mutex {}
 
@@ -41,6 +37,9 @@ pub unsafe fn raw(m: &Mutex) -> ffi::PSRWLOCK {
 //    is there there are no guarantees of fairness.
 
 impl Mutex {
+    pub const fn new() -> Mutex {
+        Mutex { inner: UnsafeCell::new(ffi::SRWLOCK_INIT) }
+    }
     #[inline]
     pub unsafe fn lock(&self) {
         ffi::AcquireSRWLockExclusive(self.inner.get())
diff --git a/src/libstd/sys/windows/net.rs b/src/libstd/sys/windows/net.rs
index 6bbcd968157..71e064bcc6b 100644
--- a/src/libstd/sys/windows/net.rs
+++ b/src/libstd/sys/windows/net.rs
@@ -18,7 +18,7 @@ use net::SocketAddr;
 use num::One;
 use ops::Neg;
 use rt;
-use sync::{Once, ONCE_INIT};
+use sync::Once;
 use sys::c;
 use sys_common::{AsInner, FromInner};
 
@@ -29,7 +29,7 @@ pub struct Socket(libc::SOCKET);
 /// Checks whether the Windows socket interface has been started already, and
 /// if not, starts it.
 pub fn init() {
-    static START: Once = ONCE_INIT;
+    static START: Once = Once::new();
 
     START.call_once(|| unsafe {
         let mut data: c::WSADATA = mem::zeroed();
diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs
index bc4762c197e..178b6ea42d2 100644
--- a/src/libstd/sys/windows/process.rs
+++ b/src/libstd/sys/windows/process.rs
@@ -24,7 +24,7 @@ use mem;
 use os::windows::ffi::OsStrExt;
 use path::Path;
 use ptr;
-use sync::{StaticMutex, MUTEX_INIT};
+use sync::StaticMutex;
 use sys::c;
 use sys::fs::{OpenOptions, File};
 use sys::handle::Handle;
@@ -169,7 +169,7 @@ impl Process {
         try!(unsafe {
             // `CreateProcess` is racy!
             // http://support.microsoft.com/kb/315939
-            static CREATE_PROCESS_LOCK: StaticMutex = MUTEX_INIT;
+            static CREATE_PROCESS_LOCK: StaticMutex = StaticMutex::new();
             let _lock = CREATE_PROCESS_LOCK.lock();
 
             cvt(CreateProcessW(ptr::null(),
diff --git a/src/libstd/sys/windows/rwlock.rs b/src/libstd/sys/windows/rwlock.rs
index 009605535a0..e727638e3e9 100644
--- a/src/libstd/sys/windows/rwlock.rs
+++ b/src/libstd/sys/windows/rwlock.rs
@@ -15,14 +15,13 @@ use sys::sync as ffi;
 
 pub struct RWLock { inner: UnsafeCell<ffi::SRWLOCK> }
 
-pub const RWLOCK_INIT: RWLock = RWLock {
-    inner: UnsafeCell { value: ffi::SRWLOCK_INIT }
-};
-
 unsafe impl Send for RWLock {}
 unsafe impl Sync for RWLock {}
 
 impl RWLock {
+    pub const fn new() -> RWLock {
+        RWLock { inner: UnsafeCell::new(ffi::SRWLOCK_INIT) }
+    }
     #[inline]
     pub unsafe fn read(&self) {
         ffi::AcquireSRWLockShared(self.inner.get())
diff --git a/src/libstd/sys/windows/thread_local.rs b/src/libstd/sys/windows/thread_local.rs
index ea5af3f2830..a3d522d1757 100644
--- a/src/libstd/sys/windows/thread_local.rs
+++ b/src/libstd/sys/windows/thread_local.rs
@@ -15,7 +15,7 @@ use libc::types::os::arch::extra::{DWORD, LPVOID, BOOL};
 use boxed;
 use ptr;
 use rt;
-use sys_common::mutex::{MUTEX_INIT, Mutex};
+use sys_common::mutex::Mutex;
 
 pub type Key = DWORD;
 pub type Dtor = unsafe extern fn(*mut u8);
@@ -58,7 +58,7 @@ pub type Dtor = unsafe extern fn(*mut u8);
 // on poisoning and this module needs to operate at a lower level than requiring
 // the thread infrastructure to be in place (useful on the borders of
 // initialization/destruction).
-static DTOR_LOCK: Mutex = MUTEX_INIT;
+static DTOR_LOCK: Mutex = Mutex::new();
 static mut DTORS: *mut Vec<(Key, Dtor)> = 0 as *mut _;
 
 // -------------------------------------------------------------------------
diff --git a/src/libstd/sys/windows/time.rs b/src/libstd/sys/windows/time.rs
index e64df54a0fa..f5a70ccc907 100644
--- a/src/libstd/sys/windows/time.rs
+++ b/src/libstd/sys/windows/time.rs
@@ -10,7 +10,7 @@
 use libc;
 use ops::Sub;
 use time::Duration;
-use sync::{Once, ONCE_INIT};
+use sync::Once;
 
 const NANOS_PER_SEC: u64 = 1_000_000_000;
 
@@ -28,7 +28,7 @@ impl SteadyTime {
 
 fn frequency() -> libc::LARGE_INTEGER {
     static mut FREQUENCY: libc::LARGE_INTEGER = 0;
-    static ONCE: Once = ONCE_INIT;
+    static ONCE: Once = Once::new();
 
     unsafe {
         ONCE.call_once(|| {
diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs
index 2e043c58a5d..0eafd4d5f12 100644
--- a/src/libstd/thread/local.rs
+++ b/src/libstd/thread/local.rs
@@ -18,12 +18,7 @@ use cell::UnsafeCell;
 
 // Sure wish we had macro hygiene, no?
 #[doc(hidden)]
-pub mod __impl {
-    pub use super::imp::Key as KeyInner;
-    pub use super::imp::destroy_value;
-    pub use sys_common::thread_local::INIT_INNER as OS_INIT_INNER;
-    pub use sys_common::thread_local::StaticKey as OsStaticKey;
-}
+pub use self::imp::Key as __KeyInner;
 
 /// A thread local storage key which owns its contents.
 ///
@@ -76,55 +71,10 @@ pub struct LocalKey<T> {
     //
     // This is trivially devirtualizable by LLVM because we never store anything
     // to this field and rustc can declare the `static` as constant as well.
-    #[doc(hidden)]
-    pub inner: fn() -> &'static __impl::KeyInner<UnsafeCell<Option<T>>>,
+    inner: fn() -> &'static __KeyInner<T>,
 
     // initialization routine to invoke to create a value
-    #[doc(hidden)]
-    pub init: fn() -> T,
-}
-
-/// Declare a new thread local storage key of type `std::thread::LocalKey`.
-///
-/// See [LocalKey documentation](thread/struct.LocalKey.html) for more information.
-#[macro_export]
-#[stable(feature = "rust1", since = "1.0.0")]
-#[allow_internal_unstable]
-macro_rules! thread_local {
-    (static $name:ident: $t:ty = $init:expr) => (
-        static $name: ::std::thread::LocalKey<$t> = {
-            use std::cell::UnsafeCell as __UnsafeCell;
-            use std::thread::__local::KeyInner as __KeyInner;
-            use std::option::Option as __Option;
-            use std::option::Option::None as __None;
-
-            __thread_local_inner!(static __KEY: __UnsafeCell<__Option<$t>> = {
-                __UnsafeCell { value: __None }
-            });
-            fn __init() -> $t { $init }
-            fn __getit() -> &'static __KeyInner<__UnsafeCell<__Option<$t>>> {
-                &__KEY
-            }
-            ::std::thread::LocalKey { inner: __getit, init: __init }
-        };
-    );
-    (pub static $name:ident: $t:ty = $init:expr) => (
-        pub static $name: ::std::thread::LocalKey<$t> = {
-            use std::cell::UnsafeCell as __UnsafeCell;
-            use std::thread::__local::KeyInner as __KeyInner;
-            use std::option::Option as __Option;
-            use std::option::Option::None as __None;
-
-            __thread_local_inner!(static __KEY: __UnsafeCell<__Option<$t>> = {
-                __UnsafeCell { value: __None }
-            });
-            fn __init() -> $t { $init }
-            fn __getit() -> &'static __KeyInner<__UnsafeCell<__Option<$t>>> {
-                &__KEY
-            }
-            ::std::thread::LocalKey { inner: __getit, init: __init }
-        };
-    );
+    init: fn() -> T,
 }
 
 // Macro pain #4586:
@@ -147,50 +97,37 @@ macro_rules! thread_local {
 // To get around this, we're forced to inject the #[cfg] logic into the macro
 // itself. Woohoo.
 
+/// Declare a new thread local storage key of type `std::thread::LocalKey`.
+///
+/// See [LocalKey documentation](thread/struct.LocalKey.html) for more information.
 #[macro_export]
-#[doc(hidden)]
+#[stable(feature = "rust1", since = "1.0.0")]
 #[allow_internal_unstable]
-macro_rules! __thread_local_inner {
+macro_rules! thread_local {
     (static $name:ident: $t:ty = $init:expr) => (
-        #[cfg_attr(all(any(target_os = "macos", target_os = "linux"),
-                       not(target_arch = "aarch64")),
-                   thread_local)]
-        static $name: ::std::thread::__local::KeyInner<$t> =
-            __thread_local_inner!($init, $t);
+        static $name: ::std::thread::LocalKey<$t> = {
+            #[cfg_attr(all(any(target_os = "macos", target_os = "linux"),
+                           not(target_arch = "aarch64")),
+                       thread_local)]
+            static __KEY: ::std::thread::__LocalKeyInner<$t> =
+                ::std::thread::__LocalKeyInner::new();
+            fn __init() -> $t { $init }
+            fn __getit() -> &'static ::std::thread::__LocalKeyInner<$t> { &__KEY }
+            ::std::thread::LocalKey::new(__getit, __init)
+        };
     );
     (pub static $name:ident: $t:ty = $init:expr) => (
-        #[cfg_attr(all(any(target_os = "macos", target_os = "linux"),
-                       not(target_arch = "aarch64")),
-                   thread_local)]
-        pub static $name: ::std::thread::__local::KeyInner<$t> =
-            __thread_local_inner!($init, $t);
-    );
-    ($init:expr, $t:ty) => ({
-        #[cfg(all(any(target_os = "macos", target_os = "linux"), not(target_arch = "aarch64")))]
-        const _INIT: ::std::thread::__local::KeyInner<$t> = {
-            ::std::thread::__local::KeyInner {
-                inner: ::std::cell::UnsafeCell { value: $init },
-                dtor_registered: ::std::cell::UnsafeCell { value: false },
-                dtor_running: ::std::cell::UnsafeCell { value: false },
-            }
-        };
-
-        #[allow(trivial_casts)]
-        #[cfg(any(not(any(target_os = "macos", target_os = "linux")), target_arch = "aarch64"))]
-        const _INIT: ::std::thread::__local::KeyInner<$t> = {
-            ::std::thread::__local::KeyInner {
-                inner: ::std::cell::UnsafeCell { value: $init },
-                os: ::std::thread::__local::OsStaticKey {
-                    inner: ::std::thread::__local::OS_INIT_INNER,
-                    dtor: ::std::option::Option::Some(
-                        ::std::thread::__local::destroy_value::<$t>
-                    ),
-                },
-            }
+        pub static $name: ::std::thread::LocalKey<$t> = {
+            #[cfg_attr(all(any(target_os = "macos", target_os = "linux"),
+                           not(target_arch = "aarch64")),
+                       thread_local)]
+            static __KEY: ::std::thread::__LocalKeyInner<$t> =
+                ::std::thread::__LocalKeyInner::new();
+            fn __init() -> $t { $init }
+            fn __getit() -> &'static ::std::thread::__LocalKeyInner<$t> { &__KEY }
+            ::std::thread::LocalKey::new(__getit, __init)
         };
-
-        _INIT
-    });
+    );
 }
 
 /// Indicator of the state of a thread local storage key.
@@ -225,6 +162,14 @@ pub enum LocalKeyState {
 }
 
 impl<T: 'static> LocalKey<T> {
+    #[doc(hidden)]
+    pub const fn new(inner: fn() -> &'static __KeyInner<T>, init: fn() -> T) -> LocalKey<T> {
+        LocalKey {
+            inner: inner,
+            init: init
+        }
+    }
+
     /// Acquires a reference to the value in this TLS key.
     ///
     /// This will lazily initialize the value if this thread has not referenced
@@ -300,44 +245,45 @@ impl<T: 'static> LocalKey<T> {
 mod imp {
     use prelude::v1::*;
 
-    use cell::UnsafeCell;
+    use cell::{Cell, UnsafeCell};
     use intrinsics;
-    use ptr;
 
     pub struct Key<T> {
-        // Place the inner bits in an `UnsafeCell` to currently get around the
-        // "only Sync statics" restriction. This allows any type to be placed in
-        // the cell.
-        //
-        // Note that all access requires `T: 'static` so it can't be a type with
-        // any borrowed pointers still.
-        pub inner: UnsafeCell<T>,
+        inner: UnsafeCell<Option<T>>,
 
         // Metadata to keep track of the state of the destructor. Remember that
         // these variables are thread-local, not global.
-        pub dtor_registered: UnsafeCell<bool>, // should be Cell
-        pub dtor_running: UnsafeCell<bool>, // should be Cell
+        dtor_registered: Cell<bool>,
+        dtor_running: Cell<bool>,
     }
 
     unsafe impl<T> ::marker::Sync for Key<T> { }
 
     impl<T> Key<T> {
-        pub unsafe fn get(&'static self) -> Option<&'static T> {
-            if intrinsics::needs_drop::<T>() && *self.dtor_running.get() {
+        pub const fn new() -> Key<T> {
+            Key {
+                inner: UnsafeCell::new(None),
+                dtor_registered: Cell::new(false),
+                dtor_running: Cell::new(false)
+            }
+        }
+
+        pub unsafe fn get(&'static self) -> Option<&'static UnsafeCell<Option<T>>> {
+            if intrinsics::needs_drop::<T>() && self.dtor_running.get() {
                 return None
             }
             self.register_dtor();
-            Some(&*self.inner.get())
+            Some(&self.inner)
         }
 
         unsafe fn register_dtor(&self) {
-            if !intrinsics::needs_drop::<T>() || *self.dtor_registered.get() {
+            if !intrinsics::needs_drop::<T>() || self.dtor_registered.get() {
                 return
             }
 
             register_dtor(self as *const _ as *mut u8,
                           destroy_value::<T>);
-            *self.dtor_registered.get() = true;
+            self.dtor_registered.set(true);
         }
     }
 
@@ -354,6 +300,7 @@ mod imp {
     unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
         use boxed;
         use mem;
+        use ptr;
         use libc;
         use sys_common::thread_local as os;
 
@@ -381,10 +328,7 @@ mod imp {
         // *should* be the case that this loop always terminates because we
         // provide the guarantee that a TLS key cannot be set after it is
         // flagged for destruction.
-        static DTORS: os::StaticKey = os::StaticKey {
-            inner: os::INIT_INNER,
-            dtor: Some(run_dtors as unsafe extern "C" fn(*mut u8)),
-        };
+        static DTORS: os::StaticKey = os::StaticKey::new(Some(run_dtors));
         type List = Vec<(*mut u8, unsafe extern fn(*mut u8))>;
         if DTORS.get().is_null() {
             let v: Box<List> = box Vec::new();
@@ -422,8 +366,8 @@ mod imp {
         // Right before we run the user destructor be sure to flag the
         // destructor as running for this thread so calls to `get` will return
         // `None`.
-        *(*ptr).dtor_running.get() = true;
-        ptr::read((*ptr).inner.get());
+        (*ptr).dtor_running.set(true);
+        intrinsics::drop_in_place((*ptr).inner.get());
     }
 }
 
@@ -433,54 +377,50 @@ mod imp {
     use prelude::v1::*;
 
     use alloc::boxed;
-    use cell::UnsafeCell;
-    use mem;
+    use cell::{Cell, UnsafeCell};
+    use marker;
     use ptr;
     use sys_common::thread_local::StaticKey as OsStaticKey;
 
     pub struct Key<T> {
-        // Statically allocated initialization expression, using an `UnsafeCell`
-        // for the same reasons as above.
-        pub inner: UnsafeCell<T>,
-
         // OS-TLS key that we'll use to key off.
-        pub os: OsStaticKey,
+        os: OsStaticKey,
+        marker: marker::PhantomData<Cell<T>>,
     }
 
     unsafe impl<T> ::marker::Sync for Key<T> { }
 
     struct Value<T: 'static> {
         key: &'static Key<T>,
-        value: T,
+        value: UnsafeCell<Option<T>>,
     }
 
-    impl<T> Key<T> {
-        pub unsafe fn get(&'static self) -> Option<&'static T> {
-            self.ptr().map(|p| &*p)
+    impl<T: 'static> Key<T> {
+        pub const fn new() -> Key<T> {
+            Key {
+                os: OsStaticKey::new(Some(destroy_value::<T>)),
+                marker: marker::PhantomData
+            }
         }
 
-        unsafe fn ptr(&'static self) -> Option<*mut T> {
+        pub unsafe fn get(&'static self) -> Option<&'static UnsafeCell<Option<T>>> {
             let ptr = self.os.get() as *mut Value<T>;
             if !ptr.is_null() {
                 if ptr as usize == 1 {
                     return None
                 }
-                return Some(&mut (*ptr).value as *mut T);
+                return Some(&(*ptr).value);
             }
 
             // If the lookup returned null, we haven't initialized our own local
             // copy, so do that now.
-            //
-            // Also note that this transmute_copy should be ok because the value
-            // `inner` is already validated to be a valid `static` value, so we
-            // should be able to freely copy the bits.
             let ptr: Box<Value<T>> = box Value {
                 key: self,
-                value: mem::transmute_copy(&self.inner),
+                value: UnsafeCell::new(None),
             };
             let ptr = boxed::into_raw(ptr);
             self.os.set(ptr as *mut u8);
-            Some(&mut (*ptr).value as *mut T)
+            Some(&(*ptr).value)
         }
     }
 
@@ -505,7 +445,7 @@ mod tests {
     use prelude::v1::*;
 
     use sync::mpsc::{channel, Sender};
-    use cell::UnsafeCell;
+    use cell::{Cell, UnsafeCell};
     use super::LocalKeyState;
     use thread;
 
@@ -520,23 +460,23 @@ mod tests {
 
     #[test]
     fn smoke_no_dtor() {
-        thread_local!(static FOO: UnsafeCell<i32> = UnsafeCell { value: 1 });
+        thread_local!(static FOO: Cell<i32> = Cell::new(1));
 
-        FOO.with(|f| unsafe {
-            assert_eq!(*f.get(), 1);
-            *f.get() = 2;
+        FOO.with(|f| {
+            assert_eq!(f.get(), 1);
+            f.set(2);
         });
         let (tx, rx) = channel();
         let _t = thread::spawn(move|| {
-            FOO.with(|f| unsafe {
-                assert_eq!(*f.get(), 1);
+            FOO.with(|f| {
+                assert_eq!(f.get(), 1);
             });
             tx.send(()).unwrap();
         });
         rx.recv().unwrap();
 
-        FOO.with(|f| unsafe {
-            assert_eq!(*f.get(), 2);
+        FOO.with(|f| {
+            assert_eq!(f.get(), 2);
         });
     }
 
@@ -565,9 +505,7 @@ mod tests {
 
     #[test]
     fn smoke_dtor() {
-        thread_local!(static FOO: UnsafeCell<Option<Foo>> = UnsafeCell {
-            value: None
-        });
+        thread_local!(static FOO: UnsafeCell<Option<Foo>> = UnsafeCell::new(None));
 
         let (tx, rx) = channel();
         let _t = thread::spawn(move|| unsafe {
@@ -583,12 +521,8 @@ mod tests {
     fn circular() {
         struct S1;
         struct S2;
-        thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell {
-            value: None
-        });
-        thread_local!(static K2: UnsafeCell<Option<S2>> = UnsafeCell {
-            value: None
-        });
+        thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell::new(None));
+        thread_local!(static K2: UnsafeCell<Option<S2>> = UnsafeCell::new(None));
         static mut HITS: u32 = 0;
 
         impl Drop for S1 {
@@ -626,9 +560,7 @@ mod tests {
     #[test]
     fn self_referential() {
         struct S1;
-        thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell {
-            value: None
-        });
+        thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell::new(None));
 
         impl Drop for S1 {
             fn drop(&mut self) {
@@ -644,12 +576,8 @@ mod tests {
     #[test]
     fn dtors_in_dtors_in_dtors() {
         struct S1(Sender<()>);
-        thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell {
-            value: None
-        });
-        thread_local!(static K2: UnsafeCell<Option<Foo>> = UnsafeCell {
-            value: None
-        });
+        thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell::new(None));
+        thread_local!(static K2: UnsafeCell<Option<Foo>> = UnsafeCell::new(None));
 
         impl Drop for S1 {
             fn drop(&mut self) {
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index 7c8cb5b01c1..f090d3e77dd 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -216,8 +216,7 @@ pub use self::local::{LocalKey, LocalKeyState};
                       consider stabilizing its interface")]
 pub use self::scoped_tls::ScopedKey;
 
-#[doc(hidden)] pub use self::local::__impl as __local;
-#[doc(hidden)] pub use self::scoped_tls::__impl as __scoped;
+#[doc(hidden)] pub use self::local::__KeyInner as __LocalKeyInner;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Builder
diff --git a/src/libstd/thread/scoped_tls.rs b/src/libstd/thread/scoped_tls.rs
index e195c3aaa3f..dda1db9aece 100644
--- a/src/libstd/thread/scoped_tls.rs
+++ b/src/libstd/thread/scoped_tls.rs
@@ -43,13 +43,6 @@
 
 use prelude::v1::*;
 
-// macro hygiene sure would be nice, wouldn't it?
-#[doc(hidden)]
-pub mod __impl {
-    pub use super::imp::KeyInner;
-    pub use sys_common::thread_local::INIT as OS_INIT;
-}
-
 /// Type representing a thread local storage key corresponding to a reference
 /// to the type parameter `T`.
 ///
@@ -60,7 +53,7 @@ pub mod __impl {
 #[unstable(feature = "scoped_tls",
            reason = "scoped TLS has yet to have wide enough use to fully consider \
                      stabilizing its interface")]
-pub struct ScopedKey<T> { #[doc(hidden)] pub inner: __impl::KeyInner<T> }
+pub struct ScopedKey<T> { inner: imp::KeyInner<T> }
 
 /// Declare a new scoped thread local storage key.
 ///
@@ -72,18 +65,6 @@ pub struct ScopedKey<T> { #[doc(hidden)] pub inner: __impl::KeyInner<T> }
 #[allow_internal_unstable]
 macro_rules! scoped_thread_local {
     (static $name:ident: $t:ty) => (
-        __scoped_thread_local_inner!(static $name: $t);
-    );
-    (pub static $name:ident: $t:ty) => (
-        __scoped_thread_local_inner!(pub static $name: $t);
-    );
-}
-
-#[macro_export]
-#[doc(hidden)]
-#[allow_internal_unstable]
-macro_rules! __scoped_thread_local_inner {
-    (static $name:ident: $t:ty) => (
         #[cfg_attr(not(any(windows,
                            target_os = "android",
                            target_os = "ios",
@@ -91,7 +72,7 @@ macro_rules! __scoped_thread_local_inner {
                            target_arch = "aarch64")),
                    thread_local)]
         static $name: ::std::thread::ScopedKey<$t> =
-            __scoped_thread_local_inner!($t);
+            ::std::thread::ScopedKey::new();
     );
     (pub static $name:ident: $t:ty) => (
         #[cfg_attr(not(any(windows,
@@ -101,42 +82,19 @@ macro_rules! __scoped_thread_local_inner {
                            target_arch = "aarch64")),
                    thread_local)]
         pub static $name: ::std::thread::ScopedKey<$t> =
-            __scoped_thread_local_inner!($t);
+            ::std::thread::ScopedKey::new();
     );
-    ($t:ty) => ({
-        use std::thread::ScopedKey as __Key;
-
-        #[cfg(not(any(windows,
-                      target_os = "android",
-                      target_os = "ios",
-                      target_os = "openbsd",
-                      target_arch = "aarch64")))]
-        const _INIT: __Key<$t> = __Key {
-            inner: ::std::thread::__scoped::KeyInner {
-                inner: ::std::cell::UnsafeCell { value: 0 as *mut _ },
-            }
-        };
-
-        #[cfg(any(windows,
-                  target_os = "android",
-                  target_os = "ios",
-                  target_os = "openbsd",
-                  target_arch = "aarch64"))]
-        const _INIT: __Key<$t> = __Key {
-            inner: ::std::thread::__scoped::KeyInner {
-                inner: ::std::thread::__scoped::OS_INIT,
-                marker: ::std::marker::PhantomData::<::std::cell::Cell<$t>>,
-            }
-        };
-
-        _INIT
-    })
 }
 
 #[unstable(feature = "scoped_tls",
            reason = "scoped TLS has yet to have wide enough use to fully consider \
                      stabilizing its interface")]
 impl<T> ScopedKey<T> {
+    #[doc(hidden)]
+    pub const fn new() -> ScopedKey<T> {
+        ScopedKey { inner: imp::KeyInner::new() }
+    }
+
     /// Inserts a value into this scoped thread local storage slot for a
     /// duration of a closure.
     ///
@@ -170,7 +128,7 @@ impl<T> ScopedKey<T> {
         F: FnOnce() -> R,
     {
         struct Reset<'a, T: 'a> {
-            key: &'a __impl::KeyInner<T>,
+            key: &'a imp::KeyInner<T>,
             val: *mut T,
         }
                 impl<'a, T> Drop for Reset<'a, T> {
@@ -231,19 +189,18 @@ impl<T> ScopedKey<T> {
               target_os = "openbsd",
               target_arch = "aarch64")))]
 mod imp {
-    use std::cell::UnsafeCell;
+    use std::cell::Cell;
 
-    #[doc(hidden)]
-    pub struct KeyInner<T> { pub inner: UnsafeCell<*mut T> }
+    pub struct KeyInner<T> { inner: Cell<*mut T> }
 
     unsafe impl<T> ::marker::Sync for KeyInner<T> { }
 
-    #[doc(hidden)]
     impl<T> KeyInner<T> {
-        #[doc(hidden)]
-        pub unsafe fn set(&self, ptr: *mut T) { *self.inner.get() = ptr; }
-        #[doc(hidden)]
-        pub unsafe fn get(&self) -> *mut T { *self.inner.get() }
+        pub const fn new() -> KeyInner<T> {
+            KeyInner { inner: Cell::new(0 as *mut _) }
+        }
+        pub unsafe fn set(&self, ptr: *mut T) { self.inner.set(ptr); }
+        pub unsafe fn get(&self) -> *mut T { self.inner.get() }
     }
 }
 
@@ -253,23 +210,27 @@ mod imp {
           target_os = "openbsd",
           target_arch = "aarch64"))]
 mod imp {
+    use prelude::v1::*;
+
+    use cell::Cell;
     use marker;
-    use std::cell::Cell;
     use sys_common::thread_local::StaticKey as OsStaticKey;
 
-    #[doc(hidden)]
     pub struct KeyInner<T> {
         pub inner: OsStaticKey,
         pub marker: marker::PhantomData<Cell<T>>,
     }
 
-    unsafe impl<T> ::marker::Sync for KeyInner<T> { }
+    unsafe impl<T> marker::Sync for KeyInner<T> { }
 
-    #[doc(hidden)]
     impl<T> KeyInner<T> {
-        #[doc(hidden)]
+        pub const fn new() -> KeyInner<T> {
+            KeyInner {
+                inner: OsStaticKey::new(None),
+                marker: marker::PhantomData
+            }
+        }
         pub unsafe fn set(&self, ptr: *mut T) { self.inner.set(ptr as *mut _) }
-        #[doc(hidden)]
         pub unsafe fn get(&self) -> *mut T { self.inner.get() as *mut _ }
     }
 }