intrinsics.rs 31.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

S
Steve Klabnik 已提交
11 12
//! rustc compiler intrinsics.
//!
R
Reeze Xia 已提交
13
//! The corresponding definitions are in librustc_trans/intrinsic.rs.
S
Steve Klabnik 已提交
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
//!
//! # Volatiles
//!
//! The volatile intrinsics provide operations intended to act on I/O
//! memory, which are guaranteed to not be reordered by the compiler
//! across other volatile intrinsics. See the LLVM documentation on
//! [[volatile]].
//!
//! [volatile]: http://llvm.org/docs/LangRef.html#volatile-memory-accesses
//!
//! # Atomics
//!
//! The atomic intrinsics provide common atomic operations on machine
//! words, with multiple possible memory orderings. They obey the same
//! semantics as C++11. See the LLVM documentation on [[atomics]].
//!
//! [atomics]: http://llvm.org/docs/Atomics.html
//!
//! A quick refresher on memory ordering:
//!
//! * Acquire - a barrier for acquiring a lock. Subsequent reads and writes
//!   take place after the barrier.
//! * Release - a barrier for releasing a lock. Preceding reads and writes
//!   take place before the barrier.
//! * Sequentially consistent - sequentially consistent operations are
//!   guaranteed to happen in order. This is the standard mode for working
//!   with atomic types and is equivalent to Java's `volatile`.
D
Daniel Micay 已提交
41

42 43 44
#![unstable(feature = "core_intrinsics",
            reason = "intrinsics are unlikely to ever be stabilized, instead \
                      they should be used through stabilized interfaces \
45 46
                      in the rest of the standard library",
            issue = "0")]
A
Aaron Turon 已提交
47
#![allow(missing_docs)]
48

49 50
extern "rust-intrinsic" {

51
    // NB: These intrinsics take raw pointers because they mutate aliased
52 53
    // memory, which is not valid for either `&` or `&mut`.

54 55 56 57 58 59 60 61 62
    pub fn atomic_cxchg<T>(dst: *mut T, old: T, src: T) -> (T, bool);
    pub fn atomic_cxchg_acq<T>(dst: *mut T, old: T, src: T) -> (T, bool);
    pub fn atomic_cxchg_rel<T>(dst: *mut T, old: T, src: T) -> (T, bool);
    pub fn atomic_cxchg_acqrel<T>(dst: *mut T, old: T, src: T) -> (T, bool);
    pub fn atomic_cxchg_relaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
    pub fn atomic_cxchg_failrelaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
    pub fn atomic_cxchg_failacq<T>(dst: *mut T, old: T, src: T) -> (T, bool);
    pub fn atomic_cxchg_acq_failrelaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
    pub fn atomic_cxchg_acqrel_failrelaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
63 64 65 66 67 68 69 70 71 72

    pub fn atomic_cxchgweak<T>(dst: *mut T, old: T, src: T) -> (T, bool);
    pub fn atomic_cxchgweak_acq<T>(dst: *mut T, old: T, src: T) -> (T, bool);
    pub fn atomic_cxchgweak_rel<T>(dst: *mut T, old: T, src: T) -> (T, bool);
    pub fn atomic_cxchgweak_acqrel<T>(dst: *mut T, old: T, src: T) -> (T, bool);
    pub fn atomic_cxchgweak_relaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
    pub fn atomic_cxchgweak_failrelaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
    pub fn atomic_cxchgweak_failacq<T>(dst: *mut T, old: T, src: T) -> (T, bool);
    pub fn atomic_cxchgweak_acq_failrelaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
    pub fn atomic_cxchgweak_acqrel_failrelaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
73

74 75 76
    pub fn atomic_load<T>(src: *const T) -> T;
    pub fn atomic_load_acq<T>(src: *const T) -> T;
    pub fn atomic_load_relaxed<T>(src: *const T) -> T;
77
    pub fn atomic_load_unordered<T>(src: *const T) -> T;
78 79 80 81

    pub fn atomic_store<T>(dst: *mut T, val: T);
    pub fn atomic_store_rel<T>(dst: *mut T, val: T);
    pub fn atomic_store_relaxed<T>(dst: *mut T, val: T);
82
    pub fn atomic_store_unordered<T>(dst: *mut T, val: T);
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148

    pub fn atomic_xchg<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_xchg_acq<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_xchg_rel<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_xchg_acqrel<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_xchg_relaxed<T>(dst: *mut T, src: T) -> T;

    pub fn atomic_xadd<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_xadd_acq<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_xadd_rel<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_xadd_acqrel<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_xadd_relaxed<T>(dst: *mut T, src: T) -> T;

    pub fn atomic_xsub<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_xsub_acq<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_xsub_rel<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_xsub_acqrel<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_xsub_relaxed<T>(dst: *mut T, src: T) -> T;

    pub fn atomic_and<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_and_acq<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_and_rel<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_and_acqrel<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_and_relaxed<T>(dst: *mut T, src: T) -> T;

    pub fn atomic_nand<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_nand_acq<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_nand_rel<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_nand_acqrel<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_nand_relaxed<T>(dst: *mut T, src: T) -> T;

    pub fn atomic_or<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_or_acq<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_or_rel<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_or_acqrel<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_or_relaxed<T>(dst: *mut T, src: T) -> T;

    pub fn atomic_xor<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_xor_acq<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_xor_rel<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_xor_acqrel<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_xor_relaxed<T>(dst: *mut T, src: T) -> T;

    pub fn atomic_max<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_max_acq<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_max_rel<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_max_acqrel<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_max_relaxed<T>(dst: *mut T, src: T) -> T;

    pub fn atomic_min<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_min_acq<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_min_rel<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_min_acqrel<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_min_relaxed<T>(dst: *mut T, src: T) -> T;

    pub fn atomic_umin<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_umin_acq<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_umin_rel<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_umin_acqrel<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_umin_relaxed<T>(dst: *mut T, src: T) -> T;

    pub fn atomic_umax<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_umax_acq<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_umax_rel<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_umax_acqrel<T>(dst: *mut T, src: T) -> T;
    pub fn atomic_umax_relaxed<T>(dst: *mut T, src: T) -> T;
149 150 151
}

