summary refs log tree commit diff
path: root/src/libstd/ty.rs
blob: ae8be25205d41aeaebf503771edf6357216b7929 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// 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.
#[lang="unsafe"]
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) }

    /// Unwraps the value
    #[inline]
    pub unsafe fn unwrap(self) -> T { self.value }
}