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/io/lazy.rs38
-rw-r--r--src/libstd/io/stdio.rs20
-rw-r--r--src/libstd/lib.rs3
-rw-r--r--src/libstd/sys/cloudabi/condvar.rs8
-rw-r--r--src/libstd/sys/cloudabi/rwlock.rs8
5 files changed, 42 insertions, 35 deletions
diff --git a/src/libstd/io/lazy.rs b/src/libstd/io/lazy.rs
index 4fb367fb6ba..24965ff6931 100644
--- a/src/libstd/io/lazy.rs
+++ b/src/libstd/io/lazy.rs
@@ -18,7 +18,6 @@ pub struct Lazy<T> {
     // We never call `lock.init()`, so it is UB to attempt to acquire this mutex reentrantly!
     lock: Mutex,
     ptr: Cell<*mut Arc<T>>,
-    init: fn() -> Arc<T>,
 }
 
 #[inline]
@@ -26,33 +25,32 @@ const fn done<T>() -> *mut Arc<T> { 1_usize as *mut _ }
 
 unsafe impl<T> Sync for Lazy<T> {}
 
-impl<T: Send + Sync + 'static> Lazy<T> {
-    /// Safety: `init` must not call `get` on the variable that is being
-    /// initialized.
-    pub const unsafe fn new(init: fn() -> Arc<T>) -> Lazy<T> {
+impl<T> Lazy<T> {
+    pub const fn new() -> Lazy<T> {
         Lazy {
             lock: Mutex::new(),
             ptr: Cell::new(ptr::null_mut()),
-            init,
         }
     }
+}
 
-    pub fn get(&'static self) -> Option<Arc<T>> {
-        unsafe {
-            let _guard = self.lock.lock();
-            let ptr = self.ptr.get();
-            if ptr.is_null() {
-                Some(self.init())
-            } else if ptr == done() {
-                None
-            } else {
-                Some((*ptr).clone())
-            }
+impl<T: Send + Sync + 'static> Lazy<T> {
+    /// Safety: `init` must not call `get` on the variable that is being
+    /// initialized.
+    pub unsafe fn get(&'static self, init: fn() -> Arc<T>) -> Option<Arc<T>> {
+        let _guard = self.lock.lock();
+        let ptr = self.ptr.get();
+        if ptr.is_null() {
+            Some(self.init(init))
+        } else if ptr == done() {
+            None
+        } else {
+            Some((*ptr).clone())
         }
     }
 
     // Must only be called with `lock` held
-    unsafe fn init(&'static self) -> Arc<T> {
+    unsafe fn init(&'static self, init: fn() -> Arc<T>) -> Arc<T> {
         // If we successfully register an at exit handler, then we cache the
         // `Arc` allocation in our own internal box (it will get deallocated by
         // the at exit handler). Otherwise we just return the freshly allocated
@@ -66,8 +64,8 @@ impl<T: Send + Sync + 'static> Lazy<T> {
         });
         // This could reentrantly call `init` again, which is a problem
         // because our `lock` allows reentrancy!
-        // That's why `new` is unsafe and requires the caller to ensure no reentrancy happens.
-        let ret = (self.init)();
+        // That's why `get` is unsafe and requires the caller to ensure no reentrancy happens.
+        let ret = init();
         if registered.is_ok() {
             self.ptr.set(Box::into_raw(Box::new(ret.clone())));
         }
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index 1f256f518c7..a413432cdaa 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -197,9 +197,11 @@ pub struct StdinLock<'a> {
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn stdin() -> Stdin {
-    static INSTANCE: Lazy<Mutex<BufReader<Maybe<StdinRaw>>>> = unsafe { Lazy::new(stdin_init) };
+    static INSTANCE: Lazy<Mutex<BufReader<Maybe<StdinRaw>>>> = Lazy::new();
     return Stdin {
-        inner: INSTANCE.get().expect("cannot access stdin during shutdown"),
+        inner: unsafe {
+            INSTANCE.get(stdin_init).expect("cannot access stdin during shutdown")
+        },
     };
 
     fn stdin_init() -> Arc<Mutex<BufReader<Maybe<StdinRaw>>>> {
@@ -396,10 +398,11 @@ pub struct StdoutLock<'a> {
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn stdout() -> Stdout {
-    static INSTANCE: Lazy<ReentrantMutex<RefCell<LineWriter<Maybe<StdoutRaw>>>>>
-        = unsafe { Lazy::new(stdout_init) };
+    static INSTANCE: Lazy<ReentrantMutex<RefCell<LineWriter<Maybe<StdoutRaw>>>>> = Lazy::new();
     return Stdout {
-        inner: INSTANCE.get().expect("cannot access stdout during shutdown"),
+        inner: unsafe {
+            INSTANCE.get(stdout_init).expect("cannot access stdout during shutdown")
+        },
     };
 
     fn stdout_init() -> Arc<ReentrantMutex<RefCell<LineWriter<Maybe<StdoutRaw>>>>> {
@@ -533,10 +536,11 @@ pub struct StderrLock<'a> {
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn stderr() -> Stderr {
-    static INSTANCE: Lazy<ReentrantMutex<RefCell<Maybe<StderrRaw>>>> =
-        unsafe { Lazy::new(stderr_init) };
+    static INSTANCE: Lazy<ReentrantMutex<RefCell<Maybe<StderrRaw>>>> = Lazy::new();
     return Stderr {
-        inner: INSTANCE.get().expect("cannot access stderr during shutdown"),
+        inner: unsafe {
+            INSTANCE.get(stderr_init).expect("cannot access stderr during shutdown")
+        },
     };
 
     fn stderr_init() -> Arc<ReentrantMutex<RefCell<Maybe<StderrRaw>>>> {
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 310475d31fd..e7195b3e21e 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -250,7 +250,8 @@
 #![feature(cfg_target_vendor)]
 #![feature(char_error_internals)]
 #![feature(compiler_builtins_lib)]
-#![feature(const_fn)]
+#![cfg_attr(stage0, feature(const_fn))]
+#![cfg_attr(not(stage0), feature(min_const_fn))]
 #![feature(const_int_ops)]
 #![feature(const_ip)]
 #![feature(core_intrinsics)]
diff --git a/src/libstd/sys/cloudabi/condvar.rs b/src/libstd/sys/cloudabi/condvar.rs
index c05c837ade2..ccf848a9be4 100644
--- a/src/libstd/sys/cloudabi/condvar.rs
+++ b/src/libstd/sys/cloudabi/condvar.rs
@@ -28,11 +28,13 @@ pub struct Condvar {
 unsafe impl Send for Condvar {}
 unsafe impl Sync for Condvar {}
 
+const NEW: Condvar = Condvar {
+    condvar: UnsafeCell::new(AtomicU32::new(abi::CONDVAR_HAS_NO_WAITERS.0)),
+};
+
 impl Condvar {
     pub const fn new() -> Condvar {
-        Condvar {
-            condvar: UnsafeCell::new(AtomicU32::new(abi::CONDVAR_HAS_NO_WAITERS.0)),
-        }
+        NEW
     }
 
     pub unsafe fn init(&mut self) {}
diff --git a/src/libstd/sys/cloudabi/rwlock.rs b/src/libstd/sys/cloudabi/rwlock.rs
index 8539aec5e2c..dc8624ec8a1 100644
--- a/src/libstd/sys/cloudabi/rwlock.rs
+++ b/src/libstd/sys/cloudabi/rwlock.rs
@@ -32,11 +32,13 @@ pub unsafe fn raw(r: &RWLock) -> *mut AtomicU32 {
 unsafe impl Send for RWLock {}
 unsafe impl Sync for RWLock {}
 
+const NEW: RWLock = RWLock {
+    lock: UnsafeCell::new(AtomicU32::new(abi::LOCK_UNLOCKED.0)),
+};
+
 impl RWLock {
     pub const fn new() -> RWLock {
-        RWLock {
-            lock: UnsafeCell::new(AtomicU32::new(abi::LOCK_UNLOCKED.0)),
-        }
+        NEW
     }
 
     pub unsafe fn try_read(&self) -> bool {