(index<- )        ./libstd/cast.rs

    git branch:    * master           c7553ea auto merge of #13609 : richo/rust/str-type-vim, r=alexcrichton
    modified:    Sat Apr 19 11:22:39 2014
   1  // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
   2  // file at the top-level directory of this distribution and at
   3  // http://rust-lang.org/COPYRIGHT.
   4  //
   5  // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
   6  // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
   7  // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
   8  // option. This file may not be copied, modified, or distributed
   9  // except according to those terms.
  10  
  11  //! Unsafe casting functions
  12  
  13  use mem;
  14  use intrinsics;
  15  use ptr::copy_nonoverlapping_memory;
  16  
  17  /// Casts the value at `src` to U. The two types must have the same length.
  18  #[inline]
  19  pub unsafe fn transmute_copy<T, U>(src&T) -> U {
  20      let mut destU = mem::uninit();
  21      let dest_ptr*mut u8 = transmute(&mut dest);
  22      let src_ptr*u8 = transmute(src);
  23      copy_nonoverlapping_memory(dest_ptr, src_ptr, mem::size_of::<U>());
  24      dest
  25  }
  26  
  27  /**
  28   * Move a thing into the void
  29   *
  30   * The forget function will take ownership of the provided value but neglect
  31   * to run any required cleanup or memory-management operations on it. This
  32   * can be used for various acts of magick.
  33   */
  34  #[inline]
  35  pub unsafe fn forget<T>(thingT) { intrinsics::forget(thing); }
  36  
  37  /**
  38   * Force-increment the reference count on a shared box. If used
  39   * carelessly, this can leak the box.
  40   */
  41  #[inline]
  42  pub unsafe fn bump_box_refcount<T>(t@T) { forget(t); }
  43  
  44  /**
  45   * Transform a value of one type into a value of another type.
  46   * Both types must have the same size and alignment.
  47   *
  48   * # Example
  49   *
  50   * ```rust
  51   * use std::cast;
  52   *
  53   * let v: &[u8] = unsafe { cast::transmute("L") };
  54   * assert!(v == [76u8]);
  55   * ```
  56   */
  57  #[inline]
  58  pub unsafe fn transmute<L, G>(thingL) -> G {
  59      intrinsics::transmute(thing)
  60  }
  61  
  62  /// Coerce an immutable reference to be mutable.
  63  #[inline]
  64  pub unsafe fn transmute_mut<'a,T>(ptr&'a T) -> &'a mut T { transmute(ptr) }
  65  
  66  /// Coerce a reference to have an arbitrary associated lifetime.
  67  #[inline]
  68  pub unsafe fn transmute_lifetime<'a,'b,T>(ptr&'a T) -> &'b T {
  69      transmute(ptr)
  70  }
  71  
  72  /// Coerce an immutable reference to be mutable.
  73  #[inline]
  74  pub unsafe fn transmute_mut_unsafe<T>(ptr*T) -> *mut T {
  75      transmute(ptr)
  76  }
  77  
  78  /// Coerce a mutable reference to have an arbitrary associated lifetime.
  79  #[inline]
  80  pub unsafe fn transmute_mut_lifetime<'a,'b,T>(ptr&'a mut T) -> &'b mut T {
  81      transmute(ptr)
  82  }
  83  
  84  /// Transforms lifetime of the second pointer to match the first.
  85  #[inline]
  86  pub unsafe fn copy_lifetime<'a,S,T>(_ptr&'a S, ptr&T) -> &'a T {
  87      transmute_lifetime(ptr)
  88  }
  89  
  90  /// Transforms lifetime of the second pointer to match the first.
  91  #[inline]
  92  pub unsafe fn copy_mut_lifetime<'a,S,T>(_ptr&'a mut S, ptr&mut T) -> &'a mut T {
  93      transmute_mut_lifetime(ptr)
  94  }
  95  
  96  /// Transforms lifetime of the second pointer to match the first.
  97  #[inline]
  98  pub unsafe fn copy_lifetime_vec<'a,S,T>(_ptr&'a [S], ptr&T) -> &'a T {
  99      transmute_lifetime(ptr)
 100  }
 101  
 102  
 103  /****************************************************************************
 104   * Tests
 105   ****************************************************************************/
 106  
 107  #[cfg(test)]
 108  mod tests {
 109      use cast::{bump_box_refcount, transmute};
 110      use raw;
 111      use str::StrSlice;
 112  
 113      #[test]
 114      fn test_transmute_copy() {
 115          assert_eq!(1u, unsafe { ::cast::transmute_copy(&1) });
 116      }
 117  
 118      #[test]
 119      fn test_bump_managed_refcount() {
 120          unsafe {
 121              let managed = @"box box box".to_owned();      // refcount 1
 122              bump_box_refcount(managed);     // refcount 2
 123              let ptr: *int = transmute(managed); // refcount 2
 124              let _box1: @~str = ::cast::transmute_copy(&ptr);
 125              let _box2: @~str = ::cast::transmute_copy(&ptr);
 126              assert!(*_box1 == "box box box".to_owned());
 127              assert!(*_box2 == "box box box".to_owned());
 128              // Will destroy _box1 and _box2. Without the bump, this would
 129              // use-after-free. With too many bumps, it would leak.
 130          }
 131      }
 132  
 133      #[test]
 134      fn test_transmute() {
 135          unsafe {
 136              let x = @100u8;
 137              let x: *raw::Box<u8> = transmute(x);
 138              assert!((*x).data == 100);
 139              let _x: @int = transmute(x);
 140          }
 141      }
 142  
 143      #[test]
 144      fn test_transmute2() {
 145          unsafe {
 146              assert_eq!(~[76u8], transmute("L".to_owned()));
 147          }
 148      }
 149  }


