(index<- )        ./libstd/mem.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-2014 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  //! Basic functions for dealing with memory
  12  //!
  13  //! This module contains functions for querying the size and alignment of
  14  //! types, initializing and manipulating memory.
  15  
  16  #![allow(missing_doc)] // FIXME
  17  
  18  use cast;
  19  use ptr;
  20  use intrinsics;
  21  use intrinsics::{bswap16, bswap32, bswap64};
  22  
  23  /// Returns the size of a type in bytes.
  24  #[inline]
  25  pub fn size_of<T>() -> uint {
  26      unsafe { intrinsics::size_of::<T>() }
  27  }
  28  
  29  /// Returns the size of the type that `_val` points to in bytes.
  30  #[inline]
  31  pub fn size_of_val<T>(_val&T) -> uint {
  32      size_of::<T>()
  33  }
  34  
  35  /// Returns the size of a type in bytes, or 1 if the actual size is zero.
  36  ///
  37  /// Useful for building structures containing variable-length arrays.
  38  #[inline]
  39  pub fn nonzero_size_of<T>() -> uint {
  40      let s = size_of::<T>();
  41      if s == 0 { 1 } else { s }
  42  }
  43  
  44  /// Returns the size in bytes of the type of the value that `_val` points to.
  45  #[inline]
  46  pub fn nonzero_size_of_val<T>(_val&T) -> uint {
  47      nonzero_size_of::<T>()
  48  }
  49  
  50  /// Returns the ABI-required minimum alignment of a type
  51  ///
  52  /// This is the alignment used for struct fields. It may be smaller
  53  /// than the preferred alignment.
  54  #[inline]
  55  pub fn min_align_of<T>() -> uint {
  56      unsafe { intrinsics::min_align_of::<T>() }
  57  }
  58  
  59  /// Returns the ABI-required minimum alignment of the type of the value that
  60  /// `_val` points to
  61  #[inline]
  62  pub fn min_align_of_val<T>(_val&T) -> uint {
  63      min_align_of::<T>()
  64  }
  65  
  66  /// Returns the preferred alignment of a type
  67  #[inline]
  68  pub fn pref_align_of<T>() -> uint {
  69      unsafe { intrinsics::pref_align_of::<T>() }
  70  }
  71  
  72  /// Returns the preferred alignment of the type of the value that
  73  /// `_val` points to
  74  #[inline]
  75  pub fn pref_align_of_val<T>(_val&T) -> uint {
  76      pref_align_of::<T>()
  77  }
  78  
  79  /// Create a value initialized to zero.
  80  ///
  81  /// `init` is unsafe because it returns a zeroed-out datum,
  82  /// which is unsafe unless T is Copy.
  83  #[inline]
  84  pub unsafe fn init<T>() -> T {
  85      intrinsics::init()
  86  }
  87  
  88  /// Create an uninitialized value.
  89  #[inline]
  90  pub unsafe fn uninit<T>() -> T {
  91      intrinsics::uninit()
  92  }
  93  
  94  /// Move a value to an uninitialized memory location.
  95  ///
  96  /// Drop glue is not run on the destination.
  97  #[inline]
  98  pub unsafe fn move_val_init<T>(dst&mut T, srcT) {
  99      intrinsics::move_val_init(dst, src)
 100  }
 101  
 102  /// Convert an u16 to little endian from the target's endianness.
 103  ///
 104  /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
 105  #[cfg(target_endian = "little")] #[inline] pub fn to_le16(x: u16) -> u16 { x }
 106  
 107  /// Convert an u16 to little endian from the target's endianness.
 108  ///
 109  /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
 110  #[cfg(target_endian = "big")]    #[inline] pub fn to_le16(x: u16) -> u16 { unsafe { bswap16(x) } }
 111  
 112  /// Convert an u32 to little endian from the target's endianness.
 113  ///
 114  /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
 115  #[cfg(target_endian = "little")] #[inline] pub fn to_le32(x: u32) -> u32 { x }
 116  
 117  /// Convert an u32 to little endian from the target's endianness.
 118  ///
 119  /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
 120  #[cfg(target_endian = "big")]    #[inline] pub fn to_le32(x: u32) -> u32 { unsafe { bswap32(x) } }
 121  
 122  /// Convert an u64 to little endian from the target's endianness.
 123  ///
 124  /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
 125  #[cfg(target_endian = "little")] #[inline] pub fn to_le64(x: u64) -> u64 { x }
 126  
 127  /// Convert an u64 to little endian from the target's endianness.
 128  ///
 129  /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
 130  #[cfg(target_endian = "big")]    #[inline] pub fn to_le64(x: u64) -> u64 { unsafe { bswap64(x) } }
 131  
 132  
 133  /// Convert an u16 to big endian from the target's endianness.
 134  ///
 135  /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
 136  #[cfg(target_endian = "little")] #[inline] pub fn to_be16(x: u16) -> u16 { unsafe { bswap16(x) } }
 137  
 138  /// Convert an u16 to big endian from the target's endianness.
 139  ///
 140  /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
 141  #[cfg(target_endian = "big")]    #[inline] pub fn to_be16(x: u16) -> u16 { x }
 142  
 143  /// Convert an u32 to big endian from the target's endianness.
 144  ///
 145  /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
 146  #[cfg(target_endian = "little")] #[inline] pub fn to_be32(x: u32) -> u32 { unsafe { bswap32(x) } }
 147  
 148  /// Convert an u32 to big endian from the target's endianness.
 149  ///
 150  /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
 151  #[cfg(target_endian = "big")]    #[inline] pub fn to_be32(x: u32) -> u32 { x }
 152  
 153  /// Convert an u64 to big endian from the target's endianness.
 154  ///
 155  /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
 156  #[cfg(target_endian = "little")] #[inline] pub fn to_be64(x: u64) -> u64 { unsafe { bswap64(x) } }
 157  
 158  /// Convert an u64 to big endian from the target's endianness.
 159  ///
 160  /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
 161  #[cfg(target_endian = "big")]    #[inline] pub fn to_be64(x: u64) -> u64 { x }
 162  
 163  
 164  /// Convert an u16 from little endian to the target's endianness.
 165  ///
 166  /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
 167  #[cfg(target_endian = "little")] #[inline] pub fn from_le16(x: u16) -> u16 { x }
 168  
 169  /// Convert an u16 from little endian to the target's endianness.
 170  ///
 171  /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
 172  #[cfg(target_endian = "big")]    #[inline] pub fn from_le16(x: u16) -> u16 { unsafe { bswap16(x) } }
 173  
 174  /// Convert an u32 from little endian to the target's endianness.
 175  ///
 176  /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
 177  #[cfg(target_endian = "little")] #[inline] pub fn from_le32(x: u32) -> u32 { x }
 178  
 179  /// Convert an u32 from little endian to the target's endianness.
 180  ///
 181  /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
 182  #[cfg(target_endian = "big")]    #[inline] pub fn from_le32(x: u32) -> u32 { unsafe { bswap32(x) } }
 183  
 184  /// Convert an u64 from little endian to the target's endianness.
 185  ///
 186  /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
 187  #[cfg(target_endian = "little")] #[inline] pub fn from_le64(x: u64) -> u64 { x }
 188  
 189  /// Convert an u64 from little endian to the target's endianness.
 190  ///
 191  /// On little endian, this is a no-op.  On big endian, the bytes are swapped.
 192  #[cfg(target_endian = "big")]    #[inline] pub fn from_le64(x: u64) -> u64 { unsafe { bswap64(x) } }
 193  
 194  
 195  /// Convert an u16 from big endian to the target's endianness.
 196  ///
 197  /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
 198  #[cfg(target_endian = "little")] #[inline] pub fn from_be16(x: u16) -> u16 { unsafe { bswap16(x) } }
 199  
 200  /// Convert an u16 from big endian to the target's endianness.
 201  ///
 202  /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
 203  #[cfg(target_endian = "big")]    #[inline] pub fn from_be16(x: u16) -> u16 { x }
 204  
 205  /// Convert an u32 from big endian to the target's endianness.
 206  ///
 207  /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
 208  #[cfg(target_endian = "little")] #[inline] pub fn from_be32(x: u32) -> u32 { unsafe { bswap32(x) } }
 209  
 210  /// Convert an u32 from big endian to the target's endianness.
 211  ///
 212  /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
 213  #[cfg(target_endian = "big")]    #[inline] pub fn from_be32(x: u32) -> u32 { x }
 214  
 215  /// Convert an u64 from big endian to the target's endianness.
 216  ///
 217  /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
 218  #[cfg(target_endian = "little")] #[inline] pub fn from_be64(x: u64) -> u64 { unsafe { bswap64(x) } }
 219  
 220  /// Convert an u64 from big endian to the target's endianness.
 221  ///
 222  /// On big endian, this is a no-op.  On little endian, the bytes are swapped.
 223  #[cfg(target_endian = "big")]    #[inline] pub fn from_be64(x: u64) -> u64 { x }
 224  
 225  
 226  /**
 227   * Swap the values at two mutable locations of the same type, without
 228   * deinitialising or copying either one.
 229   */
 230  #[inline]
 231  pub fn swap<T>(x&mut T, y&mut T) {
 232      unsafe {
 233          // Give ourselves some scratch space to work with
 234          let mut tT = uninit();
 235  
 236          // Perform the swap, `&mut` pointers never alias
 237          ptr::copy_nonoverlapping_memory(&mut t, &*x, 1);
 238          ptr::copy_nonoverlapping_memory(x, &*y, 1);
 239          ptr::copy_nonoverlapping_memory(y, &t, 1);
 240  
 241          // y and t now point to the same thing, but we need to completely forget `tmp`
 242          // because it's no longer relevant.
 243          cast::forget(t);
 244      }
 245  }
 246  
 247  /**
 248   * Replace the value at a mutable location with a new one, returning the old
 249   * value, without deinitialising or copying either one.
 250   */
 251  #[inline]
 252  pub fn replace<T>(dest&mut T, mut srcT) -> T {
 253      swap(dest, &mut src);
 254      src
 255  }
 256  
 257  /// Disposes of a value.
 258  #[inline]
 259  pub fn drop<T>(_xT) { }
 260  
 261  #[cfg(test)]
 262  mod tests {
 263      use mem::*;
 264      use option::{Some,None};
 265      use str::StrSlice;
 266  
 267      #[test]
 268      fn size_of_basic() {
 269          assert_eq!(size_of::<u8>(), 1u);
 270          assert_eq!(size_of::<u16>(), 2u);
 271          assert_eq!(size_of::<u32>(), 4u);
 272          assert_eq!(size_of::<u64>(), 8u);
 273      }
 274  
 275      #[test]
 276      #[cfg(target_arch = "x86")]
 277      #[cfg(target_arch = "arm")]
 278      #[cfg(target_arch = "mips")]
 279      fn size_of_32() {
 280          assert_eq!(size_of::<uint>(), 4u);
 281          assert_eq!(size_of::<*uint>(), 4u);
 282      }
 283  
 284      #[test]
 285      #[cfg(target_arch = "x86_64")]
 286      fn size_of_64() {
 287          assert_eq!(size_of::<uint>(), 8u);
 288          assert_eq!(size_of::<*uint>(), 8u);
 289      }
 290  
 291      #[test]
 292      fn size_of_val_basic() {
 293          assert_eq!(size_of_val(&1u8), 1);
 294          assert_eq!(size_of_val(&1u16), 2);
 295          assert_eq!(size_of_val(&1u32), 4);
 296          assert_eq!(size_of_val(&1u64), 8);
 297      }
 298  
 299      #[test]
 300      fn nonzero_size_of_basic() {
 301          type Z = [i8, ..0];
 302          assert_eq!(size_of::<Z>(), 0u);
 303          assert_eq!(nonzero_size_of::<Z>(), 1u);
 304          assert_eq!(nonzero_size_of::<uint>(), size_of::<uint>());
 305      }
 306  
 307      #[test]
 308      fn nonzero_size_of_val_basic() {
 309          let z = [0u8, ..0];
 310          assert_eq!(size_of_val(&z), 0u);
 311          assert_eq!(nonzero_size_of_val(&z), 1u);
 312          assert_eq!(nonzero_size_of_val(&1u), size_of_val(&1u));
 313      }
 314  
 315      #[test]
 316      fn align_of_basic() {
 317          assert_eq!(pref_align_of::<u8>(), 1u);
 318          assert_eq!(pref_align_of::<u16>(), 2u);
 319          assert_eq!(pref_align_of::<u32>(), 4u);
 320      }
 321  
 322      #[test]
 323      #[cfg(target_arch = "x86")]
 324      #[cfg(target_arch = "arm")]
 325      #[cfg(target_arch = "mips")]
 326      fn align_of_32() {
 327          assert_eq!(pref_align_of::<uint>(), 4u);
 328          assert_eq!(pref_align_of::<*uint>(), 4u);
 329      }
 330  
 331      #[test]
 332      #[cfg(target_arch = "x86_64")]
 333      fn align_of_64() {
 334          assert_eq!(pref_align_of::<uint>(), 8u);
 335          assert_eq!(pref_align_of::<*uint>(), 8u);
 336      }
 337  
 338      #[test]
 339      fn align_of_val_basic() {
 340          assert_eq!(pref_align_of_val(&1u8), 1u);
 341          assert_eq!(pref_align_of_val(&1u16), 2u);
 342          assert_eq!(pref_align_of_val(&1u32), 4u);
 343      }
 344  
 345      #[test]
 346      fn test_swap() {
 347          let mut x = 31337;
 348          let mut y = 42;
 349          swap(&mut x, &mut y);
 350          assert_eq!(x, 42);
 351          assert_eq!(y, 31337);
 352      }
 353  
 354      #[test]
 355      fn test_replace() {
 356          let mut x = Some("test".to_owned());
 357          let y = replace(&mut x, None);
 358          assert!(x.is_none());
 359          assert!(y.is_some());
 360      }
 361  }
 362  
 363  /// Completely miscellaneous language-construct benchmarks.
 364  #[cfg(test)]
 365  mod bench {
 366      extern crate test;
 367      use self::test::Bencher;
 368      use option::{Some,None};
 369  
 370      // Static/dynamic method dispatch
 371  
 372      struct Struct {
 373          field: int
 374      }
 375  
 376      trait Trait {
 377          fn method(&self) -> int;
 378      }
 379  
 380      impl Trait for Struct {
 381          fn method(&self) -> int {
 382              self.field
 383          }
 384      }
 385  
 386      #[bench]
 387      fn trait_vtable_method_call(b: &mut Bencher) {
 388          let s = Struct { field: 10 };
 389          let t = &s as &Trait;
 390          b.iter(|| {
 391              t.method()
 392          });
 393      }
 394  
 395      #[bench]
 396      fn trait_static_method_call(b: &mut Bencher) {
 397          let s = Struct { field: 10 };
 398          b.iter(|| {
 399              s.method()
 400          });
 401      }
 402  
 403      // Overhead of various match forms
 404  
 405      #[bench]
 406      fn match_option_some(b: &mut Bencher) {
 407          let x = Some(10);
 408          b.iter(|| {
 409              match x {
 410                  Some(y) => y,
 411                  None => 11
 412              }
 413          });
 414      }
 415  
 416      #[bench]
 417      fn match_vec_pattern(b: &mut Bencher) {
 418          let x = [1,2,3,4,5,6];
 419          b.iter(|| {
 420              match x {
 421                  [1,2,3,..] => 10,
 422                  _ => 11
 423              }
 424          });
 425      }
 426  }


