]> git.proxmox.com Git - rustc.git/blame - src/libcore/ops/place.rs
New upstream version 1.21.0+dfsg1
[rustc.git] / src / libcore / ops / place.rs
CommitLineData
041b39d2
XL
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/// Both `PLACE <- EXPR` and `box EXPR` desugar into expressions
12/// that allocate an intermediate "place" that holds uninitialized
13/// state. The desugaring evaluates EXPR, and writes the result at
14/// the address returned by the `pointer` method of this trait.
15///
16/// A `Place` can be thought of as a special representation for a
17/// hypothetical `&uninit` reference (which Rust cannot currently
18/// express directly). That is, it represents a pointer to
19/// uninitialized storage.
20///
21/// The client is responsible for two steps: First, initializing the
22/// payload (it can access its address via `pointer`). Second,
23/// converting the agent to an instance of the owning pointer, via the
24/// appropriate `finalize` method (see the `InPlace`.
25///
26/// If evaluating EXPR fails, then it is up to the destructor for the
27/// implementation of Place to clean up any intermediate state
28/// (e.g. deallocate box storage, pop a stack, etc).
29#[unstable(feature = "placement_new_protocol", issue = "27779")]
30pub trait Place<Data: ?Sized> {
31 /// Returns the address where the input value will be written.
32 /// Note that the data at this address is generally uninitialized,
33 /// and thus one should use `ptr::write` for initializing it.
34 fn pointer(&mut self) -> *mut Data;
35}
36
37/// Interface to implementations of `PLACE <- EXPR`.
38///
39/// `PLACE <- EXPR` effectively desugars into:
40///
41/// ```
42/// # #![feature(placement_new_protocol, box_heap)]
43/// # use std::ops::{Placer, Place, InPlace};
44/// # #[allow(non_snake_case)]
45/// # fn main() {
46/// # let PLACE = std::boxed::HEAP;
47/// # let EXPR = 1;
48/// let p = PLACE;
49/// let mut place = Placer::make_place(p);
50/// let raw_place = Place::pointer(&mut place);
51/// let value = EXPR;
52/// unsafe {
53/// std::ptr::write(raw_place, value);
54/// InPlace::finalize(place)
55/// }
56/// # ; }
57/// ```
58///
59/// The type of `PLACE <- EXPR` is derived from the type of `PLACE`;
60/// if the type of `PLACE` is `P`, then the final type of the whole
61/// expression is `P::Place::Owner` (see the `InPlace` and `Boxed`
62/// traits).
63///
64/// Values for types implementing this trait usually are transient
65/// intermediate values (e.g. the return value of `Vec::emplace_back`)
66/// or `Copy`, since the `make_place` method takes `self` by value.
67#[unstable(feature = "placement_new_protocol", issue = "27779")]
68pub trait Placer<Data: ?Sized> {
3b2f2976 69 /// `Place` is the intermediate agent guarding the
041b39d2
XL
70 /// uninitialized state for `Data`.
71 type Place: InPlace<Data>;
72
73 /// Creates a fresh place from `self`.
74 fn make_place(self) -> Self::Place;
75}
76
77/// Specialization of `Place` trait supporting `PLACE <- EXPR`.
78#[unstable(feature = "placement_new_protocol", issue = "27779")]
79pub trait InPlace<Data: ?Sized>: Place<Data> {
80 /// `Owner` is the type of the end value of `PLACE <- EXPR`
81 ///
82 /// Note that when `PLACE <- EXPR` is solely used for
83 /// side-effecting an existing data-structure,
84 /// e.g. `Vec::emplace_back`, then `Owner` need not carry any
85 /// information at all (e.g. it can be the unit type `()` in that
86 /// case).
87 type Owner;
88
89 /// Converts self into the final value, shifting
90 /// deallocation/cleanup responsibilities (if any remain), over to
91 /// the returned instance of `Owner` and forgetting self.
92 unsafe fn finalize(self) -> Self::Owner;
93}
94
95/// Core trait for the `box EXPR` form.
96///
97/// `box EXPR` effectively desugars into:
98///
99/// ```
100/// # #![feature(placement_new_protocol)]
101/// # use std::ops::{BoxPlace, Place, Boxed};
102/// # #[allow(non_snake_case)]
103/// # fn main() {
104/// # let EXPR = 1;
105/// let mut place = BoxPlace::make_place();
106/// let raw_place = Place::pointer(&mut place);
107/// let value = EXPR;
108/// # let _: Box<_> =
109/// unsafe {
110/// ::std::ptr::write(raw_place, value);
111/// Boxed::finalize(place)
112/// }
113/// # ; }
114/// ```
115///
116/// The type of `box EXPR` is supplied from its surrounding
117/// context; in the above expansion, the result type `T` is used
118/// to determine which implementation of `Boxed` to use, and that
119/// `<T as Boxed>` in turn dictates determines which
120/// implementation of `BoxPlace` to use, namely:
121/// `<<T as Boxed>::Place as BoxPlace>`.
122#[unstable(feature = "placement_new_protocol", issue = "27779")]
123pub trait Boxed {
124 /// The kind of data that is stored in this kind of box.
125 type Data; /* (`Data` unused b/c cannot yet express below bound.) */
126 /// The place that will negotiate the storage of the data.
127 type Place: BoxPlace<Self::Data>;
128
129 /// Converts filled place into final owning value, shifting
130 /// deallocation/cleanup responsibilities (if any remain), over to
131 /// returned instance of `Self` and forgetting `filled`.
132 unsafe fn finalize(filled: Self::Place) -> Self;
133}
134
135/// Specialization of `Place` trait supporting `box EXPR`.
136#[unstable(feature = "placement_new_protocol", issue = "27779")]
137pub trait BoxPlace<Data: ?Sized> : Place<Data> {
138 /// Creates a globally fresh place.
139 fn make_place() -> Self;
140}