libstd/cast.rs:57:10-57:10 -fn- definition:
pub unsafe fn transmute<L, G>(thing: L) -> G {
    intrinsics::transmute(thing)
}
references:- 193
libstd/fmt/mod.rs:
libstd/repr.rs:
libstd/unstable/dynamic_lib.rs:
libstd/rt/task.rs:
libstd/rt/thread.rs:
libstd/rt/local_heap.rs:
libstd/rt/local_ptr.rs:
libstd/rt/unwind.rs:
libstd/rt/backtrace.rs:
libstd/rt/args.rs:
libstd/rt/at_exit_imp.rs:
libstd/num/f32.rs:
libstd/num/f64.rs:
libstd/char.rs:
libstd/slice.rs:
libstd/vec.rs:
libstd/str.rs:
libstd/strbuf.rs:
libstd/ascii.rs:
libstd/ptr.rs:
libstd/rc.rs:
libstd/any.rs:
libstd/comm/select.rs:
libstd/comm/sync.rs:
libstd/local_data.rs:
libstd/sync/arc.rs:
libstd/sync/atomics.rs:
libstd/sync/deque.rs:
libstd/sync/mpsc_queue.rs:
libstd/sync/spsc_queue.rs:
libstd/c_str.rs:
libstd/c_vec.rs:
libstd/io/mod.rs:
libstd/io/extensions.rs:
libstd/path/windows.rs:
libstd/ptr.rs:


libstd/cast.rs:73:10-73:10 -fn- definition:
pub unsafe fn transmute_mut_unsafe<T>(ptr: *T) -> *mut T {
    transmute(ptr)
}
references:- 2
libstd/ty.rs:
65:     #[inline]
66:     pub unsafe fn get(&self) -> *mut T { cast::transmute_mut_unsafe(&self.value) }
libstd/c_str.rs:
156:         if self.buf.is_null() { fail!("CString is null!"); }
157:         f(unsafe { cast::transmute_mut_unsafe(self.buf) })
158:     }


