about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/hash/mod.rs23
-rw-r--r--src/libcore/lib.rs33
-rw-r--r--src/libcore/mem.rs80
-rw-r--r--src/libcore/ptr.rs2
-rw-r--r--src/libcore/str/pattern.rs2
5 files changed, 105 insertions, 35 deletions
diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs
index 75b7208d66b..e35f380d06f 100644
--- a/src/libcore/hash/mod.rs
+++ b/src/libcore/hash/mod.rs
@@ -91,8 +91,7 @@ pub trait Hash {
     fn hash<H: Hasher>(&self, state: &mut H);
 
     /// Feeds a slice of this type into the state provided.
-    #[unstable(feature = "hash_slice",
-               reason = "module was recently redesigned")]
+    #[stable(feature = "hash_slice", since = "1.3.0")]
     fn hash_slice<H: Hasher>(data: &[Self], state: &mut H) where Self: Sized {
         for piece in data {
             piece.hash(state);
@@ -113,29 +112,29 @@ pub trait Hasher {
 
     /// Write a single `u8` into this hasher
     #[inline]
-    #[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
+    #[stable(feature = "hasher_write", since = "1.3.0")]
     fn write_u8(&mut self, i: u8) { self.write(&[i]) }
     /// Write a single `u16` into this hasher.
     #[inline]
-    #[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
+    #[stable(feature = "hasher_write", since = "1.3.0")]
     fn write_u16(&mut self, i: u16) {
         self.write(&unsafe { mem::transmute::<_, [u8; 2]>(i) })
     }
     /// Write a single `u32` into this hasher.
     #[inline]
-    #[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
+    #[stable(feature = "hasher_write", since = "1.3.0")]
     fn write_u32(&mut self, i: u32) {
         self.write(&unsafe { mem::transmute::<_, [u8; 4]>(i) })
     }
     /// Write a single `u64` into this hasher.
     #[inline]
-    #[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
+    #[stable(feature = "hasher_write", since = "1.3.0")]
     fn write_u64(&mut self, i: u64) {
         self.write(&unsafe { mem::transmute::<_, [u8; 8]>(i) })
     }
     /// Write a single `usize` into this hasher.
     #[inline]
-    #[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
+    #[stable(feature = "hasher_write", since = "1.3.0")]
     fn write_usize(&mut self, i: usize) {
         if cfg!(target_pointer_width = "32") {
             self.write_u32(i as u32)
@@ -146,23 +145,23 @@ pub trait Hasher {
 
     /// Write a single `i8` into this hasher.
     #[inline]
-    #[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
+    #[stable(feature = "hasher_write", since = "1.3.0")]
     fn write_i8(&mut self, i: i8) { self.write_u8(i as u8) }
     /// Write a single `i16` into this hasher.
     #[inline]
-    #[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
+    #[stable(feature = "hasher_write", since = "1.3.0")]
     fn write_i16(&mut self, i: i16) { self.write_u16(i as u16) }
     /// Write a single `i32` into this hasher.
     #[inline]
-    #[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
+    #[stable(feature = "hasher_write", since = "1.3.0")]
     fn write_i32(&mut self, i: i32) { self.write_u32(i as u32) }
     /// Write a single `i64` into this hasher.
     #[inline]
-    #[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
+    #[stable(feature = "hasher_write", since = "1.3.0")]
     fn write_i64(&mut self, i: i64) { self.write_u64(i as u64) }
     /// Write a single `isize` into this hasher.
     #[inline]
-    #[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
+    #[stable(feature = "hasher_write", since = "1.3.0")]
     fn write_isize(&mut self, i: isize) { self.write_usize(i as usize) }
 }
 
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index ef2a33c37dd..238644c4a26 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -65,6 +65,7 @@
 #![allow(raw_pointer_derive)]
 #![deny(missing_docs)]
 
+#![feature(associated_type_defaults)]
 #![feature(intrinsics)]
 #![feature(lang_items)]
 #![feature(on_unimplemented)]
@@ -157,21 +158,23 @@ pub mod fmt;
 // note: does not need to be public
 mod tuple;
 
+// A curious inner-module that's not exported that contains the bindings of core
+// so that compiler-expanded references to `core::$foo` can be resolved within
+// core itself.
+//
+// Note that no crate-defined macros require this module due to the existence of
+// the `$crate` meta variable, only those expansions defined in the compiler
+// require this. This is because the compiler doesn't currently know that it's
+// compiling the core library when it's compiling this library, so it expands
+// all references to `::core::$foo`
 #[doc(hidden)]
 mod core {
-    pub use intrinsics;
-    pub use panicking;
-    pub use fmt;
-    pub use clone;
-    pub use cmp;
-    pub use hash;
-    pub use marker;
-    pub use option;
-    pub use iter;
-}
-
-#[doc(hidden)]
-mod std {
-    // range syntax
-    pub use ops;
+    pub use intrinsics;     // derive(PartialOrd)
+    pub use fmt;            // format_args!
+    pub use clone;          // derive(Clone)
+    pub use cmp;            // derive(Ord)
+    pub use hash;           // derive(Hash)
+    pub use marker;         // derive(Copy)
+    pub use option;         // iterator protocol
+    pub use iter;           // iterator protocol
 }
diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs
index 271d83201b1..3b321d43b3d 100644
--- a/src/libcore/mem.rs
+++ b/src/libcore/mem.rs
@@ -253,21 +253,89 @@ pub unsafe fn dropped<T>() -> T {
     dropped_impl()
 }
 
-/// Creates an uninitialized value.
+/// Bypasses Rust's normal memory-initialization checks by pretending to
+/// produce a value of type T, while doing nothing at all.
 ///
-/// Care must be taken when using this function, if the type `T` has a destructor and the value
-/// falls out of scope (due to unwinding or returning) before being initialized, then the
-/// destructor will run on uninitialized data, likely leading to crashes.
+/// **This is incredibly dangerous, and should not be done lightly. Deeply
+/// consider initializing your memory with a default value instead.**
 ///
-/// This is useful for FFI functions sometimes, but should generally be avoided.
+/// This is useful for FFI functions and initializing arrays sometimes,
+/// but should generally be avoided.
+///
+/// # Undefined Behaviour
+///
+/// It is Undefined Behaviour to read uninitialized memory. Even just an
+/// uninitialized boolean. For instance, if you branch on the value of such
+/// a boolean your program may take one, both, or neither of the branches.
+///
+/// Note that this often also includes *writing* to the uninitialized value.
+/// Rust believes the value is initialized, and will therefore try to Drop
+/// the uninitialized value and its fields if you try to overwrite the memory
+/// in a normal manner. The only way to safely initialize an arbitrary
+/// uninitialized value is with one of the `ptr` functions: `write`, `copy`, or
+/// `copy_nonoverlapping`. This isn't necessary if `T` is a primitive
+/// or otherwise only contains types that don't implement Drop.
+///
+/// If this value *does* need some kind of Drop, it must be initialized before
+/// it goes out of scope (and therefore would be dropped). Note that this
+/// includes a `panic` occurring and unwinding the stack suddenly.
 ///
 /// # Examples
 ///
+/// Here's how to safely initialize an array of `Vec`s.
+///
 /// ```
 /// use std::mem;
+/// use std::ptr;
 ///
-/// let x: i32 = unsafe { mem::uninitialized() };
+/// // Only declare the array. This safely leaves it
+/// // uninitialized in a way that Rust will track for us.
+/// // However we can't initialize it element-by-element
+/// // safely, and we can't use the `[value; 1000]`
+/// // constructor because it only works with `Copy` data.
+/// let mut data: [Vec<u32>; 1000];
+///
+/// unsafe {
+///     // So we need to do this to initialize it.
+///     data = mem::uninitialized();
+///
+///     // DANGER ZONE: if anything panics or otherwise
+///     // incorrectly reads the array here, we will have
+///     // Undefined Behaviour.
+///
+///     // It's ok to mutably iterate the data, since this
+///     // doesn't involve reading it at all.
+///     // (ptr and len are statically known for arrays)
+///     for elem in &mut data[..] {
+///         // *elem = Vec::new() would try to drop the
+///         // uninitialized memory at `elem` -- bad!
+///         //
+///         // Vec::new doesn't allocate or do really
+///         // anything. It's only safe to call here
+///         // because we know it won't panic.
+///         ptr::write(elem, Vec::new());
+///     }
+///
+///     // SAFE ZONE: everything is initialized.
+/// }
+///
+/// println!("{:?}", &data[0]);
 /// ```
+///
+/// Hopefully this example emphasizes to you exactly how delicate
+/// and dangerous doing this is. Note that the `vec!` macro
+/// *does* let you initialize every element with a value that
+/// is only `Clone`, so the following is equivalent and vastly
+/// less dangerous, as long as you can live with an extra heap
+/// allocation:
+///
+/// ```
+/// let data: Vec<Vec<u32>> = vec![Vec::new(); 1000];
+/// println!("{:?}", &data[0]);
+/// ```
+///
+/// For large arrays this is probably advisable
+/// anyway to avoid blowing the stack.
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub unsafe fn uninitialized<T>() -> T {
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index 6fed89547d4..116c1dfaa3e 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -20,7 +20,7 @@ use mem;
 use clone::Clone;
 use intrinsics;
 use ops::Deref;
-use core::fmt;
+use fmt;
 use option::Option::{self, Some, None};
 use marker::{PhantomData, Send, Sized, Sync};
 use nonzero::NonZero;
diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs
index 707f7fcf2ab..2b3fc39fc8b 100644
--- a/src/libcore/str/pattern.rs
+++ b/src/libcore/str/pattern.rs
@@ -17,7 +17,7 @@
             reason = "API not fully fleshed out and ready to be stabilized")]
 
 use prelude::*;
-use core::cmp;
+use cmp;
 use usize;
 
 // Pattern