(index<- )        ./libcore/kinds.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Fri May  9 13:02:28 2014
   1  // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
   2  // file at the top-level directory of this distribution and at
   3  // http://rust-lang.org/COPYRIGHT.
   4  //
   5  // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
   6  // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
   7  // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
   8  // option. This file may not be copied, modified, or distributed
   9  // except according to those terms.
  10  
  11  /*!
  12  Primitive traits representing basic 'kinds' of types
  13  
  14  Rust types can be classified in various useful ways according to
  15  intrinsic properties of the type. These classifications, often called
  16  'kinds', are represented as traits.
  17  
  18  They cannot be implemented by user code, but are instead implemented
  19  by the compiler automatically for the types to which they apply.
  20  
  21  */
  22  
  23  /// Types able to be transferred across task boundaries.
  24  #[lang="send"]
  25  pub trait Send {
  26      // empty.
  27  }
  28  
  29  /// Types with a constant size known at compile-time.
  30  #[lang="sized"]
  31  pub trait Sized {
  32      // Empty.
  33  }
  34  
  35  /// Types that can be copied by simply copying bits (i.e. `memcpy`).
  36  #[lang="copy"]
  37  pub trait Copy {
  38      // Empty.
  39  }
  40  
  41  /// Types that can be safely shared between tasks when aliased.
  42  ///
  43  /// The precise definition is: a type `T` is `Share` if `&T` is
  44  /// thread-safe. In other words, there is no possibility of data races
  45  /// when passing `&T` references between tasks.
  46  ///
  47  /// As one would expect, primitive types like `u8` and `f64` are all
  48  /// `Share`, and so are simple aggregate types containing them (like
  49  /// tuples, structs and enums). More instances of basic `Share` types
  50  /// include "immutable" types like `&T` and those with simple
  51  /// inherited mutability, such as `Box<T>`, `Vec<T>` and most other
  52  /// collection types. (Generic parameters need to be `Share` for their
  53  /// container to be `Share`.)
  54  ///
  55  /// A somewhat surprising consequence of the definition is `&mut T` is
  56  /// `Share` (if `T` is `Share`) even though it seems that it might
  57  /// provide unsynchronised mutation. The trick is a mutable reference
  58  /// stored in an aliasable reference (that is, `& &mut T`) becomes
  59  /// read-only, as if it were a `& &T`, hence there is no risk of a data
  60  /// race.
  61  ///
  62  /// Types that are not `Share` are those that have "interior
  63  /// mutability" in a non-thread-safe way, such as `Cell` and `RefCell`
  64  /// in `std::cell`. These types allow for mutation of their contents
  65  /// even when in an immutable, aliasable slot, e.g. the contents of
  66  /// `&Cell<T>` can be `.set`, and do not ensure data races are
  67  /// impossible, hence they cannot be `Share`. A higher level example
  68  /// of a non-`Share` type is the reference counted pointer
  69  /// `std::rc::Rc`, because any reference `&Rc<T>` can clone a new
  70  /// reference, which modifies the reference counts in a non-atomic
  71  /// way.
  72  ///
  73  /// For cases when one does need thread-safe interior mutability,
  74  /// types like the atomics in `std::sync` and `Mutex` & `RWLock` in
  75  /// the `sync` crate do ensure that any mutation cannot cause data
  76  /// races.  Hence these types are `Share`.
  77  ///
  78  /// Users writing their own types with interior mutability (or anything
  79  /// else that is not thread-safe) should use the `NoShare` marker type
  80  /// (from `std::kinds::marker`) to ensure that the compiler doesn't
  81  /// consider the user-defined type to be `Share`.  Any types with
  82  /// interior mutability must also use the `std::ty::Unsafe` wrapper
  83  /// around the value(s) which can be mutated when behind a `&`
  84  /// reference; not doing this is undefined behaviour (for example,
  85  /// `transmute`-ing from `&T` to `&mut T` is illegal).
  86  #[lang="share"]
  87  pub trait Share {
  88      // Empty
  89  }
  90  
  91  /// Marker types are special types that are used with unsafe code to
  92  /// inform the compiler of special constraints. Marker types should
  93  /// only be needed when you are creating an abstraction that is
  94  /// implemented using unsafe code. In that case, you may want to embed
  95  /// some of the marker types below into your type.
  96  pub mod marker {
  97  
  98      /// A marker type whose type parameter `T` is considered to be
  99      /// covariant with respect to the type itself. This is (typically)
 100      /// used to indicate that an instance of the type `T` is being stored
 101      /// into memory and read from, even though that may not be apparent.
 102      ///
 103      /// For more information about variance, refer to this Wikipedia
 104      /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
 105      ///
 106      /// *Note:* It is very unusual to have to add a covariant constraint.
 107      /// If you are not sure, you probably want to use `InvariantType`.
 108      ///
 109      /// # Example
 110      ///
 111      /// Given a struct `S` that includes a type parameter `T`
 112      /// but does not actually *reference* that type parameter:
 113      ///
 114      /// ```ignore
 115      /// use std::cast;
 116      ///
 117      /// struct S<T> { x: *() }
 118      /// fn get<T>(s: &S<T>) -> T {
 119      ///    unsafe {
 120      ///        let x: *T = cast::transmute(s.x);
 121      ///        *x
 122      ///    }
 123      /// }
 124      /// ```
 125      ///
 126      /// The type system would currently infer that the value of
 127      /// the type parameter `T` is irrelevant, and hence a `S<int>` is
 128      /// a subtype of `S<~[int]>` (or, for that matter, `S<U>` for
 129      /// any `U`). But this is incorrect because `get()` converts the
 130      /// `*()` into a `*T` and reads from it. Therefore, we should include the
 131      /// a marker field `CovariantType<T>` to inform the type checker that
 132      /// `S<T>` is a subtype of `S<U>` if `T` is a subtype of `U`
 133      /// (for example, `S<&'static int>` is a subtype of `S<&'a int>`
 134      /// for some lifetime `'a`, but not the other way around).
 135      #[lang="covariant_type"]
 136      #[deriving(Eq,Clone)]
 137      pub struct CovariantType<T>;
 138  
 139      /// A marker type whose type parameter `T` is considered to be
 140      /// contravariant with respect to the type itself. This is (typically)
 141      /// used to indicate that an instance of the type `T` will be consumed
 142      /// (but not read from), even though that may not be apparent.
 143      ///
 144      /// For more information about variance, refer to this Wikipedia
 145      /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
 146      ///
 147      /// *Note:* It is very unusual to have to add a contravariant constraint.
 148      /// If you are not sure, you probably want to use `InvariantType`.
 149      ///
 150      /// # Example
 151      ///
 152      /// Given a struct `S` that includes a type parameter `T`
 153      /// but does not actually *reference* that type parameter:
 154      ///
 155      /// ```
 156      /// use std::cast;
 157      ///
 158      /// struct S<T> { x: *() }
 159      /// fn get<T>(s: &S<T>, v: T) {
 160      ///    unsafe {
 161      ///        let x: fn(T) = cast::transmute(s.x);
 162      ///        x(v)
 163      ///    }
 164      /// }
 165      /// ```
 166      ///
 167      /// The type system would currently infer that the value of
 168      /// the type parameter `T` is irrelevant, and hence a `S<int>` is
 169      /// a subtype of `S<~[int]>` (or, for that matter, `S<U>` for
 170      /// any `U`). But this is incorrect because `get()` converts the
 171      /// `*()` into a `fn(T)` and then passes a value of type `T` to it.
 172      ///
 173      /// Supplying a `ContravariantType` marker would correct the
 174      /// problem, because it would mark `S` so that `S<T>` is only a
 175      /// subtype of `S<U>` if `U` is a subtype of `T`; given that the
 176      /// function requires arguments of type `T`, it must also accept
 177      /// arguments of type `U`, hence such a conversion is safe.
 178      #[lang="contravariant_type"]
 179      #[deriving(Eq,Clone)]
 180      pub struct ContravariantType<T>;
 181  
 182      /// A marker type whose type parameter `T` is considered to be
 183      /// invariant with respect to the type itself. This is (typically)
 184      /// used to indicate that instances of the type `T` may be read or
 185      /// written, even though that may not be apparent.
 186      ///
 187      /// For more information about variance, refer to this Wikipedia
 188      /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
 189      ///
 190      /// # Example
 191      ///
 192      /// The Cell type is an example which uses unsafe code to achieve
 193      /// "interior" mutability:
 194      ///
 195      /// ```
 196      /// pub struct Cell<T> { value: T }
 197      /// # fn main() {}
 198      /// ```
 199      ///
 200      /// The type system would infer that `value` is only read here and
 201      /// never written, but in fact `Cell` uses unsafe code to achieve
 202      /// interior mutability.
 203      #[lang="invariant_type"]
 204      #[deriving(Eq,Clone)]
 205      pub struct InvariantType<T>;
 206  
 207      /// As `CovariantType`, but for lifetime parameters. Using
 208      /// `CovariantLifetime<'a>` indicates that it is ok to substitute
 209      /// a *longer* lifetime for `'a` than the one you originally
 210      /// started with (e.g., you could convert any lifetime `'foo` to
 211      /// `'static`). You almost certainly want `ContravariantLifetime`
 212      /// instead, or possibly `InvariantLifetime`. The only case where
 213      /// it would be appropriate is that you have a (type-casted, and
 214      /// hence hidden from the type system) function pointer with a
 215      /// signature like `fn(&'a T)` (and no other uses of `'a`). In
 216      /// this case, it is ok to substitute a larger lifetime for `'a`
 217      /// (e.g., `fn(&'static T)`), because the function is only
 218      /// becoming more selective in terms of what it accepts as
 219      /// argument.
 220      ///
 221      /// For more information about variance, refer to this Wikipedia
 222      /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
 223      #[lang="covariant_lifetime"]
 224      #[deriving(Eq,Clone)]
 225      pub struct CovariantLifetime<'a>;
 226  
 227      /// As `ContravariantType`, but for lifetime parameters. Using
 228      /// `ContravariantLifetime<'a>` indicates that it is ok to
 229      /// substitute a *shorter* lifetime for `'a` than the one you
 230      /// originally started with (e.g., you could convert `'static` to
 231      /// any lifetime `'foo`). This is appropriate for cases where you
 232      /// have an unsafe pointer that is actually a pointer into some
 233      /// memory with lifetime `'a`, and thus you want to limit the
 234      /// lifetime of your data structure to `'a`. An example of where
 235      /// this is used is the iterator for vectors.
 236      ///
 237      /// For more information about variance, refer to this Wikipedia
 238      /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
 239      #[lang="contravariant_lifetime"]
 240      #[deriving(Eq,Clone)]
 241      pub struct ContravariantLifetime<'a>;
 242  
 243      /// As `InvariantType`, but for lifetime parameters. Using
 244      /// `InvariantLifetime<'a>` indicates that it is not ok to
 245      /// substitute any other lifetime for `'a` besides its original
 246      /// value. This is appropriate for cases where you have an unsafe
 247      /// pointer that is actually a pointer into memory with lifetime `'a`,
 248      /// and this pointer is itself stored in an inherently mutable
 249      /// location (such as a `Cell`).
 250      #[lang="invariant_lifetime"]
 251      #[deriving(Eq,Clone)]
 252      pub struct InvariantLifetime<'a>;
 253  
 254      /// A type which is considered "not sendable", meaning that it cannot
 255      /// be safely sent between tasks, even if it is owned. This is
 256      /// typically embedded in other types, such as `Gc`, to ensure that
 257      /// their instances remain thread-local.
 258      #[lang="no_send_bound"]
 259      #[deriving(Eq,Clone)]
 260      pub struct NoSend;
 261  
 262      /// A type which is considered "not POD", meaning that it is not
 263      /// implicitly copyable. This is typically embedded in other types to
 264      /// ensure that they are never copied, even if they lack a destructor.
 265      #[lang="no_copy_bound"]
 266      #[deriving(Eq,Clone)]
 267      pub struct NoCopy;
 268  
 269      /// A type which is considered "not sharable", meaning that
 270      /// its contents are not threadsafe, hence they cannot be
 271      /// shared between tasks.
 272      #[lang="no_share_bound"]
 273      #[deriving(Eq,Clone)]
 274      pub struct NoShare;
 275  
 276      /// A type which is considered managed by the GC. This is typically
 277      /// embedded in other types.
 278      #[lang="managed_bound"]
 279      #[deriving(Eq,Clone)]
 280      pub struct Managed;
 281  }