libstd/cast.rs:18:10-18:10 -fn- definition:
pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
    let mut dest: U = mem::uninit();
    let dest_ptr: *mut u8 = transmute(&mut dest);
references:- 8
libstd/repr.rs:
159:                 var_stk: vec!(),
160:                 writer: ::cast::transmute_copy(&self.writer),
161:                 last_err: None,
libstd/raw.rs:
75:     #[inline]
76:     fn repr(&self) -> T { unsafe { cast::transmute_copy(self) } }
77: }
libstd/rt/rtio.rs:
141:         unsafe {
142:             cast::transmute_copy(&self.factory)
143:         }
libstd/any.rs:
108:                 // Get the raw representation of the trait object
109:                 let to: TraitObject = transmute_copy(&self);
--
132:                 // Get the raw representation of the trait object
133:                 let to: TraitObject = transmute_copy(&self);
libstd/slice.rs:
1669:             let len = self.len();
1670:             let self2: &'a mut [T] = cast::transmute_copy(&self);
1671:             (self.mut_slice(0, mid), self2.mut_slice(mid, len))


libstd/cast.rs:67:10-67:10 -fn- definition:
pub unsafe fn transmute_lifetime<'a,'b,T>(ptr: &'a T) -> &'b T {
    transmute(ptr)
}
references:- 2
98: pub unsafe fn copy_lifetime_vec<'a,S,T>(_ptr: &'a [S], ptr: &T) -> &'a T {
99:     transmute_lifetime(ptr)
100: }


libstd/cast.rs:63:10-63:10 -fn- definition:
pub unsafe fn transmute_mut<'a,T>(ptr: &'a T) -> &'a mut T { transmute(ptr) }
/// Coerce a reference to have an arbitrary associated lifetime.
pub unsafe fn transmute_lifetime<'a,'b,T>(ptr: &'a T) -> &'b T {
references:- 10
libstd/slice.rs:
1719:             let s: &mut Slice<T> = transmute(self);
1720:             Some(cast::transmute_mut(&*raw::shift_ptr(s)))
1721:         }
--
1727:             let s: &mut Slice<T> = transmute(self);
1728:             Some(cast::transmute_mut(&*raw::pop_ptr(s)))
1729:         }
libstd/comm/mod.rs:
908:             unsafe {
909:                 mem::swap(&mut cast::transmute_mut(self).inner,
910:                           &mut new_port.inner);
--
932:             unsafe {
933:                 mem::swap(&mut cast::transmute_mut(self).inner,
934:                           &mut new_port.inner);
libstd/local_data.rs:
202:             // there is no need to be upset!
203:             Some(x) => { f(Some(unsafe { cast::transmute_mut(x) })) }
204:         }
libstd/comm/mod.rs:
567:             let mut tmp = Sender::new(Stream(new_inner));
568:             mem::swap(&mut cast::transmute_mut(self).inner, &mut tmp.inner);
569:         }


libstd/cast.rs:34:10-34:10 -fn- definition:
pub unsafe fn forget<T>(thing: T) { intrinsics::forget(thing); }
/**
 * Force-increment the reference count on a shared box. If used
references:- 8
42: pub unsafe fn bump_box_refcount<T>(t: @T) { forget(t); }
libstd/mem.rs:
242:         // because it's no longer relevant.
243:         cast::forget(t);
244:     }
libstd/slice.rs:
1230:                                                 1);
1231:                 cast::forget(tmp);
1232:             }
libstd/vec.rs:
639:             let ptr = self.ptr as *mut c_void;
640:             forget(self);
641:             MoveItems { allocation: ptr, iter: iter }
libstd/ptr.rs:
258:     // because it's no longer relevant.
259:     cast::forget(tmp);
260: }
libstd/sync/deque.rs:
295:         } else {
296:             cast::forget(data); // someone else stole this value
297:             Abort
--
374:         ptr::copy_nonoverlapping_memory(ptr as *mut T, &t as *T, 1);
375:         cast::forget(t);
376:     }