@@ -1266,3 +1266,115 @@ impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {}
1266
1266
1267
1267
// *const T -> *const U
1268
1268
impl < 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