2014-06-28 13:57:36 -07:00
|
|
|
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
2012-12-10 15:44:02 -08:00
|
|
|
// 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.
|
|
|
|
|
2014-05-07 12:12:24 -07:00
|
|
|
// FIXME: talk about offset, copy_memory, copy_nonoverlapping_memory
|
|
|
|
|
2014-06-25 12:47:34 -07:00
|
|
|
//! Operations on unsafe pointers, `*const T`, and `*mut T`.
|
2014-04-07 14:00:19 -07:00
|
|
|
//!
|
2014-05-22 09:44:54 -07:00
|
|
|
//! Working with unsafe pointers in Rust is uncommon,
|
|
|
|
//! typically limited to a few patterns.
|
2014-04-07 14:00:19 -07:00
|
|
|
//!
|
|
|
|
//! Use the [`null` function](fn.null.html) to create null pointers,
|
|
|
|
//! the [`is_null`](trait.RawPtr.html#tymethod.is_null)
|
|
|
|
//! and [`is_not_null`](trait.RawPtr.html#method.is_not_null)
|
|
|
|
//! methods of the [`RawPtr` trait](trait.RawPtr.html) to check for null.
|
|
|
|
//! The `RawPtr` trait is imported by the prelude, so `is_null` etc.
|
2014-05-22 09:44:54 -07:00
|
|
|
//! work everywhere. The `RawPtr` also defines the `offset` method,
|
|
|
|
//! for pointer math.
|
2014-04-07 14:00:19 -07:00
|
|
|
//!
|
|
|
|
//! # Common ways to create unsafe pointers
|
|
|
|
//!
|
|
|
|
//! ## 1. Coerce a reference (`&T`) or mutable reference (`&mut T`).
|
|
|
|
//!
|
|
|
|
//! ```
|
|
|
|
//! let my_num: int = 10;
|
2014-06-25 12:47:34 -07:00
|
|
|
//! let my_num_ptr: *const int = &my_num;
|
2014-04-07 14:00:19 -07:00
|
|
|
//! let mut my_speed: int = 88;
|
|
|
|
//! let my_speed_ptr: *mut int = &mut my_speed;
|
|
|
|
//! ```
|
|
|
|
//!
|
|
|
|
//! This does not take ownership of the original allocation
|
|
|
|
//! and requires no resource management later,
|
|
|
|
//! but you must not use the pointer after its lifetime.
|
|
|
|
//!
|
2014-05-05 18:56:44 -07:00
|
|
|
//! ## 2. Transmute an owned box (`Box<T>`).
|
2014-04-07 14:00:19 -07:00
|
|
|
//!
|
|
|
|
//! The `transmute` function takes, by value, whatever it's given
|
|
|
|
//! and returns it as whatever type is requested, as long as the
|
2014-06-25 12:47:34 -07:00
|
|
|
//! types are the same size. Because `Box<T>` and `*mut T` have the same
|
2014-04-07 14:00:19 -07:00
|
|
|
//! representation they can be trivially,
|
|
|
|
//! though unsafely, transformed from one type to the other.
|
|
|
|
//!
|
|
|
|
//! ```
|
core: Remove the cast module
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]
2014-05-09 10:34:51 -07:00
|
|
|
//! use std::mem;
|
2014-04-07 14:00:19 -07:00
|
|
|
//!
|
|
|
|
//! unsafe {
|
2014-05-05 18:56:44 -07:00
|
|
|
//! let my_num: Box<int> = box 10;
|
2014-06-25 12:47:34 -07:00
|
|
|
//! let my_num: *const int = mem::transmute(my_num);
|
2014-05-05 18:56:44 -07:00
|
|
|
//! let my_speed: Box<int> = box 88;
|
core: Remove the cast module
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]
2014-05-09 10:34:51 -07:00
|
|
|
//! let my_speed: *mut int = mem::transmute(my_speed);
|
2014-04-07 14:00:19 -07:00
|
|
|
//!
|
2014-05-05 18:56:44 -07:00
|
|
|
//! // By taking ownership of the original `Box<T>` though
|
2014-04-07 14:00:19 -07:00
|
|
|
//! // we are obligated to transmute it back later to be destroyed.
|
core: Remove the cast module
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]
2014-05-09 10:34:51 -07:00
|
|
|
//! drop(mem::transmute::<_, Box<int>>(my_speed));
|
|
|
|
//! drop(mem::transmute::<_, Box<int>>(my_num));
|
2014-04-07 14:00:19 -07:00
|
|
|
//! }
|
|
|
|
//! ```
|
|
|
|
//!
|
|
|
|
//! Note that here the call to `drop` is for clarity - it indicates
|
|
|
|
//! that we are done with the given value and it should be destroyed.
|
|
|
|
//!
|
|
|
|
//! ## 3. Get it from C.
|
|
|
|
//!
|
|
|
|
//! ```
|
|
|
|
//! extern crate libc;
|
|
|
|
//!
|
|
|
|
//! use std::mem;
|
|
|
|
//!
|
|
|
|
//! fn main() {
|
|
|
|
//! unsafe {
|
|
|
|
//! let my_num: *mut int = libc::malloc(mem::size_of::<int>() as libc::size_t) as *mut int;
|
|
|
|
//! if my_num.is_null() {
|
2014-10-09 15:17:22 -04:00
|
|
|
//! panic!("failed to allocate memory");
|
2014-04-07 14:00:19 -07:00
|
|
|
//! }
|
|
|
|
//! libc::free(my_num as *mut libc::c_void);
|
|
|
|
//! }
|
|
|
|
//! }
|
|
|
|
//! ```
|
|
|
|
//!
|
|
|
|
//! Usually you wouldn't literally use `malloc` and `free` from Rust,
|
|
|
|
//! but C APIs hand out a lot of pointers generally, so are a common source
|
|
|
|
//! of unsafe pointers in Rust.
|
2012-03-10 00:04:09 -08:00
|
|
|
|
core: Remove the cast module
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]
2014-05-09 10:34:51 -07:00
|
|
|
use mem;
|
2013-07-02 12:47:32 -07:00
|
|
|
use clone::Clone;
|
2014-04-30 20:17:50 -07:00
|
|
|
use intrinsics;
|
2014-11-28 11:57:41 -05:00
|
|
|
use option::Option;
|
|
|
|
use option::Option::{Some, None};
|
2013-07-17 21:32:49 +02:00
|
|
|
|
2014-12-12 18:44:22 +01:00
|
|
|
use cmp::{PartialEq, Eq, Ord, PartialOrd, Equiv};
|
2014-11-28 11:57:41 -05:00
|
|
|
use cmp::Ordering;
|
|
|
|
use cmp::Ordering::{Less, Equal, Greater};
|
2013-02-28 11:57:33 -05:00
|
|
|
|
2014-07-09 22:24:23 -07:00
|
|
|
pub use intrinsics::copy_memory;
|
|
|
|
pub use intrinsics::copy_nonoverlapping_memory;
|
|
|
|
pub use intrinsics::set_memory;
|
|
|
|
|
2014-05-01 20:02:11 -05:00
|
|
|
/// Create a null pointer.
|
2014-04-07 14:00:19 -07:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::ptr;
|
|
|
|
///
|
2014-06-25 12:47:34 -07:00
|
|
|
/// let p: *const int = ptr::null();
|
2014-04-07 14:00:19 -07:00
|
|
|
/// assert!(p.is_null());
|
|
|
|
/// ```
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2014-05-29 17:40:18 -07:00
|
|
|
#[unstable = "may need a different name after pending changes to pointer types"]
|
2014-06-25 12:47:34 -07:00
|
|
|
pub fn null<T>() -> *const T { 0 as *const T }
|
2012-04-03 21:56:16 -07:00
|
|
|
|
2014-04-07 14:00:19 -07:00
|
|
|
/// Create an unsafe mutable null pointer.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::ptr;
|
|
|
|
///
|
2014-09-14 20:27:36 -07:00
|
|
|
/// let p: *mut int = ptr::null_mut();
|
2014-04-07 14:00:19 -07:00
|
|
|
/// assert!(p.is_null());
|
|
|
|
/// ```
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2014-05-29 17:40:18 -07:00
|
|
|
#[unstable = "may need a different name after pending changes to pointer types"]
|
2014-09-14 15:57:55 -07:00
|
|
|
pub fn null_mut<T>() -> *mut T { 0 as *mut T }
|
2012-09-14 16:12:18 -07:00
|
|
|
|
2014-04-07 14:00:19 -07:00
|
|
|
/// Zeroes out `count * size_of::<T>` bytes of memory at `dst`
|
2013-06-20 15:13:22 -04:00
|
|
|
#[inline]
|
2014-05-29 17:40:18 -07:00
|
|
|
#[experimental = "uncertain about naming and semantics"]
|
|
|
|
#[allow(experimental)]
|
2013-06-20 15:13:22 -04:00
|
|
|
pub unsafe fn zero_memory<T>(dst: *mut T, count: uint) {
|
|
|
|
set_memory(dst, 0, count);
|
|
|
|
}
|
|
|
|
|
2014-04-07 14:00:19 -07:00
|
|
|
/// Swap the values at two mutable locations of the same type, without
|
|
|
|
/// deinitialising either. They may overlap.
|
2013-05-31 10:21:29 -04:00
|
|
|
#[inline]
|
2014-05-29 17:40:18 -07:00
|
|
|
#[unstable]
|
2014-02-14 18:42:01 -05:00
|
|
|
pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
|
2013-05-31 10:21:29 -04:00
|
|
|
// Give ourselves some scratch space to work with
|
2014-05-23 20:53:56 -07:00
|
|
|
let mut tmp: T = mem::uninitialized();
|
2013-05-31 10:21:29 -04:00
|
|
|
let t: *mut T = &mut tmp;
|
|
|
|
|
|
|
|
// Perform the swap
|
2014-01-31 14:01:59 -08:00
|
|
|
copy_nonoverlapping_memory(t, &*x, 1);
|
|
|
|
copy_memory(x, &*y, 1); // `x` and `y` may overlap
|
|
|
|
copy_nonoverlapping_memory(y, &*t, 1);
|
2013-05-31 10:21:29 -04:00
|
|
|
|
|
|
|
// y and t now point to the same thing, but we need to completely forget `tmp`
|
|
|
|
// because it's no longer relevant.
|
core: Remove the cast module
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]
2014-05-09 10:34:51 -07:00
|
|
|
mem::forget(tmp);
|
2013-05-31 10:21:29 -04:00
|
|
|
}
|
|
|
|
|
2014-04-07 14:00:19 -07:00
|
|
|
/// Replace the value at a mutable location with a new one, returning the old
|
|
|
|
/// value, without deinitialising either.
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2014-05-29 17:40:18 -07:00
|
|
|
#[unstable]
|
2014-02-14 18:42:01 -05:00
|
|
|
pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
|
core: Remove the cast module
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]
2014-05-09 10:34:51 -07:00
|
|
|
mem::swap(mem::transmute(dest), &mut src); // cannot overlap
|
2013-05-31 10:21:29 -04:00
|
|
|
src
|
|
|
|
}
|
|
|
|
|
2014-04-07 14:00:19 -07:00
|
|
|
/// Reads the value from `*src` and returns it.
|
2013-06-20 15:13:22 -04:00
|
|
|
#[inline(always)]
|
2014-05-29 17:40:18 -07:00
|
|
|
#[unstable]
|
2014-06-25 12:47:34 -07:00
|
|
|
pub unsafe fn read<T>(src: *const T) -> T {
|
2014-05-23 20:53:56 -07:00
|
|
|
let mut tmp: T = mem::uninitialized();
|
2013-07-09 15:22:18 -04:00
|
|
|
copy_nonoverlapping_memory(&mut tmp, src, 1);
|
2013-06-20 15:13:22 -04:00
|
|
|
tmp
|
|
|
|
}
|
|
|
|
|
2014-04-07 14:00:19 -07:00
|
|
|
/// Reads the value from `*src` and nulls it out.
|
|
|
|
/// This currently prevents destructors from executing.
|
2013-06-20 15:13:22 -04:00
|
|
|
#[inline(always)]
|
2014-05-29 17:40:18 -07:00
|
|
|
#[experimental]
|
|
|
|
#[allow(experimental)]
|
2014-02-14 18:42:01 -05:00
|
|
|
pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
|
2013-06-20 15:13:22 -04:00
|
|
|
// Copy the data out from `dest`:
|
2014-02-14 18:42:01 -05:00
|
|
|
let tmp = read(&*dest);
|
2013-06-20 15:13:22 -04:00
|
|
|
|
|
|
|
// Now zero out `dest`:
|
|
|
|
zero_memory(dest, 1);
|
|
|
|
|
|
|
|
tmp
|
|
|
|
}
|
|
|
|
|
2014-05-29 17:40:18 -07:00
|
|
|
/// Unsafely overwrite a memory location with the given value without destroying
|
|
|
|
/// the old value.
|
|
|
|
///
|
|
|
|
/// This operation is unsafe because it does not destroy the previous value
|
|
|
|
/// contained at the location `dst`. This could leak allocations or resources,
|
|
|
|
/// so care must be taken to previously deallocate the value at `dst`.
|
|
|
|
#[inline]
|
|
|
|
#[unstable]
|
|
|
|
pub unsafe fn write<T>(dst: *mut T, src: T) {
|
|
|
|
intrinsics::move_val_init(&mut *dst, src)
|
|
|
|
}
|
|
|
|
|
2014-05-22 09:44:54 -07:00
|
|
|
/// Methods on raw pointers
|
2013-06-03 13:50:29 -04:00
|
|
|
pub trait RawPtr<T> {
|
2014-02-14 18:42:01 -05:00
|
|
|
/// Returns the null pointer.
|
2013-08-02 21:41:06 -07:00
|
|
|
fn null() -> Self;
|
2014-08-20 13:06:34 -07:00
|
|
|
|
2014-02-14 18:42:01 -05:00
|
|
|
/// Returns true if the pointer is equal to the null pointer.
|
2013-06-23 20:44:11 -07:00
|
|
|
fn is_null(&self) -> bool;
|
2014-08-20 13:06:34 -07:00
|
|
|
|
2014-02-14 18:42:01 -05:00
|
|
|
/// Returns true if the pointer is not equal to the null pointer.
|
|
|
|
fn is_not_null(&self) -> bool { !self.is_null() }
|
2014-08-20 13:06:34 -07:00
|
|
|
|
2014-02-14 18:42:01 -05:00
|
|
|
/// Returns the value of this pointer (ie, the address it points to)
|
2013-08-02 21:41:06 -07:00
|
|
|
fn to_uint(&self) -> uint;
|
2014-08-20 13:06:34 -07:00
|
|
|
|
|
|
|
/// Returns `None` if the pointer is null, or else returns a reference to the
|
|
|
|
/// value wrapped in `Some`.
|
2014-02-14 18:42:01 -05:00
|
|
|
///
|
|
|
|
/// # Safety Notes
|
|
|
|
///
|
2014-08-20 13:06:34 -07:00
|
|
|
/// While this method and its mutable counterpart are useful for null-safety,
|
|
|
|
/// it is important to note that this is still an unsafe operation because
|
|
|
|
/// the returned value could be pointing to invalid memory.
|
|
|
|
unsafe fn as_ref<'a>(&self) -> Option<&'a T>;
|
|
|
|
|
2014-02-14 18:42:01 -05:00
|
|
|
/// Calculates the offset from a pointer. The offset *must* be in-bounds of
|
2014-02-20 14:58:46 +01:00
|
|
|
/// the object, or one-byte-past-the-end. `count` is in units of T; e.g. a
|
|
|
|
/// `count` of 3 represents a pointer offset of `3 * sizeof::<T>()` bytes.
|
2013-08-08 22:22:52 -07:00
|
|
|
unsafe fn offset(self, count: int) -> Self;
|
2012-07-11 12:45:54 -07:00
|
|
|
}
|
|
|
|
|
2014-08-20 13:06:34 -07:00
|
|
|
/// Methods on mutable raw pointers
|
|
|
|
pub trait RawMutPtr<T>{
|
|
|
|
/// Returns `None` if the pointer is null, or else returns a mutable reference
|
|
|
|
/// to the value wrapped in `Some`. As with `as_ref`, this is unsafe because
|
|
|
|
/// it cannot verify the validity of the returned pointer.
|
|
|
|
unsafe fn as_mut<'a>(&self) -> Option<&'a mut T>;
|
|
|
|
}
|
|
|
|
|
2014-06-25 12:47:34 -07:00
|
|
|
impl<T> RawPtr<T> for *const T {
|
2013-08-02 21:41:06 -07:00
|
|
|
#[inline]
|
2014-06-25 12:47:34 -07:00
|
|
|
fn null() -> *const T { null() }
|
2013-08-02 21:41:06 -07:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-08-02 21:41:06 -07:00
|
|
|
fn is_null(&self) -> bool { *self == RawPtr::null() }
|
2012-04-15 21:46:29 -07:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2014-02-14 18:42:01 -05:00
|
|
|
fn to_uint(&self) -> uint { *self as uint }
|
2013-08-02 21:41:06 -07:00
|
|
|
|
|
|
|
#[inline]
|
2014-06-25 12:47:34 -07:00
|
|
|
unsafe fn offset(self, count: int) -> *const T {
|
|
|
|
intrinsics::offset(self, count)
|
|
|
|
}
|
2012-10-01 14:34:53 -07:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2014-08-20 13:06:34 -07:00
|
|
|
unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
|
2014-02-14 18:42:01 -05:00
|
|
|
if self.is_null() {
|
|
|
|
None
|
|
|
|
} else {
|
2014-05-18 11:21:47 -07:00
|
|
|
Some(&**self)
|
2013-05-19 14:08:27 +10:00
|
|
|
}
|
|
|
|
}
|
2012-04-15 21:46:29 -07:00
|
|
|
}
|
|
|
|
|
2013-06-03 13:50:29 -04:00
|
|
|
impl<T> RawPtr<T> for *mut T {
|
2013-08-02 21:41:06 -07:00
|
|
|
#[inline]
|
2014-09-14 20:27:36 -07:00
|
|
|
fn null() -> *mut T { null_mut() }
|
2013-08-02 21:41:06 -07:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-08-02 21:41:06 -07:00
|
|
|
fn is_null(&self) -> bool { *self == RawPtr::null() }
|
2012-11-07 16:24:29 +10:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2014-02-14 18:42:01 -05:00
|
|
|
fn to_uint(&self) -> uint { *self as uint }
|
2013-08-02 21:41:06 -07:00
|
|
|
|
|
|
|
#[inline]
|
2014-04-30 20:17:50 -07:00
|
|
|
unsafe fn offset(self, count: int) -> *mut T {
|
2014-06-25 12:47:34 -07:00
|
|
|
intrinsics::offset(self as *const T, count) as *mut T
|
2014-04-30 20:17:50 -07:00
|
|
|
}
|
2012-11-07 16:24:29 +10:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2014-08-20 13:06:34 -07:00
|
|
|
unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
|
2014-02-14 18:42:01 -05:00
|
|
|
if self.is_null() {
|
|
|
|
None
|
|
|
|
} else {
|
2014-05-18 11:21:47 -07:00
|
|
|
Some(&**self)
|
2013-05-19 14:08:27 +10:00
|
|
|
}
|
|
|
|
}
|
2012-11-07 16:24:29 +10:00
|
|
|
}
|
|
|
|
|
2014-08-20 13:06:34 -07:00
|
|
|
impl<T> RawMutPtr<T> for *mut T {
|
|
|
|
#[inline]
|
|
|
|
unsafe fn as_mut<'a>(&self) -> Option<&'a mut T> {
|
|
|
|
if self.is_null() {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some(&mut **self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-27 17:33:22 -07:00
|
|
|
// Equality for pointers
|
2014-06-25 12:47:34 -07:00
|
|
|
impl<T> PartialEq for *const T {
|
2013-09-12 01:01:59 -04:00
|
|
|
#[inline]
|
2014-06-25 12:47:34 -07:00
|
|
|
fn eq(&self, other: &*const T) -> bool {
|
2013-09-12 01:01:59 -04:00
|
|
|
*self == *other
|
|
|
|
}
|
|
|
|
#[inline]
|
2014-06-25 12:47:34 -07:00
|
|
|
fn ne(&self, other: &*const T) -> bool { !self.eq(other) }
|
2013-09-12 01:01:59 -04:00
|
|
|
}
|
|
|
|
|
2014-06-25 12:47:34 -07:00
|
|
|
impl<T> Eq for *const T {}
|
2014-03-22 16:30:45 -04:00
|
|
|
|
2014-05-29 17:45:07 -07:00
|
|
|
impl<T> PartialEq for *mut T {
|
2013-09-12 01:01:59 -04:00
|
|
|
#[inline]
|
|
|
|
fn eq(&self, other: &*mut T) -> bool {
|
|
|
|
*self == *other
|
|
|
|
}
|
|
|
|
#[inline]
|
|
|
|
fn ne(&self, other: &*mut T) -> bool { !self.eq(other) }
|
|
|
|
}
|
|
|
|
|
2014-05-31 10:43:52 -07:00
|
|
|
impl<T> Eq for *mut T {}
|
2014-03-22 16:30:45 -04:00
|
|
|
|
2013-08-02 21:41:06 -07:00
|
|
|
// Equivalence for pointers
|
2014-11-26 23:50:12 -05:00
|
|
|
#[allow(deprecated)]
|
|
|
|
#[deprecated = "Use overloaded `core::cmp::PartialEq`"]
|
2014-06-25 12:47:34 -07:00
|
|
|
impl<T> Equiv<*mut T> for *const T {
|
2013-08-02 21:41:06 -07:00
|
|
|
fn equiv(&self, other: &*mut T) -> bool {
|
|
|
|
self.to_uint() == other.to_uint()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-26 23:50:12 -05:00
|
|
|
#[allow(deprecated)]
|
|
|
|
#[deprecated = "Use overloaded `core::cmp::PartialEq`"]
|
2014-06-25 12:47:34 -07:00
|
|
|
impl<T> Equiv<*const T> for *mut T {
|
|
|
|
fn equiv(&self, other: &*const T) -> bool {
|
2013-08-02 21:41:06 -07:00
|
|
|
self.to_uint() == other.to_uint()
|
|
|
|
}
|
2012-09-19 18:00:26 -07:00
|
|
|
}
|
2012-08-27 16:26:35 -07:00
|
|
|
|
2014-06-25 12:47:34 -07:00
|
|
|
impl<T> Clone for *const T {
|
2014-05-29 17:40:18 -07:00
|
|
|
#[inline]
|
2014-06-25 12:47:34 -07:00
|
|
|
fn clone(&self) -> *const T {
|
2014-05-29 17:40:18 -07:00
|
|
|
*self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> Clone for *mut T {
|
|
|
|
#[inline]
|
|
|
|
fn clone(&self) -> *mut T {
|
|
|
|
*self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-21 09:31:02 -04:00
|
|
|
// Equality for extern "C" fn pointers
|
|
|
|
mod externfnpointers {
|
core: Remove the cast module
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]
2014-05-09 10:34:51 -07:00
|
|
|
use mem;
|
2014-05-29 17:45:07 -07:00
|
|
|
use cmp::PartialEq;
|
2013-08-21 09:31:02 -04:00
|
|
|
|
2014-05-29 17:45:07 -07:00
|
|
|
impl<_R> PartialEq for extern "C" fn() -> _R {
|
2013-08-21 09:31:02 -04:00
|
|
|
#[inline]
|
|
|
|
fn eq(&self, other: &extern "C" fn() -> _R) -> bool {
|
2014-06-25 12:47:34 -07:00
|
|
|
let self_: *const () = unsafe { mem::transmute(*self) };
|
|
|
|
let other_: *const () = unsafe { mem::transmute(*other) };
|
2013-08-21 09:31:02 -04:00
|
|
|
self_ == other_
|
|
|
|
}
|
|
|
|
}
|
|
|
|
macro_rules! fnptreq(
|
|
|
|
($($p:ident),*) => {
|
2014-05-29 17:45:07 -07:00
|
|
|
impl<_R,$($p),*> PartialEq for extern "C" fn($($p),*) -> _R {
|
2013-08-21 09:31:02 -04:00
|
|
|
#[inline]
|
|
|
|
fn eq(&self, other: &extern "C" fn($($p),*) -> _R) -> bool {
|
2014-06-25 12:47:34 -07:00
|
|
|
let self_: *const () = unsafe { mem::transmute(*self) };
|
|
|
|
|
|
|
|
let other_: *const () = unsafe { mem::transmute(*other) };
|
2013-08-21 09:31:02 -04:00
|
|
|
self_ == other_
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
fnptreq!(A)
|
|
|
|
fnptreq!(A,B)
|
|
|
|
fnptreq!(A,B,C)
|
|
|
|
fnptreq!(A,B,C,D)
|
|
|
|
fnptreq!(A,B,C,D,E)
|
|
|
|
}
|
|
|
|
|
2012-08-27 16:26:35 -07:00
|
|
|
// Comparison for pointers
|
2014-12-12 18:44:22 +01:00
|
|
|
impl<T> Ord for *const T {
|
2014-06-17 23:25:51 -07:00
|
|
|
#[inline]
|
2014-12-12 18:44:22 +01:00
|
|
|
fn cmp(&self, other: &*const T) -> Ordering {
|
2014-06-17 23:25:51 -07:00
|
|
|
if self < other {
|
2014-12-12 18:44:22 +01:00
|
|
|
Less
|
2014-06-17 23:25:51 -07:00
|
|
|
} else if self == other {
|
2014-12-12 18:44:22 +01:00
|
|
|
Equal
|
2014-06-17 23:25:51 -07:00
|
|
|
} else {
|
2014-12-12 18:44:22 +01:00
|
|
|
Greater
|
2014-06-17 23:25:51 -07:00
|
|
|
}
|
|
|
|
}
|
2014-12-12 18:44:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> PartialOrd for *const T {
|
|
|
|
#[inline]
|
|
|
|
fn partial_cmp(&self, other: &*const T) -> Option<Ordering> {
|
|
|
|
Some(self.cmp(other))
|
|
|
|
}
|
2014-06-17 23:25:51 -07:00
|
|
|
|
2013-09-12 01:01:59 -04:00
|
|
|
#[inline]
|
2014-06-25 12:47:34 -07:00
|
|
|
fn lt(&self, other: &*const T) -> bool { *self < *other }
|
2014-06-17 23:25:51 -07:00
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn le(&self, other: &*const T) -> bool { *self <= *other }
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn gt(&self, other: &*const T) -> bool { *self > *other }
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn ge(&self, other: &*const T) -> bool { *self >= *other }
|
2013-09-12 01:01:59 -04:00
|
|
|
}
|
|
|
|
|
2014-12-12 18:44:22 +01:00
|
|
|
impl<T> Ord for *mut T {
|
2014-06-17 23:25:51 -07:00
|
|
|
#[inline]
|
2014-12-12 18:44:22 +01:00
|
|
|
fn cmp(&self, other: &*mut T) -> Ordering {
|
2014-06-17 23:25:51 -07:00
|
|
|
if self < other {
|
2014-12-12 18:44:22 +01:00
|
|
|
Less
|
2014-06-17 23:25:51 -07:00
|
|
|
} else if self == other {
|
2014-12-12 18:44:22 +01:00
|
|
|
Equal
|
2014-06-17 23:25:51 -07:00
|
|
|
} else {
|
2014-12-12 18:44:22 +01:00
|
|
|
Greater
|
2014-06-17 23:25:51 -07:00
|
|
|
}
|
|
|
|
}
|
2014-12-12 18:44:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> PartialOrd for *mut T {
|
|
|
|
#[inline]
|
|
|
|
fn partial_cmp(&self, other: &*mut T) -> Option<Ordering> {
|
|
|
|
Some(self.cmp(other))
|
|
|
|
}
|
2014-06-17 23:25:51 -07:00
|
|
|
|
2013-09-12 01:01:59 -04:00
|
|
|
#[inline]
|
2014-04-30 20:17:50 -07:00
|
|
|
fn lt(&self, other: &*mut T) -> bool { *self < *other }
|
2014-06-17 23:25:51 -07:00
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn le(&self, other: &*mut T) -> bool { *self <= *other }
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn gt(&self, other: &*mut T) -> bool { *self > *other }
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn ge(&self, other: &*mut T) -> bool { *self >= *other }
|
2013-09-12 01:01:59 -04:00
|
|
|
}
|
librustc: Make `Copy` opt-in.
This change makes the compiler no longer infer whether types (structures
and enumerations) implement the `Copy` trait (and thus are implicitly
copyable). Rather, you must implement `Copy` yourself via `impl Copy for
MyType {}`.
A new warning has been added, `missing_copy_implementations`, to warn
you if a non-generic public type has been added that could have
implemented `Copy` but didn't.
For convenience, you may *temporarily* opt out of this behavior by using
`#![feature(opt_out_copy)]`. Note though that this feature gate will never be
accepted and will be removed by the time that 1.0 is released, so you should
transition your code away from using it.
This breaks code like:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
Change this code to:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
impl Copy for Point2D {}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
This is the backwards-incompatible part of #13231.
Part of RFC #3.
[breaking-change]
2014-12-05 17:01:33 -08:00
|
|
|
|