diff options
| author | pravic <[email protected]> | 2016-04-12 17:47:49 +0300 |
|---|---|---|
| committer | pravic <[email protected]> | 2016-04-12 17:47:49 +0300 |
| commit | 91d227b219446d3a8b13f5bf7eb87bfc78a8b339 (patch) | |
| tree | 0e438aefd2b3cf07354a68595d5aa4ed73f81f15 /libcore/ptr.rs | |
| parent | add native import libraries (diff) | |
| download | kmd-env-rs-91d227b219446d3a8b13f5bf7eb87bfc78a8b339.tar.xz kmd-env-rs-91d227b219446d3a8b13f5bf7eb87bfc78a8b339.zip | |
add libcore from 2016-04-11 nightly
Diffstat (limited to 'libcore/ptr.rs')
| -rw-r--r-- | libcore/ptr.rs | 744 |
1 files changed, 744 insertions, 0 deletions
diff --git a/libcore/ptr.rs b/libcore/ptr.rs new file mode 100644 index 0000000..42aef3a --- /dev/null +++ b/libcore/ptr.rs @@ -0,0 +1,744 @@ +// Copyright 2012-2014 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. + +// FIXME: talk about offset, copy_memory, copy_nonoverlapping_memory + +//! Raw, unsafe pointers, `*const T`, and `*mut T`. +//! +//! *[See also the pointer primitive types](../../std/primitive.pointer.html).* + +#![stable(feature = "rust1", since = "1.0.0")] + +use clone::Clone; +use intrinsics; +use ops::{CoerceUnsized, Deref}; +use fmt; +use hash; +use option::Option::{self, Some, None}; +use marker::{Copy, PhantomData, Send, Sized, Sync, Unsize}; +use mem; +use nonzero::NonZero; + +use cmp::{PartialEq, Eq, Ord, PartialOrd}; +use cmp::Ordering::{self, Less, Equal, Greater}; + +// FIXME #19649: intrinsic docs don't render, so these have no docs :( + +#[stable(feature = "rust1", since = "1.0.0")] +pub use intrinsics::copy_nonoverlapping; + +#[stable(feature = "rust1", since = "1.0.0")] +pub use intrinsics::copy; + +#[stable(feature = "rust1", since = "1.0.0")] +pub use intrinsics::write_bytes; + +#[stable(feature = "drop_in_place", since = "1.8.0")] +pub use intrinsics::drop_in_place; + +/// Creates a null raw pointer. +/// +/// # Examples +/// +/// ``` +/// use std::ptr; +/// +/// let p: *const i32 = ptr::null(); +/// assert!(p.is_null()); +/// ``` +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub const fn null<T>() -> *const T { 0 as *const T } + +/// Creates a null mutable raw pointer. +/// +/// # Examples +/// +/// ``` +/// use std::ptr; +/// +/// let p: *mut i32 = ptr::null_mut(); +/// assert!(p.is_null()); +/// ``` +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub const fn null_mut<T>() -> *mut T { 0 as *mut T } + +/// Swaps the values at two mutable locations of the same type, without +/// deinitializing either. They may overlap, unlike `mem::swap` which is +/// otherwise equivalent. +/// +/// # Safety +/// +/// This is only unsafe because it accepts a raw pointer. +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub unsafe fn swap<T>(x: *mut T, y: *mut T) { + // Give ourselves some scratch space to work with + let mut tmp: T = mem::uninitialized(); + + // Perform the swap + copy_nonoverlapping(x, &mut tmp, 1); + copy(y, x, 1); // `x` and `y` may overlap + copy_nonoverlapping(&tmp, y, 1); + + // y and t now point to the same thing, but we need to completely forget `tmp` + // because it's no longer relevant. + mem::forget(tmp); +} + +/// Replaces the value at `dest` with `src`, returning the old +/// value, without dropping either. +/// +/// # Safety +/// +/// This is only unsafe because it accepts a raw pointer. +/// Otherwise, this operation is identical to `mem::replace`. +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T { + mem::swap(&mut *dest, &mut src); // cannot overlap + src +} + +/// Reads the value from `src` without moving it. This leaves the +/// memory in `src` unchanged. +/// +/// # Safety +/// +/// Beyond accepting a raw pointer, this is unsafe because it semantically +/// moves the value out of `src` without preventing further usage of `src`. +/// If `T` is not `Copy`, then care must be taken to ensure that the value at +/// `src` is not used before the data is overwritten again (e.g. with `write`, +/// `zero_memory`, or `copy_memory`). Note that `*src = foo` counts as a use +/// because it will attempt to drop the value previously at `*src`. +#[inline(always)] +#[stable(feature = "rust1", since = "1.0.0")] +pub unsafe fn read<T>(src: *const T) -> T { + let mut tmp: T = mem::uninitialized(); + copy_nonoverlapping(src, &mut tmp, 1); + tmp +} + +#[allow(missing_docs)] +#[inline(always)] +#[unstable(feature = "filling_drop", + reason = "may play a larger role in std::ptr future extensions", + issue = "5016")] +pub unsafe fn read_and_drop<T>(dest: *mut T) -> T { + // Copy the data out from `dest`: + let tmp = read(&*dest); + + // Now mark `dest` as dropped: + write_bytes(dest, mem::POST_DROP_U8, 1); + + tmp +} + +/// Overwrites a memory location with the given value without reading or +/// dropping the old value. +/// +/// # Safety +/// +/// This operation is marked unsafe because it accepts a raw pointer. +/// +/// It does not drop the contents of `dst`. This is safe, but it could leak +/// allocations or resources, so care must be taken not to overwrite an object +/// that should be dropped. +/// +/// This is appropriate for initializing uninitialized memory, or overwriting +/// memory that has previously been `read` from. +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub unsafe fn write<T>(dst: *mut T, src: T) { + intrinsics::move_val_init(&mut *dst, src) +} + +/// Performs a volatile read of the value from `src` without moving it. This +/// leaves the memory in `src` unchanged. +/// +/// Volatile operations are intended to act on I/O memory, and are guaranteed +/// to not be elided or reordered by the compiler across other volatile +/// operations. See the LLVM documentation on [[volatile]]. +/// +/// [volatile]: http://llvm.org/docs/LangRef.html#volatile-memory-accesses +/// +/// # Safety +/// +/// Beyond accepting a raw pointer, this is unsafe because it semantically +/// moves the value out of `src` without preventing further usage of `src`. +/// If `T` is not `Copy`, then care must be taken to ensure that the value at +/// `src` is not used before the data is overwritten again (e.g. with `write`, +/// `zero_memory`, or `copy_memory`). Note that `*src = foo` counts as a use +/// because it will attempt to drop the value previously at `*src`. +#[inline] +#[unstable(feature = "volatile", reason = "recently added", issue = "31756")] +pub unsafe fn read_volatile<T>(src: *const T) -> T { + intrinsics::volatile_load(src) +} + +/// Performs a volatile write of a memory location with the given value without +/// reading or dropping the old value. +/// +/// Volatile operations are intended to act on I/O memory, and are guaranteed +/// to not be elided or reordered by the compiler across other volatile +/// operations. See the LLVM documentation on [[volatile]]. +/// +/// [volatile]: http://llvm.org/docs/LangRef.html#volatile-memory-accesses +/// +/// # Safety +/// +/// This operation is marked unsafe because it accepts a raw pointer. +/// +/// It does not drop the contents of `dst`. This is safe, but it could leak +/// allocations or resources, so care must be taken not to overwrite an object +/// that should be dropped. +/// +/// This is appropriate for initializing uninitialized memory, or overwriting +/// memory that has previously been `read` from. +#[inline] +#[unstable(feature = "volatile", reason = "recently added", issue = "31756")] +pub unsafe fn write_volatile<T>(dst: *mut T, src: T) { + intrinsics::volatile_store(dst, src); +} + +#[lang = "const_ptr"] +impl<T: ?Sized> *const T { + /// Returns true if the pointer is null. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let s: &str = "Follow the rabbit"; + /// let ptr: *const u8 = s.as_ptr(); + /// assert!(!ptr.is_null()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn is_null(self) -> bool where T: Sized { + self == null() + } + + /// Returns `None` if the pointer is null, or else returns a reference to + /// the value wrapped in `Some`. + /// + /// # Safety + /// + /// 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. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ```ignore + /// let val: *const u8 = &10u8 as *const u8; + /// + /// unsafe { + /// if let Some(val_back) = val.as_ref() { + /// println!("We got back the value: {}!", val_back); + /// } + /// } + /// ``` + #[unstable(feature = "ptr_as_ref", + reason = "Option is not clearly the right return type, and we \ + may want to tie the return lifetime to a borrow of \ + the raw pointer", + issue = "27780")] + #[inline] + pub unsafe fn as_ref<'a>(&self) -> Option<&'a T> where T: Sized { + if self.is_null() { + None + } else { + Some(&**self) + } + } + + /// Calculates the offset from a pointer. `count` is in units of T; e.g. a + /// `count` of 3 represents a pointer offset of `3 * sizeof::<T>()` bytes. + /// + /// # 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. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let s: &str = "123"; + /// let ptr: *const u8 = s.as_ptr(); + /// + /// unsafe { + /// println!("{}", *ptr.offset(1) as char); + /// println!("{}", *ptr.offset(2) as char); + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub unsafe fn offset(self, count: isize) -> *const T where T: Sized { + intrinsics::offset(self, count) + } +} + +#[lang = "mut_ptr"] +impl<T: ?Sized> *mut T { + /// Returns true if the pointer is null. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let mut s = [1, 2, 3]; + /// let ptr: *mut u32 = s.as_mut_ptr(); + /// assert!(!ptr.is_null()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn is_null(self) -> bool where T: Sized { + self == null_mut() + } + + /// Returns `None` if the pointer is null, or else returns a reference to + /// the value wrapped in `Some`. + /// + /// # Safety + /// + /// 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. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ```ignore + /// let val: *mut u8 = &mut 10u8 as *mut u8; + /// + /// unsafe { + /// if let Some(val_back) = val.as_ref() { + /// println!("We got back the value: {}!", val_back); + /// } + /// } + /// ``` + #[unstable(feature = "ptr_as_ref", + reason = "Option is not clearly the right return type, and we \ + may want to tie the return lifetime to a borrow of \ + the raw pointer", + issue = "27780")] + #[inline] + pub unsafe fn as_ref<'a>(&self) -> Option<&'a T> where T: Sized { + if self.is_null() { + None + } else { + Some(&**self) + } + } + + /// Calculates the offset from a pointer. `count` is in units of T; e.g. a + /// `count` of 3 represents a pointer offset of `3 * sizeof::<T>()` bytes. + /// + /// # Safety + /// + /// The offset must be in-bounds of the object, or one-byte-past-the-end. + /// Otherwise `offset` invokes Undefined Behavior, regardless of whether + /// the pointer is used. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let mut s = [1, 2, 3]; + /// let ptr: *mut u32 = s.as_mut_ptr(); + /// + /// unsafe { + /// println!("{}", *ptr.offset(1)); + /// println!("{}", *ptr.offset(2)); + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub unsafe fn offset(self, count: isize) -> *mut T where T: Sized { + intrinsics::offset(self, count) as *mut T + } + + /// Returns `None` if the pointer is null, or else returns a mutable + /// reference to the value wrapped in `Some`. + /// + /// # Safety + /// + /// As with `as_ref`, this is unsafe because it cannot verify the validity + /// of the returned pointer. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let mut s = [1, 2, 3]; + /// let ptr: *mut u32 = s.as_mut_ptr(); + /// ``` + #[unstable(feature = "ptr_as_ref", + reason = "return value does not necessarily convey all possible \ + information", + issue = "27780")] + #[inline] + pub unsafe fn as_mut<'a>(&self) -> Option<&'a mut T> where T: Sized { + if self.is_null() { + None + } else { + Some(&mut **self) + } + } +} + +// Equality for pointers +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> PartialEq for *const T { + #[inline] + fn eq(&self, other: &*const T) -> bool { *self == *other } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> Eq for *const T {} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> PartialEq for *mut T { + #[inline] + fn eq(&self, other: &*mut T) -> bool { *self == *other } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> Eq for *mut T {} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> Clone for *const T { + #[inline] + fn clone(&self) -> *const T { + *self + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> Clone for *mut T { + #[inline] + fn clone(&self) -> *mut T { + *self + } +} + +// Impls for function pointers +macro_rules! fnptr_impls_safety_abi { + ($FnTy: ty, $($Arg: ident),*) => { + #[stable(feature = "rust1", since = "1.0.0")] + impl<Ret, $($Arg),*> Clone for $FnTy { + #[inline] + fn clone(&self) -> Self { + *self + } + } + + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl<Ret, $($Arg),*> PartialEq for $FnTy { + #[inline] + fn eq(&self, other: &Self) -> bool { + *self as usize == *other as usize + } + } + + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl<Ret, $($Arg),*> Eq for $FnTy {} + + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl<Ret, $($Arg),*> PartialOrd for $FnTy { + #[inline] + fn partial_cmp(&self, other: &Self) -> Option<Ordering> { + (*self as usize).partial_cmp(&(*other as usize)) + } + } + + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl<Ret, $($Arg),*> Ord for $FnTy { + #[inline] + fn cmp(&self, other: &Self) -> Ordering { + (*self as usize).cmp(&(*other as usize)) + } + } + + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl<Ret, $($Arg),*> hash::Hash for $FnTy { + fn hash<HH: hash::Hasher>(&self, state: &mut HH) { + state.write_usize(*self as usize) + } + } + + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl<Ret, $($Arg),*> fmt::Pointer for $FnTy { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Pointer::fmt(&(*self as *const ()), f) + } + } + + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl<Ret, $($Arg),*> fmt::Debug for $FnTy { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Pointer::fmt(&(*self as *const ()), f) + } + } + } +} + +macro_rules! fnptr_impls_args { + ($($Arg: ident),*) => { + fnptr_impls_safety_abi! { extern "Rust" fn($($Arg),*) -> Ret, $($Arg),* } + fnptr_impls_safety_abi! { extern "C" fn($($Arg),*) -> Ret, $($Arg),* } + fnptr_impls_safety_abi! { unsafe extern "Rust" fn($($Arg),*) -> Ret, $($Arg),* } + fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),*) -> Ret, $($Arg),* } + } +} + +fnptr_impls_args! { } +fnptr_impls_args! { A } +fnptr_impls_args! { A, B } +fnptr_impls_args! { A, B, C } +fnptr_impls_args! { A, B, C, D } +fnptr_impls_args! { A, B, C, D, E } +fnptr_impls_args! { A, B, C, D, E, F } +fnptr_impls_args! { A, B, C, D, E, F, G } +fnptr_impls_args! { A, B, C, D, E, F, G, H } +fnptr_impls_args! { A, B, C, D, E, F, G, H, I } +fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J } +fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K } +fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K, L } + +// Comparison for pointers +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> Ord for *const T { + #[inline] + fn cmp(&self, other: &*const T) -> Ordering { + if self < other { + Less + } else if self == other { + Equal + } else { + Greater + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> PartialOrd for *const T { + #[inline] + fn partial_cmp(&self, other: &*const T) -> Option<Ordering> { + Some(self.cmp(other)) + } + + #[inline] + fn lt(&self, other: &*const T) -> bool { *self < *other } + + #[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 } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> Ord for *mut T { + #[inline] + fn cmp(&self, other: &*mut T) -> Ordering { + if self < other { + Less + } else if self == other { + Equal + } else { + Greater + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> PartialOrd for *mut T { + #[inline] + fn partial_cmp(&self, other: &*mut T) -> Option<Ordering> { + Some(self.cmp(other)) + } + + #[inline] + fn lt(&self, other: &*mut T) -> bool { *self < *other } + + #[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 } +} + +/// A wrapper around a raw non-null `*mut T` that indicates that the possessor +/// of this wrapper owns the referent. This in turn implies that the +/// `Unique<T>` is `Send`/`Sync` if `T` is `Send`/`Sync`, unlike a raw +/// `*mut T` (which conveys no particular ownership semantics). It +/// also implies that the referent of the pointer should not be +/// modified without a unique path to the `Unique` reference. Useful +/// for building abstractions like `Vec<T>` or `Box<T>`, which +/// internally use raw pointers to manage the memory that they own. +#[allow(missing_debug_implementations)] +#[unstable(feature = "unique", reason = "needs an RFC to flesh out design", + issue = "27730")] +pub struct Unique<T: ?Sized> { + pointer: NonZero<*const T>, + // NOTE: this marker has no consequences for variance, but is necessary + // for dropck to understand that we logically own a `T`. + // + // For details, see: + // https://github.com/rust-lang/rfcs/blob/master/text/0769-sound-generic-drop.md#phantom-data + _marker: PhantomData<T>, +} + +/// `Unique` pointers are `Send` if `T` is `Send` because the data they +/// reference is unaliased. Note that this aliasing invariant is +/// unenforced by the type system; the abstraction using the +/// `Unique` must enforce it. +#[unstable(feature = "unique", issue = "27730")] +unsafe impl<T: Send + ?Sized> Send for Unique<T> { } + +/// `Unique` pointers are `Sync` if `T` is `Sync` because the data they +/// reference is unaliased. Note that this aliasing invariant is +/// unenforced by the type system; the abstraction using the +/// `Unique` must enforce it. +#[unstable(feature = "unique", issue = "27730")] +unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { } + +#[unstable(feature = "unique", issue = "27730")] +impl<T: ?Sized> Unique<T> { + /// Creates a new `Unique`. + /// + /// # Safety + /// + /// `ptr` must be non-null. + pub const unsafe fn new(ptr: *mut T) -> Unique<T> { + Unique { pointer: NonZero::new(ptr), _marker: PhantomData } + } + + /// Dereferences the content. + pub unsafe fn get(&self) -> &T { + &**self.pointer + } + + /// Mutably dereferences the content. + pub unsafe fn get_mut(&mut self) -> &mut T { + &mut ***self + } +} + +#[unstable(feature = "unique", issue = "27730")] +impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> { } + +#[unstable(feature = "unique", issue= "27730")] +impl<T:?Sized> Deref for Unique<T> { + type Target = *mut T; + + #[inline] + fn deref(&self) -> &*mut T { + unsafe { mem::transmute(&*self.pointer) } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T> fmt::Pointer for Unique<T> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Pointer::fmt(&*self.pointer, f) + } +} + +/// A wrapper around a raw non-null `*mut T` that indicates that the possessor +/// of this wrapper has shared ownership of the referent. Useful for +/// building abstractions like `Rc<T>` or `Arc<T>`, which internally +/// use raw pointers to manage the memory that they own. +#[allow(missing_debug_implementations)] +#[unstable(feature = "shared", reason = "needs an RFC to flesh out design", + issue = "27730")] +pub struct Shared<T: ?Sized> { + pointer: NonZero<*const T>, + // NOTE: this marker has no consequences for variance, but is necessary + // for dropck to understand that we logically own a `T`. + // + // For details, see: + // https://github.com/rust-lang/rfcs/blob/master/text/0769-sound-generic-drop.md#phantom-data + _marker: PhantomData<T>, +} + +/// `Shared` pointers are not `Send` because the data they reference may be aliased. +// NB: This impl is unnecessary, but should provide better error messages. +#[unstable(feature = "shared", issue = "27730")] +impl<T: ?Sized> !Send for Shared<T> { } + +/// `Shared` pointers are not `Sync` because the data they reference may be aliased. +// NB: This impl is unnecessary, but should provide better error messages. +#[unstable(feature = "shared", issue = "27730")] +impl<T: ?Sized> !Sync for Shared<T> { } + +#[unstable(feature = "shared", issue = "27730")] +impl<T: ?Sized> Shared<T> { + /// Creates a new `Shared`. + /// + /// # Safety + /// + /// `ptr` must be non-null. + pub unsafe fn new(ptr: *mut T) -> Self { + Shared { pointer: NonZero::new(ptr), _marker: PhantomData } + } +} + +#[unstable(feature = "shared", issue = "27730")] +impl<T: ?Sized> Clone for Shared<T> { + fn clone(&self) -> Self { + *self + } +} + +#[unstable(feature = "shared", issue = "27730")] +impl<T: ?Sized> Copy for Shared<T> { } + +#[unstable(feature = "shared", issue = "27730")] +impl<T: ?Sized, U: ?Sized> CoerceUnsized<Shared<U>> for Shared<T> where T: Unsize<U> { } + +#[unstable(feature = "shared", issue = "27730")] +impl<T: ?Sized> Deref for Shared<T> { + type Target = *mut T; + + #[inline] + fn deref(&self) -> &*mut T { + unsafe { mem::transmute(&*self.pointer) } + } +} + +#[unstable(feature = "shared", issue = "27730")] +impl<T> fmt::Pointer for Shared<T> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Pointer::fmt(&*self.pointer, f) + } +} |