-
Notifications
You must be signed in to change notification settings - Fork 13.2k
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1266,3 +1266,115 @@ impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {} | |
|
||
// *const T -> *const U | ||
impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {} | ||
|
||
/// Both `in (PLACE) EXPR` and `box EXPR` desugar into expressions | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
pnkfelix
Author
Member
|
||
/// that allocate an intermediate "place" that holds uninitialized | ||
/// state. The desugaring evaluates EXPR, and writes the result at | ||
/// the address returned by the `pointer` method of this trait. | ||
/// | ||
/// A `Place` can be thought of as a special representation for a | ||
/// hypothetical `&uninit` reference (which Rust cannot currently | ||
/// express directly). That is, it represents a pointer to | ||
/// uninitialized storage. | ||
/// | ||
/// The client is responsible for two steps: First, initializing the | ||
/// payload (it can access its address via `pointer`). Second, | ||
/// converting the agent to an instance of the owning pointer, via the | ||
/// appropriate `finalize` method (see the `InPlace`. | ||
/// | ||
/// If evaluating EXPR fails, then the destructor for the | ||
/// implementation of Place to clean up any intermediate state | ||
/// (e.g. deallocate box storage, pop a stack, etc). | ||
pub trait Place<Data: ?Sized> { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
pnkfelix
Author
Member
|
||
/// Returns the address where the input value will be written. | ||
/// Note that the data at this address is generally uninitialized, | ||
/// and thus one should use `ptr::write` for initializing it. | ||
fn pointer(&mut self) -> *mut Data; | ||
} | ||
|
||
/// Interface to implementations of `in (PLACE) EXPR`. | ||
/// | ||
/// `in (PLACE) EXPR` effectively desugars into: | ||
/// | ||
/// ```rust,ignore | ||
/// let p = PLACE; | ||
/// let mut place = Placer::make_place(p); | ||
/// let raw_place = Place::pointer(&mut place); | ||
/// let value = EXPR; | ||
/// unsafe { | ||
/// std::ptr::write(raw_place, value); | ||
/// InPlace::finalize(place) | ||
/// } | ||
/// ``` | ||
/// | ||
/// The type of `in (PLACE) EXPR` is derived from the type of `PLACE`; | ||
/// if the type of `PLACE` is `P`, then the final type of the whole | ||
/// expression is `P::Place::Owner` (see the `InPlace` and `Boxed` | ||
/// traits). | ||
/// | ||
/// Values for types implementing this trait usually are transient | ||
/// intermediate values (e.g. the return value of `Vec::emplace_back`) | ||
/// or `Copy`, since the `make_place` method takes `self` by value. | ||
pub trait Placer<Data: ?Sized> { | ||
/// `Place` is the intermedate agent guarding the | ||
This comment has been minimized.
Sorry, something went wrong. |
||
/// uninitialized state for `Data`. | ||
type Place: InPlace<Data>; | ||
|
||
/// Creates a fresh place from `self`. | ||
fn make_place(self) -> Self::Place; | ||
} | ||
|
||
/// Specialization of `Place` trait supporting `in (PLACE) EXPR`. | ||
pub trait InPlace<Data: ?Sized>: Place<Data> { | ||
/// `Owner` is the type of the end value of `in (PLACE) EXPR` | ||
This comment has been minimized.
Sorry, something went wrong. |
||
/// | ||
/// Note that when `in (PLACE) EXPR` is solely used for | ||
/// side-effecting an existing data-structure, | ||
/// e.g. `Vec::emplace_back`, then `Owner` need not carry any | ||
/// information at all (e.g. it can be the unit type `()` in that | ||
/// case). | ||
type Owner; | ||
|
||
/// Converts self into the final value, shifting | ||
/// deallocation/cleanup responsibilities (if any remain), over to | ||
/// the returned instance of `Owner` and forgetting self. | ||
unsafe fn finalize(self) -> Self::Owner; | ||
} | ||
|
||
/// Core trait for the `box EXPR` form. | ||
/// | ||
/// `box EXPR` effectively desugars into: | ||
/// | ||
/// ```rust,ignore | ||
/// let mut place = BoxPlace::make_place(); | ||
/// let raw_place = Place::pointer(&mut place); | ||
/// let value = EXPR; | ||
/// unsafe { | ||
/// ::std::ptr::write(raw_place, value); | ||
/// Boxed::finalize(place) | ||
/// } | ||
/// ``` | ||
/// | ||
/// The type of `box EXPR` is supplied from its surrounding | ||
/// context; in the above expansion, the result type `T` is used | ||
/// to determine which implementation of `Boxed` to use, and that | ||
/// `<T as Boxed>` in turn dictates determines which | ||
/// implementation of `BoxPlace` to use, namely: | ||
/// `<<T as Boxed>::Place as BoxPlace>`. | ||
pub trait Boxed { | ||
This comment has been minimized.
Sorry, something went wrong. |
||
/// The kind of data that is stored in this kind of box. | ||
type Data; /* (`Data` unused b/c cannot yet express below bound.) */ | ||
/// The place that will negotiate the storage of the data. | ||
type Place; /* should be bounded by BoxPlace<Self::Data> */ | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong. |
||
|
||
/// Converts filled place into final owning value, shifting | ||
/// deallocation/cleanup responsibilities (if any remain), over to | ||
/// returned instance of `Self` and forgetting `filled`. | ||
unsafe fn finalize(filled: Self::Place) -> Self; | ||
} | ||
|
||
/// Specialization of `Place` trait supporting `box EXPR`. | ||
pub trait BoxPlace<Data: ?Sized> : Place<Data> { | ||
/// Creates a globally fresh place. | ||
fn make_place() -> Self; | ||
} |
Seems to me that this is a base trait, and the "core trait" for
in
isInPlacer
, no?