extern "rust-intrinsic" {
152 153 154 155 156 157

    pub fn atomic_fence();
    pub fn atomic_fence_acq();
    pub fn atomic_fence_rel();
    pub fn atomic_fence_acqrel();

158 159
    /// A compiler-only memory barrier.
    ///
160 161 162 163
    /// Memory accesses will never be reordered across this barrier by the
    /// compiler, but no instructions will be emitted for it. This is
    /// appropriate for operations on the same thread that may be preempted,
    /// such as when interacting with signal handlers.
164 165 166 167 168
    pub fn atomic_singlethreadfence();
    pub fn atomic_singlethreadfence_acq();
    pub fn atomic_singlethreadfence_rel();
    pub fn atomic_singlethreadfence_acqrel();

169 170 171 172
    /// Magic intrinsic that derives its meaning from attributes
    /// attached to the function.
    ///
    /// For example, dataflow uses this to inject static assertions so
173
    /// that `rustc_peek(potentially_uninitialized)` would actually
174 175 176 177
    /// double-check that dataflow did indeed compute that it is
    /// uninitialized at that point in the control flow.
    pub fn rustc_peek<T>(_: T) -> T;

178
    /// Aborts the execution of the process.
179 180
    pub fn abort() -> !;

181
    /// Tells LLVM that this point in the code is not reachable,
K
Keegan McAllister 已提交
182 183 184 185 186
    /// enabling further optimizations.
    ///
    /// NB: This is very different from the `unreachable!()` macro!
    pub fn unreachable() -> !;

187
    /// Informs the optimizer that a condition is always true.
V
Viktor Dahl 已提交
188 189
    /// If the condition is false, the behavior is undefined.
    ///
190 191 192 193 194
    /// No code is generated for this intrinsic, but the optimizer will try
    /// to preserve it (and its condition) between passes, which may interfere
    /// with optimization of surrounding code and reduce performance. It should
    /// not be used if the invariant can be discovered by the optimizer on its
    /// own, or if it does not enable any significant optimizations.
V
Viktor Dahl 已提交
195 196
    pub fn assume(b: bool);

197
    /// Executes a breakpoint trap, for inspection by a debugger.
198 199
    pub fn breakpoint();

B
Brian Anderson 已提交
200 201
    /// The size of a type in bytes.
    ///
202 203
    /// More specifically, this is the offset in bytes between successive
    /// items of the same type, including alignment padding.
204
    pub fn size_of<T>() -> usize;
205

206 207 208 209 210
    /// Moves a value to an uninitialized memory location.
    ///
    /// Drop glue is not run on the destination.
    pub fn move_val_init<T>(dst: *mut T, src: T);

211 212
    pub fn min_align_of<T>() -> usize;
    pub fn pref_align_of<T>() -> usize;
213

N
Nick Cameron 已提交
214 215
    pub fn size_of_val<T: ?Sized>(_: &T) -> usize;
    pub fn min_align_of_val<T: ?Sized>(_: &T) -> usize;
216 217 218

    /// Executes the destructor (if any) of the pointed-to value.
    ///
219
    /// This has two use cases:
220 221 222 223 224 225 226 227 228 229
    ///
    /// * It is *required* to use `drop_in_place` to drop unsized types like
    ///   trait objects, because they can't be read out onto the stack and
    ///   dropped normally.
    ///
    /// * It is friendlier to the optimizer to do this over `ptr::read` when
    ///   dropping manually allocated memory (e.g. when writing Box/Rc/Vec),
    ///   as the compiler doesn't need to prove that it's sound to elide the
    ///   copy.
    ///
230
    /// # Undefined Behavior
231 232 233
    ///
    /// This has all the same safety problems as `ptr::read` with respect to
    /// invalid pointers, types, and double drops.
234
    #[stable(feature = "drop_in_place", since = "1.8.0")]
235
    pub fn drop_in_place<T: ?Sized>(to_drop: *mut T);
N
Nick Cameron 已提交
236

237 238 239
    /// Gets a static string slice containing the name of a type.
    pub fn type_name<T: ?Sized>() -> &'static str;

A
Alex Crichton 已提交
240 241 242
    /// Gets an identifier which is globally unique to the specified type. This
    /// function will return the same value for a type regardless of whichever
    /// crate it is invoked in.
243 244
    pub fn type_id<T: ?Sized + 'static>() -> u64;

245
    /// Creates a value initialized to zero.
B
Brian Anderson 已提交
246 247
    ///
    /// `init` is unsafe because it returns a zeroed-out datum,
248 249 250
    /// which is unsafe unless T is `Copy`.  Also, even if T is
    /// `Copy`, an all-zero value may not correspond to any legitimate
    /// state for the type in question.
251
    pub fn init<T>() -> T;
252

253
    /// Creates an uninitialized value.
254 255 256 257 258 259
    ///
    /// `uninit` is unsafe because there is no guarantee of what its
    /// contents are. In particular its drop-flag may be set to any
    /// state, which means it may claim either dropped or
    /// undropped. In the general case one must use `ptr::write` to
    /// initialize memory previous set to the result of `uninit`.
260
    pub fn uninit<T>() -> T;
J
James Miller 已提交
261

262
    /// Moves a value out of scope without running drop glue.
263
    pub fn forget<T>(_: T) -> ();
264

K
Keegan McAllister 已提交
265 266 267 268
    /// Reinterprets the bits of a value of one type as another type.
    ///
    /// Both types must have the same size. Neither the original, nor the result,
    /// may be an [invalid value](../../nomicon/meet-safe-and-unsafe.html).
269
    ///
U
ubsan 已提交
270
    /// `transmute` is semantically equivalent to a bitwise move of one type
K
Keegan McAllister 已提交
271 272 273
    /// into another. It copies the bits from the source value into the
    /// destination value, then forgets the original. It's equivalent to C's
    /// `memcpy` under the hood, just like `transmute_copy`.
274
    ///
K
Keegan McAllister 已提交
275 276
    /// `transmute` is **incredibly** unsafe. There are a vast number of ways to
    /// cause [undefined behavior][ub] with this function. `transmute` should be
277 278
    /// the absolute last resort.
    ///
U
ubsan 已提交
279 280
    /// The [nomicon](../../nomicon/transmutes.html) has additional
    /// documentation.
281
    ///
K
Keegan McAllister 已提交
282 283
    /// [ub]: ../../reference.html#behavior-considered-undefined
    ///
A
Alexis Beingessner 已提交
284
    /// # Examples
285
    ///
U
ubsan 已提交
286 287 288
    /// There are a few things that `transmute` is really useful for.
    ///
    /// Getting the bitpattern of a floating point type (or, more generally,
U
ubsan 已提交
289
    /// type punning, when `T` and `U` aren't pointers):
U
ubsan 已提交
290 291 292 293 294 295 296 297
    ///
    /// ```
    /// let bitpattern = unsafe {
    ///     std::mem::transmute::<f32, u32>(1.0)
    /// };
    /// assert_eq!(bitpattern, 0x3F800000);
    /// ```
    ///
K
Keegan McAllister 已提交
298 299
    /// Turning a pointer into a function pointer. This is *not* portable to
    /// machines where function pointers and data pointers have different sizes.
U
ubsan 已提交
300 301 302 303 304 305 306 307 308 309 310 311
    ///
    /// ```
    /// fn foo() -> i32 {
    ///     0
    /// }
    /// let pointer = foo as *const ();
    /// let function = unsafe {
    ///     std::mem::transmute::<*const (), fn() -> i32>(pointer)
    /// };
    /// assert_eq!(function(), 0);
    /// ```
    ///
K
Keegan McAllister 已提交
312 313
    /// Extending a lifetime, or shortening an invariant lifetime. This is
    /// advanced, very unsafe Rust!
U
ubsan 已提交
314 315 316 317 318 319 320 321 322 323 324 325 326
    ///
    /// ```
    /// struct R<'a>(&'a i32);
    /// unsafe fn extend_lifetime<'b>(r: R<'b>) -> R<'static> {
    ///     std::mem::transmute::<R<'b>, R<'static>>(r)
    /// }
    ///
    /// unsafe fn shorten_invariant_lifetime<'b, 'c>(r: &'b mut R<'static>)
    ///                                              -> &'b mut R<'c> {
    ///     std::mem::transmute::<&'b mut R<'static>, &'b mut R<'c>>(r)
    /// }
    /// ```
    ///
U
ubsan 已提交
327 328
    /// # Alternatives
    ///
K
Keegan McAllister 已提交
329 330 331
    /// Don't despair: many uses of `transmute` can be achieved through other means.
    /// Below are common applications of `transmute` which can be replaced with safer
    /// constructs.
332
    ///
U
ubsan 已提交
333
    /// Turning a pointer into a `usize`:
U
ubsan 已提交
334
    ///
335
    /// ```
U
ubsan 已提交
336
    /// let ptr = &0;
U
ubsan 已提交
337 338 339
    /// let ptr_num_transmute = unsafe {
    ///     std::mem::transmute::<&i32, usize>(ptr)
    /// };
K
Keegan McAllister 已提交
340
    ///
U
ubsan 已提交
341
    /// // Use an `as` cast instead
U
ubsan 已提交
342
    /// let ptr_num_cast = ptr as *const i32 as usize;
343
    /// ```
U
ubsan 已提交
344
    ///
U
ubsan 已提交
345
    /// Turning a `*mut T` into an `&mut T`:
U
ubsan 已提交
346
    ///
U
ubsan 已提交
347 348
    /// ```
    /// let ptr: *mut i32 = &mut 0;
U
ubsan 已提交
349 350 351
    /// let ref_transmuted = unsafe {
    ///     std::mem::transmute::<*mut i32, &mut i32>(ptr)
    /// };
K
Keegan McAllister 已提交
352
    ///
U
ubsan 已提交
353
    /// // Use a reborrow instead
U
ubsan 已提交
354
    /// let ref_casted = unsafe { &mut *ptr };
U
ubsan 已提交
355
    /// ```
U
ubsan 已提交
356
    ///
U
ubsan 已提交
357
    /// Turning an `&mut T` into an `&mut U`:
U
ubsan 已提交
358
    ///
U
ubsan 已提交
359 360
    /// ```
    /// let ptr = &mut 0;
U
ubsan 已提交
361 362 363
    /// let val_transmuted = unsafe {
    ///     std::mem::transmute::<&mut i32, &mut u32>(ptr)
    /// };
K
Keegan McAllister 已提交
364
    ///
U
ubsan 已提交
365 366
    /// // Now, put together `as` and reborrowing - note the chaining of `as`
    /// // `as` is not transitive
U
ubsan 已提交
367
    /// let val_casts = unsafe { &mut *(ptr as *mut i32 as *mut u32) };
U
ubsan 已提交
368
    /// ```
369
    ///
U
ubsan 已提交
370
    /// Turning an `&str` into an `&[u8]`:
371
    ///
U
ubsan 已提交
372 373
    /// ```
    /// // this is not a good way to do this.
U
ubsan 已提交
374
    /// let slice = unsafe { std::mem::transmute::<&str, &[u8]>("Rust") };
U
ubsan 已提交
375
    /// assert_eq!(slice, &[82, 117, 115, 116]);
K
Keegan McAllister 已提交
376
    ///
U
ubsan 已提交
377 378
    /// // You could use `str::as_bytes`
    /// let slice = "Rust".as_bytes();
U
ubsan 已提交
379
    /// assert_eq!(slice, &[82, 117, 115, 116]);
K
Keegan McAllister 已提交
380
    ///
U
ubsan 已提交
381 382
    /// // Or, just use a byte string, if you have control over the string
    /// // literal
U
ubsan 已提交
383
    /// assert_eq!(b"Rust", &[82, 117, 115, 116]);
U
ubsan 已提交
384
    /// ```
U
ubsan 已提交
385
    ///
U
ubsan 已提交
386
    /// Turning a `Vec<&T>` into a `Vec<Option<&T>>`:
U
ubsan 已提交
387
    ///
U
ubsan 已提交
388 389
    /// ```
    /// let store = [0, 1, 2, 3];
U
ubsan 已提交
390
    /// let mut v_orig = store.iter().collect::<Vec<&i32>>();
K
Keegan McAllister 已提交
391
    ///
U
ubsan 已提交
392 393
    /// // Using transmute: this is Undefined Behavior, and a bad idea.
    /// // However, it is no-copy.
U
ubsan 已提交
394 395 396 397
    /// let v_transmuted = unsafe {
    ///     std::mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>(
    ///         v_orig.clone())
    /// };
K
Keegan McAllister 已提交
398
    ///
U
ubsan 已提交
399
    /// // This is the suggested, safe way.
K
Keegan McAllister 已提交
400
    /// // It does copy the entire vector, though, into a new array.
U
ubsan 已提交
401 402 403 404
    /// let v_collected = v_orig.clone()
    ///                         .into_iter()
    ///                         .map(|r| Some(r))
    ///                         .collect::<Vec<Option<&i32>>>();
K
Keegan McAllister 已提交
405
    ///
U
ubsan 已提交
406
    /// // The no-copy, unsafe way, still using transmute, but not UB.
U
ubsan 已提交
407 408 409 410 411
    /// // This is equivalent to the original, but safer, and reuses the
    /// // same Vec internals. Therefore the new inner type must have the
    /// // exact same size, and the same or lesser alignment, as the old
    /// // type. The same caveats exist for this method as transmute, for
    /// // the original inner type (`&i32`) to the converted inner type
U
ubsan 已提交
412
    /// // (`Option<&i32>`), so read the nomicon pages linked above.
U
ubsan 已提交
413 414 415 416 417 418
    /// let v_from_raw = unsafe {
    ///     Vec::from_raw_parts(v_orig.as_mut_ptr(),
    ///                         v_orig.len(),
    ///                         v_orig.capacity())
    /// };
    /// std::mem::forget(v_orig);
U
ubsan 已提交
419
    /// ```
U
ubsan 已提交
420
    ///
U
ubsan 已提交
421 422
    /// Implementing `split_at_mut`:
    ///
U
ubsan 已提交
423 424
    /// ```
    /// use std::{slice, mem};
K
Keegan McAllister 已提交
425
    ///
U
ubsan 已提交
426
    /// // There are multiple ways to do this; and there are multiple problems
U
ubsan 已提交
427
    /// // with the following, transmute, way.
U
ubsan 已提交
428
    /// fn split_at_mut_transmute<T>(slice: &mut [T], mid: usize)
U
ubsan 已提交
429 430
    ///                              -> (&mut [T], &mut [T]) {
    ///     let len = slice.len();
U
ubsan 已提交
431
    ///     assert!(mid <= len);
U
ubsan 已提交
432
    ///     unsafe {
U
ubsan 已提交
433
    ///         let slice2 = mem::transmute::<&mut [T], &mut [T]>(slice);
U
ubsan 已提交
434 435
    ///         // first: transmute is not typesafe; all it checks is that T and
    ///         // U are of the same size. Second, right here, you have two
U
ubsan 已提交
436
    ///         // mutable references pointing to the same memory.
U
ubsan 已提交
437
    ///         (&mut slice[0..mid], &mut slice2[mid..len])
U
ubsan 已提交
438
    ///     }
U
ubsan 已提交
439
    /// }
K
Keegan McAllister 已提交
440
    ///
U
ubsan 已提交
441
    /// // This gets rid of the typesafety problems; `&mut *` will *only* give
U
ubsan 已提交
442
    /// // you an `&mut T` from an `&mut T` or `*mut T`.
U
ubsan 已提交
443
    /// fn split_at_mut_casts<T>(slice: &mut [T], mid: usize)
U
ubsan 已提交
444 445
    ///                          -> (&mut [T], &mut [T]) {
    ///     let len = slice.len();
U
ubsan 已提交
446
    ///     assert!(mid <= len);
U
ubsan 已提交
447 448 449
    ///     unsafe {
    ///         let slice2 = &mut *(slice as *mut [T]);
    ///         // however, you still have two mutable references pointing to
U
ubsan 已提交
450
    ///         // the same memory.
U
ubsan 已提交
451
    ///         (&mut slice[0..mid], &mut slice2[mid..len])
U
ubsan 已提交
452 453
    ///     }
    /// }
K
Keegan McAllister 已提交
454
    ///
U
ubsan 已提交
455 456
    /// // This is how the standard library does it. This is the best method, if
    /// // you need to do something like this
U
ubsan 已提交
457
    /// fn split_at_stdlib<T>(slice: &mut [T], mid: usize)
U
ubsan 已提交
458
    ///                       -> (&mut [T], &mut [T]) {
U
ubsan 已提交
459 460
    ///     let len = slice.len();
    ///     assert!(mid <= len);
U
ubsan 已提交
461
    ///     unsafe {
U
ubsan 已提交
462
    ///         let ptr = slice.as_mut_ptr();
U
ubsan 已提交
463 464
    ///         // This now has three mutable references pointing at the same
    ///         // memory. `slice`, the rvalue ret.0, and the rvalue ret.1.
U
ubsan 已提交
465 466 467
    ///         // `slice` is never used after `let ptr = ...`, and so one can
    ///         // treat it as "dead", and therefore, you only have two real
    ///         // mutable slices.
U
ubsan 已提交
468 469
    ///         (slice::from_raw_parts_mut(ptr, mid),
    ///          slice::from_raw_parts_mut(ptr.offset(mid as isize), len - mid))
U
ubsan 已提交
470
    ///     }
471
    /// }
472
    /// ```
B
Brian Anderson 已提交
473
    #[stable(feature = "rust1", since = "1.0.0")]
474
    pub fn transmute<T, U>(e: T) -> U;
475

476 477 478 479 480 481
    /// Returns `true` if the actual type given as `T` requires drop
    /// glue; returns `false` if the actual type provided for `T`
    /// implements `Copy`.
    ///
    /// If the actual type neither requires drop glue nor implements
    /// `Copy`, then may return `true` or `false`.
482
    pub fn needs_drop<T>() -> bool;
483

S
Simonas Kazlauskas 已提交
484
    /// Calculates the offset from a pointer.
D
Daniel Micay 已提交
485
    ///
486 487
    /// This is implemented as an intrinsic to avoid converting to and from an
    /// integer, since the conversion would throw away aliasing information.
S
Simonas Kazlauskas 已提交
488 489 490 491 492 493 494
    ///
    /// # Safety
    ///
    /// Both the starting and resulting pointer must be either in bounds or one
    /// byte past the end of an allocated object. If either pointer is out of
    /// bounds or arithmetic overflow occurs then any further use of the
    /// returned value will result in undefined behavior.
495
    pub fn offset<T>(dst: *const T, offset: isize) -> *const T;
D
Daniel Micay 已提交
496

497 498 499 500 501 502 503 504 505 506 507 508 509
    /// Calculates the offset from a pointer, potentially wrapping.
    ///
    /// This is implemented as an intrinsic to avoid converting to and from an
    /// integer, since the conversion inhibits certain optimizations.
    ///
    /// # Safety
    ///
    /// Unlike the `offset` intrinsic, this intrinsic does not restrict the
    /// resulting pointer to point into or one byte past the end of an allocated
    /// object, and it wraps with two's complement arithmetic. The resulting
    /// value is not necessarily valid to be used to actually access memory.
    pub fn arith_offset<T>(dst: *const T, offset: isize) -> *const T;

A
Alexis Beingessner 已提交
510
    /// Copies `count * size_of<T>` bytes from `src` to `dst`. The source
511 512
    /// and destination may *not* overlap.
    ///
513
    /// `copy_nonoverlapping` is semantically equivalent to C's `memcpy`.
514
    ///
A
Alexis Beingessner 已提交
515 516
    /// # Safety
    ///
517
    /// Beyond requiring that the program must be allowed to access both regions
A
Andrew Paseltiner 已提交
518
    /// of memory, it is Undefined Behavior for source and destination to
519 520 521 522
    /// overlap. Care must also be taken with the ownership of `src` and
    /// `dst`. This method semantically moves the values of `src` into `dst`.
    /// However it does not drop the contents of `dst`, or prevent the contents
    /// of `src` from being dropped or used.
A
Alexis Beingessner 已提交
523 524
    ///
    /// # Examples
525 526 527 528 529 530 531
    ///
    /// A safe swap function:
    ///
    /// ```
    /// use std::mem;
    /// use std::ptr;
    ///
K
Kevin Butler 已提交
532
    /// # #[allow(dead_code)]
533 534 535 536 537 538
    /// fn swap<T>(x: &mut T, y: &mut T) {
    ///     unsafe {
    ///         // Give ourselves some scratch space to work with
    ///         let mut t: T = mem::uninitialized();
    ///
    ///         // Perform the swap, `&mut` pointers never alias
539 540 541
    ///         ptr::copy_nonoverlapping(x, &mut t, 1);
    ///         ptr::copy_nonoverlapping(y, x, 1);
    ///         ptr::copy_nonoverlapping(&t, y, 1);
542 543 544 545 546 547 548
    ///
    ///         // y and t now point to the same thing, but we need to completely forget `tmp`
    ///         // because it's no longer relevant.
    ///         mem::forget(t);
    ///     }
    /// }
    /// ```
549
    #[stable(feature = "rust1", since = "1.0.0")]
550 551
    pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);

