From 710f13f0ad8f41c4c3d5de96b0d96ee4dea4c8b2 Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Mon, 10 Mar 2014 22:55:15 +0100 Subject: [PATCH] Add Unsafe type --- src/librustc/middle/lang_items.rs | 2 + src/librustc/middle/ty.rs | 5 +- src/libstd/lib.rs | 3 ++ src/libstd/ty.rs | 79 +++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 src/libstd/ty.rs 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 @@ pub fn collect_language_items(krate: &ast::Crate, 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 @@ mod TC { // 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 @@ fn apply_lang_items(cx: &ctxt, 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 @@ #[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 or the MIT license +// , 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` 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 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 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 { +/// value: Unsafe, +/// marker1: marker::NoShare +/// } +/// ``` +/// +/// **NOTE:** Unsafe 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 { + /// Wrapped value + value: T, + + /// Invariance marker + marker1: marker::InvariantType +} + +/// Unsafe type for stage0 +#[cfg(stage0)] +pub struct Unsafe { + /// Wrapped value + value: T, + + /// Invariance marker + marker1: marker::InvariantType +} + + +impl Unsafe { + + /// Static constructor + pub fn new(value: T) -> Unsafe { + 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) } +} -- GitLab