@@ -1266,3 +1266,115 @@ impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {}
12661266
12671267// *const T -> *const U
12681268impl < T : ?Sized +Unsize < U > , U : ?Sized > CoerceUnsized < * const U > for * const T { }
1269+
1270+ /// Both `in (PLACE) EXPR` and `box EXPR` desugar into expressions
1271+ /// that allocate an intermediate "place" that holds uninitialized
1272+ /// state. The desugaring evaluates EXPR, and writes the result at
1273+ /// the address returned by the `pointer` method of this trait.
1274+ ///
1275+ /// A `Place` can be thought of as a special representation for a
1276+ /// hypothetical `&uninit` reference (which Rust cannot currently
1277+ /// express directly). That is, it represents a pointer to
1278+ /// uninitialized storage.
1279+ ///
1280+ /// The client is responsible for two steps: First, initializing the
1281+ /// payload (it can access its address via `pointer`). Second,
1282+ /// converting the agent to an instance of the owning pointer, via the
1283+ /// appropriate `finalize` method (see the `InPlace`.
1284+ ///
1285+ /// If evaluating EXPR fails, then the destructor for the
1286+ /// implementation of Place to clean up any intermediate state
1287+ /// (e.g. deallocate box storage, pop a stack, etc).
1288+ pub trait Place < Data : ?Sized > {
1289+ /// Returns the address where the input value will be written.
1290+ /// Note that the data at this address is generally uninitialized,
1291+ /// and thus one should use `ptr::write` for initializing it.
1292+ fn pointer ( & mut self ) -> * mut Data ;
1293+ }
1294+
1295+ /// Interface to implementations of `in (PLACE) EXPR`.
1296+ ///
1297+ /// `in (PLACE) EXPR` effectively desugars into:
1298+ ///
1299+ /// ```rust,ignore
1300+ /// let p = PLACE;
1301+ /// let mut place = Placer::make_place(p);
1302+ /// let raw_place = Place::pointer(&mut place);
1303+ /// let value = EXPR;
1304+ /// unsafe {
1305+ /// std::ptr::write(raw_place, value);
1306+ /// InPlace::finalize(place)
1307+ /// }
1308+ /// ```
1309+ ///
1310+ /// The type of `in (PLACE) EXPR` is derived from the type of `PLACE`;
1311+ /// if the type of `PLACE` is `P`, then the final type of the whole
1312+ /// expression is `P::Place::Owner` (see the `InPlace` and `Boxed`
1313+ /// traits).
1314+ ///
1315+ /// Values for types implementing this trait usually are transient
1316+ /// intermediate values (e.g. the return value of `Vec::emplace_back`)
1317+ /// or `Copy`, since the `make_place` method takes `self` by value.
1318+ pub trait Placer < Data : ?Sized > {
1319+ /// `Place` is the intermedate agent guarding the
1320+ /// uninitialized state for `Data`.
1321+ type Place : InPlace < Data > ;
1322+
1323+ /// Creates a fresh place from `self`.
1324+ fn make_place ( self ) -> Self :: Place ;
1325+ }
1326+
1327+ /// Specialization of `Place` trait supporting `in (PLACE) EXPR`.
1328+ pub trait InPlace < Data : ?Sized > : Place < Data > {
1329+ /// `Owner` is the type of the end value of `in (PLACE) EXPR`
1330+ ///
1331+ /// Note that when `in (PLACE) EXPR` is solely used for
1332+ /// side-effecting an existing data-structure,
1333+ /// e.g. `Vec::emplace_back`, then `Owner` need not carry any
1334+ /// information at all (e.g. it can be the unit type `()` in that
1335+ /// case).
1336+ type Owner ;
1337+
1338+ /// Converts self into the final value, shifting
1339+ /// deallocation/cleanup responsibilities (if any remain), over to
1340+ /// the returned instance of `Owner` and forgetting self.
1341+ unsafe fn finalize ( self ) -> Self :: Owner ;
1342+ }
1343+
1344+ /// Core trait for the `box EXPR` form.
1345+ ///
1346+ /// `box EXPR` effectively desugars into:
1347+ ///
1348+ /// ```rust,ignore
1349+ /// let mut place = BoxPlace::make_place();
1350+ /// let raw_place = Place::pointer(&mut place);
1351+ /// let value = EXPR;
1352+ /// unsafe {
1353+ /// ::std::ptr::write(raw_place, value);
1354+ /// Boxed::finalize(place)
1355+ /// }
1356+ /// ```
1357+ ///
1358+ /// The type of `box EXPR` is supplied from its surrounding
1359+ /// context; in the above expansion, the result type `T` is used
1360+ /// to determine which implementation of `Boxed` to use, and that
1361+ /// `<T as Boxed>` in turn dictates determines which
1362+ /// implementation of `BoxPlace` to use, namely:
1363+ /// `<<T as Boxed>::Place as BoxPlace>`.
1364+ pub trait Boxed {
1365+ /// The kind of data that is stored in this kind of box.
1366+ type Data ; /* (`Data` unused b/c cannot yet express below bound.) */
1367+ /// The place that will negotiate the storage of the data.
1368+ type Place ; /* should be bounded by BoxPlace<Self::Data> */
1369+
1370+ /// Converts filled place into final owning value, shifting
1371+ /// deallocation/cleanup responsibilities (if any remain), over to
1372+ /// returned instance of `Self` and forgetting `filled`.
1373+ unsafe fn finalize ( filled : Self :: Place ) -> Self ;
1374+ }
1375+
1376+ /// Specialization of `Place` trait supporting `box EXPR`.
1377+ pub trait BoxPlace < Data : ?Sized > : Place < Data > {
1378+ /// Creates a globally fresh place.
1379+ fn make_place ( ) -> Self ;
1380+ }
0 commit comments