A
Alexis Beingessner 已提交
552
    /// Copies `count * size_of<T>` bytes from `src` to `dst`. The source
553 554
    /// and destination may overlap.
    ///
555
    /// `copy` is semantically equivalent to C's `memmove`.
556
    ///
A
Alexis Beingessner 已提交
557 558 559 560 561 562 563 564
    /// # Safety
    ///
    /// Care must be taken with the ownership of `src` and `dst`.
    /// This method semantically moves the values of `src` into `dst`.
    /// However it does not drop the contents of `dst`, or prevent the contents of `src`
    /// from being dropped or used.
    ///
    /// # Examples
565 566 567 568 569 570
    ///
    /// Efficiently create a Rust vector from an unsafe buffer:
    ///
    /// ```
    /// use std::ptr;
    ///
K
Kevin Butler 已提交
571
    /// # #[allow(dead_code)]
572
    /// unsafe fn from_buf_raw<T>(ptr: *const T, elts: usize) -> Vec<T> {
573 574
    ///     let mut dst = Vec::with_capacity(elts);
    ///     dst.set_len(elts);
575
    ///     ptr::copy(ptr, dst.as_mut_ptr(), elts);
576 577 578 579
    ///     dst
    /// }
    /// ```
    ///
580
    #[stable(feature = "rust1", since = "1.0.0")]
