Skip to content

Commit

Permalink
core: Remove the cast module
Browse files Browse the repository at this point in the history
This commit revisits the `cast` module in libcore and libstd, and scrutinizes
all functions inside of it. The result was to remove the `cast` module entirely,
folding all functionality into the `mem` module. Specifically, this is the fate
of each function in the `cast` module.

* transmute - This function was moved to `mem`, but it is now marked as
              #[unstable]. This is due to planned changes to the `transmute`
              function and how it can be invoked (see the #[unstable] comment).
              For more information, see RFC 5 and #12898

* transmute_copy - This function was moved to `mem`, with clarification that is
                   is not an error to invoke it with T/U that are different
                   sizes, but rather that it is strongly discouraged. This
                   function is now #[stable]

* forget - This function was moved to `mem` and marked #[stable]

* bump_box_refcount - This function was removed due to the deprecation of
                      managed boxes as well as its questionable utility.

* transmute_mut - This function was previously deprecated, and removed as part
                  of this commit.

* transmute_mut_unsafe - This function doesn't serve much of a purpose when it
                         can be achieved with an `as` in safe code, so it was
                         removed.

* transmute_lifetime - This function was removed because it is likely a strong
                       indication that code is incorrect in the first place.

* transmute_mut_lifetime - This function was removed for the same reasons as
                           `transmute_lifetime`

* copy_lifetime - This function was moved to `mem`, but it is marked
                  `#[unstable]` now due to the likelihood of being removed in
                  the future if it is found to not be very useful.

* copy_mut_lifetime - This function was also moved to `mem`, but had the same
                      treatment as `copy_lifetime`.

* copy_lifetime_vec - This function was removed because it is not used today,
                      and its existence is not necessary with DST
                      (copy_lifetime will suffice).

In summary, the cast module was stripped down to these functions, and then the
functions were moved to the `mem` module.

    transmute - #[unstable]
    transmute_copy - #[stable]
    forget - #[stable]
    copy_lifetime - #[unstable]
    copy_mut_lifetime - #[unstable]

[breaking-change]
  • Loading branch information
alexcrichton committed May 11, 2014
1 parent adb8b0b commit f94d671
Show file tree
Hide file tree
Showing 137 changed files with 723 additions and 766 deletions.
4 changes: 2 additions & 2 deletions src/doc/guide-unsafe.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ restrictions is undefined behaviour. For example, the following
creates two aliasing `&mut` pointers, and is invalid.

```
use std::cast;
use std::mem;
let mut x: u8 = 1;
let ref_1: &mut u8 = &mut x;
let ref_2: &mut u8 = unsafe { cast::transmute_mut_lifetime(ref_1) };
let ref_2: &mut u8 = unsafe { mem::transmute(&mut *ref_1) };
// oops, ref_1 and ref_2 point to the same piece of data (x) and are
// both usable
Expand Down
57 changes: 22 additions & 35 deletions src/libarena/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@

extern crate collections;

use std::cast::{transmute, transmute_mut_lifetime};
use std::cast;
use std::cell::{Cell, RefCell};
use std::cmp;
use std::intrinsics::{TyDesc, get_tydesc};
Expand Down Expand Up @@ -137,7 +135,7 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
let fill = chunk.fill.get();

while idx < fill {
let tydesc_data: *uint = transmute(buf.offset(idx as int));
let tydesc_data: *uint = mem::transmute(buf.offset(idx as int));
let (tydesc, is_done) = un_bitpack_tydesc_ptr(*tydesc_data);
let (size, align) = ((*tydesc).size, (*tydesc).align);

Expand Down Expand Up @@ -187,28 +185,27 @@ impl Arena {
#[inline]
fn alloc_copy_inner(&mut self, n_bytes: uint, align: uint) -> *u8 {
unsafe {
let this = transmute_mut_lifetime(self);
let start = round_up(this.copy_head.fill.get(), align);
let start = round_up(self.copy_head.fill.get(), align);
let end = start + n_bytes;
if end > self.chunk_size() {
return this.alloc_copy_grow(n_bytes, align);
return self.alloc_copy_grow(n_bytes, align);
}
this.copy_head.fill.set(end);
self.copy_head.fill.set(end);

//debug!("idx = {}, size = {}, align = {}, fill = {}",
// start, n_bytes, align, head.fill.get());

this.copy_head.as_ptr().offset(start as int)
self.copy_head.as_ptr().offset(start as int)
}
}

#[inline]
fn alloc_copy<'a, T>(&'a mut self, op: || -> T) -> &'a T {
unsafe {
let ptr = self.alloc_copy_inner(mem::size_of::<T>(), min_align_of::<T>());
let ptr: *mut T = transmute(ptr);
let ptr = ptr as *mut T;
mem::move_val_init(&mut (*ptr), op());
return transmute(ptr);
return &*ptr;
}
}

Expand All @@ -228,26 +225,16 @@ impl Arena {
fn alloc_noncopy_inner(&mut self, n_bytes: uint, align: uint)
-> (*u8, *u8) {
unsafe {
let start;
let end;
let tydesc_start;
let after_tydesc;

{
let head = transmute_mut_lifetime(&mut self.head);

tydesc_start = head.fill.get();
after_tydesc = head.fill.get() + mem::size_of::<*TyDesc>();
start = round_up(after_tydesc, align);
end = start + n_bytes;
}
let tydesc_start = self.head.fill.get();
let after_tydesc = self.head.fill.get() + mem::size_of::<*TyDesc>();
let start = round_up(after_tydesc, align);
let end = start + n_bytes;

if end > self.head.capacity() {
return self.alloc_noncopy_grow(n_bytes, align);
}

let head = transmute_mut_lifetime(&mut self.head);
head.fill.set(round_up(end, mem::pref_align_of::<*TyDesc>()));
self.head.fill.set(round_up(end, mem::pref_align_of::<*TyDesc>()));

//debug!("idx = {}, size = {}, align = {}, fill = {}",
// start, n_bytes, align, head.fill);
Expand All @@ -263,18 +250,18 @@ impl Arena {
let tydesc = get_tydesc::<T>();
let (ty_ptr, ptr) =
self.alloc_noncopy_inner(mem::size_of::<T>(), min_align_of::<T>());
let ty_ptr: *mut uint = transmute(ty_ptr);
let ptr: *mut T = transmute(ptr);
let ty_ptr = ty_ptr as *mut uint;
let ptr = ptr as *mut T;
// Write in our tydesc along with a bit indicating that it
// has *not* been initialized yet.
*ty_ptr = transmute(tydesc);
*ty_ptr = mem::transmute(tydesc);
// Actually initialize it
mem::move_val_init(&mut(*ptr), op());
// Now that we are done, update the tydesc to indicate that
// the object is there.
*ty_ptr = bitpack_tydesc_ptr(tydesc, true);

return transmute(ptr);
return &*ptr;
}
}

Expand All @@ -283,7 +270,7 @@ impl Arena {
pub fn alloc<'a, T>(&'a self, op: || -> T) -> &'a T {
unsafe {
// FIXME #13933: Remove/justify all `&T` to `&mut T` transmutes
let this: &mut Arena = transmute::<&_, &mut _>(self);
let this: &mut Arena = mem::transmute::<&_, &mut _>(self);
if intrinsics::needs_drop::<T>() {
this.alloc_noncopy(op)
} else {
Expand Down Expand Up @@ -366,7 +353,7 @@ impl<T> TypedArenaChunk<T> {

let mut chunk = unsafe {
let chunk = exchange_malloc(size);
let mut chunk: Box<TypedArenaChunk<T>> = cast::transmute(chunk);
let mut chunk: Box<TypedArenaChunk<T>> = mem::transmute(chunk);
mem::move_val_init(&mut chunk.next, next);
chunk
};
Expand All @@ -387,7 +374,7 @@ impl<T> TypedArenaChunk<T> {

let mut chunk = unsafe {
let chunk = exchange_malloc(size, min_align_of::<TypedArenaChunk<T>>());
let mut chunk: Box<TypedArenaChunk<T>> = cast::transmute(chunk);
let mut chunk: Box<TypedArenaChunk<T>> = mem::transmute(chunk);
mem::move_val_init(&mut chunk.next, next);
chunk
};
Expand Down Expand Up @@ -425,7 +412,7 @@ impl<T> TypedArenaChunk<T> {
fn start(&self) -> *u8 {
let this: *TypedArenaChunk<T> = self;
unsafe {
cast::transmute(round_up(this.offset(1) as uint, min_align_of::<T>()))
mem::transmute(round_up(this.offset(1) as uint, min_align_of::<T>()))
}
}

Expand Down Expand Up @@ -463,12 +450,12 @@ impl<T> TypedArena<T> {
pub fn alloc<'a>(&'a self, object: T) -> &'a T {
unsafe {
// FIXME #13933: Remove/justify all `&T` to `&mut T` transmutes
let this: &mut TypedArena<T> = cast::transmute::<&_, &mut _>(self);
let this: &mut TypedArena<T> = mem::transmute::<&_, &mut _>(self);
if this.ptr == this.end {
this.grow()
}

let ptr: &'a mut T = cast::transmute(this.ptr);
let ptr: &'a mut T = mem::transmute(this.ptr);
mem::move_val_init(ptr, object);
this.ptr = this.ptr.offset(1);
let ptr: &'a T = ptr;
Expand Down
11 changes: 5 additions & 6 deletions src/libcollections/dlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,9 @@
// Backlinks over DList::prev are raw pointers that form a full chain in
// the reverse direction.

use std::cast;
use std::iter::Rev;
use std::iter;
use std::mem::{replace, swap};
use std::mem;
use std::ptr;

use deque::Deque;
Expand Down Expand Up @@ -93,13 +92,13 @@ impl<T> Rawlink<T> {
if self.p.is_null() {
None
} else {
Some(unsafe { cast::transmute(self.p) })
Some(unsafe { mem::transmute(self.p) })
}
}

/// Return the `Rawlink` and replace with `Rawlink::none()`
fn take(&mut self) -> Rawlink<T> {
replace(self, Rawlink::none())
mem::replace(self, Rawlink::none())
}
}

Expand Down Expand Up @@ -159,7 +158,7 @@ impl<T> DList<T> {
Some(ref mut head) => {
new_head.prev = Rawlink::none();
head.prev = Rawlink::some(new_head);
swap(head, &mut new_head);
mem::swap(head, &mut new_head);
head.next = Some(new_head);
}
}
Expand Down Expand Up @@ -317,7 +316,7 @@ impl<T> DList<T> {
/// O(1)
#[inline]
pub fn prepend(&mut self, mut other: DList<T>) {
swap(self, &mut other);
mem::swap(self, &mut other);
self.append(other);
}

Expand Down
4 changes: 2 additions & 2 deletions src/libcollections/enum_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ impl<E:CLike> Iterator<E> for Items<E> {
#[cfg(test)]
mod test {

use std::cast;
use std::mem;

use enum_set::{EnumSet, CLike};

Expand All @@ -153,7 +153,7 @@ mod test {
}

fn from_uint(v: uint) -> Foo {
unsafe { cast::transmute(v) }
unsafe { mem::transmute(v) }
}
}

Expand Down
9 changes: 4 additions & 5 deletions src/libcollections/lru_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
//! assert!(cache.get(&2).is_none());
//! ```

use std::cast;
use std::container::Container;
use std::hash::Hash;
use std::fmt;
Expand Down Expand Up @@ -93,7 +92,7 @@ impl<K: Hash + TotalEq, V> LruCache<K, V> {
let cache = LruCache {
map: HashMap::new(),
max_size: capacity,
head: unsafe{ cast::transmute(box mem::uninit::<LruEntry<K, V>>()) },
head: unsafe{ mem::transmute(box mem::uninit::<LruEntry<K, V>>()) },
};
unsafe {
(*cache.head).next = cache.head;
Expand Down Expand Up @@ -241,11 +240,11 @@ impl<K: Hash + TotalEq, V> Mutable for LruCache<K, V> {
impl<K, V> Drop for LruCache<K, V> {
fn drop(&mut self) {
unsafe {
let node: Box<LruEntry<K, V>> = cast::transmute(self.head);
let node: Box<LruEntry<K, V>> = mem::transmute(self.head);
// Prevent compiler from trying to drop the un-initialized field in the sigil node.
let box LruEntry { key: k, value: v, .. } = node;
cast::forget(k);
cast::forget(v);
mem::forget(k);
mem::forget(v);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
//! value. `Box<Any>` adds the `move` method, which will unwrap a `Box<T>` from the object. See
//! the extension traits (`*Ext`) for the full details.

use cast::{transmute, transmute_copy};
use mem::{transmute, transmute_copy};
use option::{Option, Some, None};
use owned::Box;
use raw::TraitObject;
Expand Down
Loading

5 comments on commit f94d671

@bors
Copy link
Contributor

@bors bors commented on f94d671 May 11, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from brson
at alexcrichton@f94d671

@bors
Copy link
Contributor

@bors bors commented on f94d671 May 11, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging alexcrichton/rust/cast-module = f94d671 into auto

@bors
Copy link
Contributor

@bors bors commented on f94d671 May 11, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alexcrichton/rust/cast-module = f94d671 merged ok, testing candidate = fb569fd

@bors
Copy link
Contributor

@bors bors commented on f94d671 May 11, 2014

@bors
Copy link
Contributor

@bors bors commented on f94d671 May 11, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = fb569fd

Please sign in to comment.