Add Unsafe<T> type
This commit is contained in:
parent
b85d5f1f9a
commit
710f13f0ad
|
@ -233,6 +233,8 @@ lets_do_this! {
|
|||
ShrTraitLangItem, "shr", shr_trait;
|
||||
IndexTraitLangItem, "index", index_trait;
|
||||
|
||||
UnsafeTypeLangItem, "unsafe", unsafe_type;
|
||||
|
||||
DerefTraitLangItem, "deref", deref_trait;
|
||||
DerefMutTraitLangItem, "deref_mut", deref_mut_trait;
|
||||
|
||||
|
|
|
@ -1878,7 +1878,8 @@ def_type_content_sets!(
|
|||
|
||||
// Things that are interior to the value (first nibble):
|
||||
InteriorUnsized = 0b0000_0000__0000_0000__0001,
|
||||
// InteriorAll = 0b0000_0000__0000_0000__1111,
|
||||
InteriorUnsafe = 0b0000_0000__0000_0000__0010,
|
||||
// InteriorAll = 0b00000000__00000000__1111,
|
||||
|
||||
// Things that are owned by the value (second and third nibbles):
|
||||
OwnsOwned = 0b0000_0000__0000_0001__0000,
|
||||
|
@ -2297,6 +2298,8 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
|
|||
tc | TC::OwnsAffine
|
||||
} else if Some(did) == cx.lang_items.no_share_bound() {
|
||||
tc | TC::ReachesNoShare
|
||||
} else if Some(did) == cx.lang_items.unsafe_type() {
|
||||
tc | TC::InteriorUnsafe
|
||||
} else {
|
||||
tc
|
||||
}
|
||||
|
|
|
@ -83,6 +83,7 @@
|
|||
#[cfg(test)] pub use kinds = realstd::kinds;
|
||||
#[cfg(test)] pub use ops = realstd::ops;
|
||||
#[cfg(test)] pub use cmp = realstd::cmp;
|
||||
#[cfg(test)] pub use ty = realstd::ty;
|
||||
|
||||
pub mod macros;
|
||||
|
||||
|
@ -138,6 +139,7 @@ pub mod gc;
|
|||
#[cfg(not(test))] pub mod kinds;
|
||||
#[cfg(not(test))] pub mod ops;
|
||||
#[cfg(not(test))] pub mod cmp;
|
||||
#[cfg(not(test))] pub mod ty;
|
||||
|
||||
|
||||
/* Common traits */
|
||||
|
@ -226,5 +228,6 @@ mod std {
|
|||
pub use rt;
|
||||
pub use str;
|
||||
pub use to_str;
|
||||
pub use ty;
|
||||
pub use unstable;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
// Copyright 2012-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.
|
||||
|
||||
//! Types dealing with unsafe actions.
|
||||
|
||||
use cast;
|
||||
use kinds::marker;
|
||||
|
||||
/// Unsafe type that wraps a type T and indicates unsafe interior operations on the
|
||||
/// wrapped type. Types with an `Unsafe<T>` field are considered to have an *unsafe
|
||||
/// interior*. The Unsafe type is the only legal way to obtain aliasable data that is
|
||||
/// considered mutable. In general, transmuting an &T type into an &mut T is considered
|
||||
/// undefined behavior.
|
||||
///
|
||||
/// Although it is possible to put an Unsafe<T> into static item, it is not permitted to
|
||||
/// take the address of the static item if the item is not declared as mutable. This rule
|
||||
/// exists because immutable static items are stored in read-only memory, and thus any
|
||||
/// attempt to mutate their interior can cause segfaults. Immutable static items containing
|
||||
/// Unsafe<T> instances are still useful as read-only initializers, however, so we do not
|
||||
/// forbid them altogether.
|
||||
///
|
||||
/// Types like `Cell` and `RefCell` use this type to wrap their internal data.
|
||||
///
|
||||
/// Unsafe doesn't opt-out from any kind, instead, types with an `Unsafe` interior
|
||||
/// are expected to opt-out from kinds themselves.
|
||||
///
|
||||
/// # Example:
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::ty::Unsafe;
|
||||
/// use std::kinds::marker;
|
||||
///
|
||||
/// struct NotThreadSafe<T> {
|
||||
/// value: Unsafe<T>,
|
||||
/// marker1: marker::NoShare
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// **NOTE:** Unsafe<T> fields are public to allow static initializers. It is not recommended
|
||||
/// to access its fields directly, `get` should be used instead.
|
||||
#[cfg(not(stage0))]
|
||||
#[lang="unsafe"]
|
||||
pub struct Unsafe<T> {
|
||||
/// Wrapped value
|
||||
value: T,
|
||||
|
||||
/// Invariance marker
|
||||
marker1: marker::InvariantType<T>
|
||||
}
|
||||
|
||||
/// Unsafe type for stage0
|
||||
#[cfg(stage0)]
|
||||
pub struct Unsafe<T> {
|
||||
/// Wrapped value
|
||||
value: T,
|
||||
|
||||
/// Invariance marker
|
||||
marker1: marker::InvariantType<T>
|
||||
}
|
||||
|
||||
|
||||
impl<T> Unsafe<T> {
|
||||
|
||||
/// Static constructor
|
||||
pub fn new(value: T) -> Unsafe<T> {
|
||||
Unsafe{value: value, marker1: marker::InvariantType}
|
||||
}
|
||||
|
||||
/// Gets a mutable pointer to the wrapped value
|
||||
#[inline]
|
||||
pub unsafe fn get(&self) -> *mut T { cast::transmute(&self.value) }
|
||||
}
|
Loading…
Reference in New Issue