581 582
    pub fn copy<T>(src: *const T, dst: *mut T, count: usize);

583
    /// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
C
Cole Reynolds 已提交
584
    /// bytes of memory starting at `dst` to `val`.
585 586 587
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn write_bytes<T>(dst: *mut T, val: u8, count: usize);

588 589 590 591
    /// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with
    /// a size of `count` * `size_of::<T>()` and an alignment of
    /// `min_align_of::<T>()`
    ///
592
    /// The volatile parameter is set to `true`, so it will not be optimized out.
593
    pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T,
594
                                                  count: usize);
595 596 597 598
    /// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with
    /// a size of `count` * `size_of::<T>()` and an alignment of
    /// `min_align_of::<T>()`
    ///
599
    /// The volatile parameter is set to `true`, so it will not be optimized out.
600
    pub fn volatile_copy_memory<T>(dst: *mut T, src: *const T, count: usize);
601 602 603 604
    /// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a
    /// size of `count` * `size_of::<T>()` and an alignment of
    /// `min_align_of::<T>()`.
    ///
605
    /// The volatile parameter is set to `true`, so it will not be optimized out.
606
    pub fn volatile_set_memory<T>(dst: *mut T, val: u8, count: usize);
607 608

    /// Perform a volatile load from the `src` pointer.
