diff options
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/hash/mod.rs | 23 | ||||
| -rw-r--r-- | src/libcore/lib.rs | 33 | ||||
| -rw-r--r-- | src/libcore/mem.rs | 80 | ||||
| -rw-r--r-- | src/libcore/ptr.rs | 2 | ||||
| -rw-r--r-- | src/libcore/str/pattern.rs | 2 |
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 |
