about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlavio Percoco <flaper87@gmail.com>2014-03-10 22:55:15 +0100
committerFlavio Percoco <flaper87@gmail.com>2014-03-20 10:16:55 +0100
commit710f13f0ad8f41c4c3d5de96b0d96ee4dea4c8b2 (patch)
tree8d621031b1769b61afca403aa6e507fb9c83356e
parentb85d5f1f9a873e706bd17be843cd54f55dcff211 (diff)
downloadrust-710f13f0ad8f41c4c3d5de96b0d96ee4dea4c8b2.tar.gz
rust-710f13f0ad8f41c4c3d5de96b0d96ee4dea4c8b2.zip
Add Unsafe<T> type
-rw-r--r--src/librustc/middle/lang_items.rs2
-rw-r--r--src/librustc/middle/ty.rs5
-rw-r--r--src/libstd/lib.rs3
-rw-r--r--src/libstd/ty.rs79
4 files changed, 88 insertions, 1 deletions
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 4e16683bcba..8ef4991be13 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -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;
 
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 00ccadc68c6..cf974b2f1fa 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -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
         }
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index c6a1d710a52..73be83c254d 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -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;
 }
diff --git a/src/libstd/ty.rs b/src/libstd/ty.rs
new file mode 100644
index 00000000000..e17e28a84fd
--- /dev/null
+++ b/src/libstd/ty.rs
@@ -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) }
+}