609
    pub fn volatile_load<T>(src: *const T) -> T;
610 611 612
    /// Perform a volatile store to the `dst` pointer.
    pub fn volatile_store<T>(dst: *mut T, val: T);

L
lucy 已提交
613
    /// Returns the square root of an `f32`
614
    pub fn sqrtf32(x: f32) -> f32;
L
lucy 已提交
615
    /// Returns the square root of an `f64`
616
    pub fn sqrtf64(x: f64) -> f64;
617

L
lucy 已提交
618
    /// Raises an `f32` to an integer power.
619
    pub fn powif32(a: f32, x: i32) -> f32;
L
lucy 已提交
620
    /// Raises an `f64` to an integer power.
621
    pub fn powif64(a: f64, x: i32) -> f64;
622

L
lucy 已提交
623
    /// Returns the sine of an `f32`.
624
    pub fn sinf32(x: f32) -> f32;
L
lucy 已提交
625
    /// Returns the sine of an `f64`.
626
    pub fn sinf64(x: f64) -> f64;
627

L
lucy 已提交
628
    /// Returns the cosine of an `f32`.
629
    pub fn cosf32(x: f32) -> f32;
L
lucy 已提交
630
    /// Returns the cosine of an `f64`.
631
    pub fn cosf64(x: f64) -> f64;