libcore/kinds.rs:260:4-260:4 -struct- definition:
    pub struct NoSend;
    /// A type which is considered "not POD", meaning that it is not
    /// implicitly copyable. This is typically embedded in other types to
references:- 5
258:     #[lang="no_send_bound"]
259:     #[deriving(Eq,Clone)]
260:     pub struct NoSend;


libcore/kinds.rs:137:4-137:4 -struct- definition:
    pub struct CovariantType<T>;
    /// A marker type whose type parameter `T` is considered to be
    /// contravariant with respect to the type itself. This is (typically)
references:- 5
135:     #[lang="covariant_type"]
136:     #[deriving(Eq,Clone)]
137:     pub struct CovariantType<T>;


libcore/kinds.rs:205:4-205:4 -struct- definition:
    pub struct InvariantType<T>;
    /// As `CovariantType`, but for lifetime parameters. Using
    /// `CovariantLifetime<'a>` indicates that it is ok to substitute
references:- 6
203:     #[lang="invariant_type"]
204:     #[deriving(Eq,Clone)]
205:     pub struct InvariantType<T>;
libcore/ty.rs:
53:     /// Invariance marker
54:     pub marker1: marker::InvariantType<T>
55: }


libcore/kinds.rs:267:4-267:4 -struct- definition:
    pub struct NoCopy;
    /// A type which is considered "not sharable", meaning that
    /// its contents are not threadsafe, hence they cannot be