libstd/mem.rs:258:10-258:10 -fn- definition:
pub fn drop<T>(_x: T) { }
mod tests {
    use mem::*;
references:- 16
libstd/rt/task.rs:
165:                 drop(task);
166:                 drop(storage_map);
libstd/rt/unwind.rs:
430:                             Local::put(task);
431:                             drop(prev);
432:                             task = Local::take();
libstd/comm/sync.rs:
352:         };
353:         mem::drop((state, guard));
libstd/io/process.rs:
379:     pub fn wait(&mut self) -> ProcessExit {
380:         drop(self.stdin.take());
381:         self.handle.wait()
--
389:     pub fn wait_with_output(&mut self) -> ProcessOutput {
390:         drop(self.stdin.take());
391:         fn read(stream: Option<io::PipeStream>) -> Receiver<IoResult<Vec<u8>>> {
--
417:         drop(self.stdin.take());
418:         drop(self.stdout.take());
419:         drop(self.stderr.take());
420:         drop(mem::replace(&mut self.extra_io, ~[]));
libstd/io/signal.rs:
143:         match self.handles.iter().position(|&(i, _)| i == signum) {
144:             Some(i) => drop(self.handles.remove(i)),
145:             None => {}
libstd/io/stdio.rs:
233:             let prev = replace(&mut Local::borrow(None::<Task>).stdout, my_stdout);
234:             drop(prev);
235:             ret
libstd/rt/task.rs:
164:                 };
165:                 drop(task);
166:                 drop(storage_map);


libstd/mem.rs:38:10-38:10 -fn- definition:
pub fn nonzero_size_of<T>() -> uint {
    let s = size_of::<T>();
    if s == 0 { 1 } else { s }
references:- 5
46: pub fn nonzero_size_of_val<T>(_val: &T) -> uint {
47:     nonzero_size_of::<T>()
48: }
libstd/slice.rs:
2062:                 let diff = (self.end as uint) - (self.ptr as uint);
2063:                 let exact = diff / mem::nonzero_size_of::<T>();
2064:                 (exact, Some(exact))
--
2304:             (*ret).fill = len * mem::nonzero_size_of::<A>();
2305:             (*ret).alloc = len * mem::nonzero_size_of::<A>();
2306:             ptr::copy_nonoverlapping_memory(&mut (*ret).data as *mut _ as *mut u8,


libstd/mem.rs:251:10-251:10 -fn- definition:
pub fn replace<T>(dest: &mut T, mut src: T) -> T {
    swap(dest, &mut src);
    src
references:- 30
libstd/rt/unwind.rs:
libstd/rt/args.rs:
libstd/rt/at_exit_imp.rs:
libstd/slice.rs:
libstd/option.rs:
libstd/comm/oneshot.rs:
libstd/comm/sync.rs:
libstd/local_data.rs:
libstd/io/process.rs:
libstd/io/stdio.rs:
libstd/comm/sync.rs:


libstd/mem.rs:24:10-24:10 -fn- definition:
pub fn size_of<T>() -> uint {
    unsafe { intrinsics::size_of::<T>() }
}
references:- 135
libstd/reflect.rs:
libstd/rt/global_heap.rs:
libstd/rt/local_heap.rs:
libstd/slice.rs:
libstd/vec.rs:
libstd/num/mod.rs:
libstd/sync/deque.rs:
libstd/cast.rs:
libstd/num/mod.rs:


libstd/mem.rs:83:10-83:10 -fn- definition:
pub unsafe fn init<T>() -> T {
    intrinsics::init()
}
references:- 2
libstd/unstable/mutex.rs:
392:             let m = Mutex {
393:                 lock: Unsafe::new(mem::init()),
394:                 cond: Unsafe::new(mem::init()),
395:             };


libstd/mem.rs:89:10-89:10 -fn- definition:
pub unsafe fn uninit<T>() -> T {
    intrinsics::uninit()
}
references:- 7
233:         // Give ourselves some scratch space to work with
234:         let mut t: T = uninit();
libstd/rt/thread.rs:
227:         let mut native: libc::pthread_t = mem::uninit();
228:         let mut attr: libc::pthread_attr_t = mem::uninit();
229:         assert_eq!(pthread_attr_init(&mut attr), 0);
libstd/ptr.rs:
272: pub unsafe fn read<T>(src: *T) -> T {
273:     let mut tmp: T = mem::uninit();
274:     copy_nonoverlapping_memory(&mut tmp, src, 1);
libstd/c_str.rs:
349:     if v.len() < BUF_LEN {
350:         let mut buf: [u8, .. BUF_LEN] = mem::uninit();
351:         slice::bytes::copy_memory(buf, v);
libstd/cast.rs:
19: pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
20:     let mut dest: U = mem::uninit();
21:     let dest_ptr: *mut u8 = transmute(&mut dest);
libstd/rt/thread.rs:
226:     pub unsafe fn create(stack: uint, p: ~proc():Send) -> rust_thread {
227:         let mut native: libc::pthread_t = mem::uninit();
228:         let mut attr: libc::pthread_attr_t = mem::uninit();


libstd/mem.rs:97:10-97:10 -fn- definition:
pub unsafe fn move_val_init<T>(dst: &mut T, src: T) {
    intrinsics::move_val_init(dst, src)
}
references:- 7
libstd/slice.rs:
670:                 |i, ()| while *i < len {
671:                     mem::move_val_init(
672:                         &mut(*p.offset(*i as int)),
--
1780:     unsafe fn init_elem(self, i: uint, val: T) {
1781:         mem::move_val_init(&mut (*self.as_mut_ptr().offset(i as int)), val);
1782:     }
libstd/vec.rs:
921:                 // element.
922:                 move_val_init(&mut *p, element);
923:             }


libstd/mem.rs:230:10-230:10 -fn- definition:
pub fn swap<T>(x: &mut T, y: &mut T) {
    unsafe {
        // Give ourselves some scratch space to work with
references:- 13
252: pub fn replace<T>(dest: &mut T, mut src: T) -> T {
253:     swap(dest, &mut src);
254:     src
libstd/slice.rs:
1758:         for (a, b) in self.mut_iter().zip(src.mut_slice(start, end).mut_iter()) {
1759:             mem::swap(a, b);
1760:         }
libstd/vec.rs:
1342:                         let p_w = p_wm1.offset(1);
1343:                         mem::swap(&mut *p_r, &mut *p_w);
1344:                     }
libstd/ptr.rs:
265: pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
266:     mem::swap(cast::transmute(dest), &mut src); // cannot overlap
267:     src
libstd/comm/mod.rs:
601:             let mut tmp = Sender::new(Shared(packet.clone()));
602:             mem::swap(&mut cast::transmute_mut(self).inner, &mut tmp.inner);
603:         }
--
876:             unsafe {
877:                 mem::swap(&mut cast::transmute_mut(self).inner,
878:                           &mut new_port.inner);
--
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/iter.rs:
688:             match (self.next(), self.next_back()) {
689:                 (Some(x), Some(y)) => mem::swap(x, y),
690:                 _ => break


libstd/mem.rs:54:10-54:10 -fn- definition:
pub fn min_align_of<T>() -> uint {
    unsafe { intrinsics::min_align_of::<T>() }
}
references:- 2
62: pub fn min_align_of_val<T>(_val: &T) -> uint {
63:     min_align_of::<T>()
64: }
libstd/reflect.rs:
60:     pub fn align_to<T>(&mut self) {
61:         self.align(mem::min_align_of::<T>());
62:     }