632

L
lucy 已提交
633
    /// Raises an `f32` to an `f32` power.
634
    pub fn powf32(a: f32, x: f32) -> f32;
L
lucy 已提交
635
    /// Raises an `f64` to an `f64` power.
636
    pub fn powf64(a: f64, x: f64) -> f64;
637

L
lucy 已提交
638
    /// Returns the exponential of an `f32`.
639
    pub fn expf32(x: f32) -> f32;
L
lucy 已提交
640
    /// Returns the exponential of an `f64`.
641
    pub fn expf64(x: f64) -> f64;
642

L
lucy 已提交
643
    /// Returns 2 raised to the power of an `f32`.
644
    pub fn exp2f32(x: f32) -> f32;
L
lucy 已提交
645
    /// Returns 2 raised to the power of an `f64`.
646
    pub fn exp2f64(x: f64) -> f64;
647

L
lucy 已提交
648
    /// Returns the natural logarithm of an `f32`.
649
    pub fn logf32(x: f32) -> f32;
L
lucy 已提交
650
    /// Returns the natural logarithm of an `f64`.
651
    pub fn logf64(x: f64) -> f64;
652

L
lucy 已提交
653
    /// Returns the base 10 logarithm of an `f32`.
654
    pub fn log10f32(x: f32) -> f32;