references:- 7
265:     #[lang="no_copy_bound"]
266:     #[deriving(Eq,Clone)]
267:     pub struct NoCopy;
libcore/cell.rs:
65:     borrow: Cell<BorrowFlag>,
66:     nocopy: marker::NoCopy,
67:     noshare: marker::NoShare,
libcore/slice.rs:
1267:     marker: marker::ContravariantLifetime<'a>,
1268:     marker2: marker::NoCopy
1269: }


libcore/kinds.rs:280:4-280:4 -struct- definition:
    pub struct Managed;
}

references:- 5
278:     #[lang="managed_bound"]
279:     #[deriving(Eq,Clone)]
280:     pub struct Managed;


libcore/kinds.rs:36:15-36:15 -trait- definition:
pub trait Copy {
    // Empty.
}
references:- 4
libcore/cell.rs:
56: impl<T:Eq + Copy> Eq for Cell<T> {
57:     fn eq(&self, other: &Cell<T>) -> bool {
libcore/num/mod.rs:
260: /// may be useful for systems programming.
261: pub trait Primitive: Copy
262:                    + Clone


libcore/kinds.rs:241:4-241:4 -struct- definition:
    pub struct ContravariantLifetime<'a>;
    /// As `InvariantType`, but for lifetime parameters. Using
    /// `InvariantLifetime<'a>` indicates that it is not ok to
references:- 7
239:     #[lang="contravariant_lifetime"]
240:     #[deriving(Eq,Clone)]
241:     pub struct ContravariantLifetime<'a>;
libcore/slice.rs:
1266:     end: *mut T,
1267:     marker: marker::ContravariantLifetime<'a>,
1268:     marker2: marker::NoCopy


libcore/kinds.rs:274:4-274:4 -struct- definition:
    pub struct NoShare;
    /// A type which is considered managed by the GC. This is typically
    /// embedded in other types.
references:- 7
272:     #[lang="no_share_bound"]
273:     #[deriving(Eq,Clone)]
274:     pub struct NoShare;
libcore/cell.rs:
66:     nocopy: marker::NoCopy,
67:     noshare: marker::NoShare,
68: }
libcore/kinds.rs:
272:     #[lang="no_share_bound"]
273:     #[deriving(Eq,Clone)]
274:     pub struct NoShare;


libcore/kinds.rs:180:4-180:4 -struct- definition:
    pub struct ContravariantType<T>;
    /// A marker type whose type parameter `T` is considered to be
    /// invariant with respect to the type itself. This is (typically)
references:- 5
178:     #[lang="contravariant_type"]
179:     #[deriving(Eq,Clone)]
180:     pub struct ContravariantType<T>;


libcore/kinds.rs:252:4-252:4 -struct- definition:
    pub struct InvariantLifetime<'a>;
    /// A type which is considered "not sendable", meaning that it cannot
    /// be safely sent between tasks, even if it is owned. This is
references:- 5
250:     #[lang="invariant_lifetime"]
251:     #[deriving(Eq,Clone)]
252:     pub struct InvariantLifetime<'a>;


libcore/kinds.rs:225:4-225:4 -struct- definition:
    pub struct CovariantLifetime<'a>;
    /// As `ContravariantType`, but for lifetime parameters. Using
    /// `ContravariantLifetime<'a>` indicates that it is ok to
references:- 5
223:     #[lang="covariant_lifetime"]
224:     #[deriving(Eq,Clone)]
225:     pub struct CovariantLifetime<'a>;