L
lucy 已提交
655
    /// Returns the base 10 logarithm of an `f64`.
656
    pub fn log10f64(x: f64) -> f64;
657

L
lucy 已提交
658
    /// Returns the base 2 logarithm of an `f32`.
659
    pub fn log2f32(x: f32) -> f32;
L
lucy 已提交
660
    /// Returns the base 2 logarithm of an `f64`.
661 662
    pub fn log2f64(x: f64) -> f64;

L
lucy 已提交
663
    /// Returns `a * b + c` for `f32` values.
664
    pub fn fmaf32(a: f32, b: f32, c: f32) -> f32;
L
lucy 已提交
665
    /// Returns `a * b + c` for `f64` values.
666
    pub fn fmaf64(a: f64, b: f64, c: f64) -> f64;
667

L
lucy 已提交
668
    /// Returns the absolute value of an `f32`.
669
    pub fn fabsf32(x: f32) -> f32;
L
lucy 已提交
670
    /// Returns the absolute value of an `f64`.
671
    pub fn fabsf64(x: f64) -> f64;
672

L
lucy 已提交
673
    /// Copies the sign from `y` to `x` for `f32` values.
674
    pub fn copysignf32(x: f32, y: f32) -> f32;
L
lucy 已提交
675
    /// Copies the sign from `y` to `x` for `f64` values.
676
    pub fn copysignf64(x: f64, y: f64) -> f64;
677

L
lucy 已提交
678
    /// Returns the largest integer less than or equal to an `f32`.
679
    pub fn floorf32(x: f32) -> f32;
L
lucy 已提交
680
    /// Returns the largest integer less than or equal to an `f64`.
681 682
    pub fn floorf64(x: f64) -> f64;

L
lucy 已提交
683
    /// Returns the smallest integer greater than or equal to an `f32`.
684
    pub fn ceilf32(x: f32) -> f32;
L
lucy 已提交
685
    /// Returns the smallest integer greater than or equal to an `f64`.
686
    pub fn ceilf64(x: f64) -> f64;
687

L
lucy 已提交
688
    /// Returns the integer part of an `f32`.
689
    pub fn truncf32(x: f32) -> f32;
L
lucy 已提交
690
    /// Returns the integer part of an `f64`.
691
    pub fn truncf64(x: f64) -> f64;
692

L
lucy 已提交
693 694
    /// Returns the nearest integer to an `f32`. May raise an inexact floating-point exception
    /// if the argument is not an integer.
695
    pub fn rintf32(x: f32) -> f32;
L
lucy 已提交
696 697
    /// Returns the nearest integer to an `f64`. May raise an inexact floating-point exception
    /// if the argument is not an integer.
698 699
    pub fn rintf64(x: f64) -> f64;

L
lucy 已提交
700
    /// Returns the nearest integer to an `f32`.
701
    pub fn nearbyintf32(x: f32) -> f32;
L
lucy 已提交
702
    /// Returns the nearest integer to an `f64`.
703 704
    pub fn nearbyintf64(x: f64) -> f64;

L
lucy 已提交
705
    /// Returns the nearest integer to an `f32`. Rounds half-way cases away from zero.
706
    pub fn roundf32(x: f32) -> f32;
L
lucy 已提交
707
    /// Returns the nearest integer to an `f64`. Rounds half-way cases away from zero.
708
    pub fn roundf64(x: f64) -> f64;
A
Alex Crichton 已提交
709

710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730
    /// Float addition that allows optimizations based on algebraic rules.
    /// May assume inputs are finite.
    pub fn fadd_fast<T>(a: T, b: T) -> T;

    /// Float subtraction that allows optimizations based on algebraic rules.
    /// May assume inputs are finite.
    pub fn fsub_fast<T>(a: T, b: T) -> T;

    /// Float multiplication that allows optimizations based on algebraic rules.
    /// May assume inputs are finite.
    pub fn fmul_fast<T>(a: T, b: T) -> T;

    /// Float division that allows optimizations based on algebraic rules.
    /// May assume inputs are finite.
    pub fn fdiv_fast<T>(a: T, b: T) -> T;

    /// Float remainder that allows optimizations based on algebraic rules.
    /// May assume inputs are finite.
    pub fn frem_fast<T>(a: T, b: T) -> T;


731 732
    /// Returns the number of bits set in an integer type `T`
    pub fn ctpop<T>(x: T) -> T;
733

734 735
    /// Returns the number of leading bits unset in an integer type `T`
    pub fn ctlz<T>(x: T) -> T;
736

737 738
    /// Returns the number of trailing bits unset in an integer type `T`
    pub fn cttz<T>(x: T) -> T;
739

740 741
    /// Reverses the bytes in an integer type `T`.
    pub fn bswap<T>(x: T) -> T;
742

743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759
    /// Performs checked integer addition.
    pub fn add_with_overflow<T>(x: T, y: T) -> (T, bool);

    /// Performs checked integer subtraction
    pub fn sub_with_overflow<T>(x: T, y: T) -> (T, bool);

    /// Performs checked integer multiplication
    pub fn mul_with_overflow<T>(x: T, y: T) -> (T, bool);

    /// Performs an unchecked division, resulting in undefined behavior
    /// where y = 0 or x = `T::min_value()` and y = -1
    pub fn unchecked_div<T>(x: T, y: T) -> T;
    /// Returns the remainder of an unchecked division, resulting in
    /// undefined behavior where y = 0 or x = `T::min_value()` and y = -1
    pub fn unchecked_rem<T>(x: T, y: T) -> T;

    /// Returns (a + b) mod 2^N, where N is the width of T in bits.
760
    pub fn overflowing_add<T>(a: T, b: T) -> T;
761
    /// Returns (a - b) mod 2^N, where N is the width of T in bits.
762
    pub fn overflowing_sub<T>(a: T, b: T) -> T;
763
    /// Returns (a * b) mod 2^N, where N is the width of T in bits.
764
    pub fn overflowing_mul<T>(a: T, b: T) -> T;
765

E
Eduard Burtescu 已提交
766 767 768
    /// Returns the value of the discriminant for the variant in 'v',
    /// cast to a `u64`; if `T` has no discriminant, returns 0.
    pub fn discriminant_value<T>(v: &T) -> u64;
769 770

    /// Rust's "try catch" construct which invokes the function pointer `f` with
771 772 773 774 775 776 777 778
    /// the data pointer `data`.
    ///
    /// The third pointer is a target-specific data pointer which is filled in
    /// with the specifics of the exception that occurred. For examples on Unix
    /// platforms this is a `*mut *mut T` which is filled in by the compiler and
    /// on MSVC it's `*mut [usize; 2]`. For more information see the compiler's
    /// source as well as std's catch implementation.
    pub fn try(f: fn(*mut u8), data: *mut u8, local_ptr: *mut u8) -> i32;
779
}