@@ -160,7 +160,7 @@ tandem with types provided by the stdlib, such as `Box<T>`.
160
160
foo(box some_expr());
161
161
```
162
162
the type inference system attempts to unify the type ` Box<SomeTrait> `
163
- with the return-type of ` ::protocol::Boxed ::finalize(place) ` .
163
+ with the return-type of ` ::protocol::Place ::finalize(place) ` .
164
164
This may also be due to weakness in the compiler, but that is not
165
165
immediately obvious.
166
166
@@ -295,26 +295,26 @@ macro_rules! in_ {
295
295
let value = $ value ;
296
296
unsafe {
297
297
:: std :: ptr :: write (raw_place , value );
298
- :: protocol :: InPlace :: finalize (place )
298
+ :: protocol :: Place :: finalize (place )
299
299
}
300
300
} }
301
301
}
302
302
303
303
macro_rules! box_ {
304
304
($ value : expr ) => { {
305
- let mut place = :: protocol :: BoxPlace :: make_place ();
305
+ let mut place = :: protocol :: Boxer :: make_place ();
306
306
let raw_place = :: protocol :: Place :: pointer (& mut place );
307
307
let value = $ value ;
308
308
unsafe {
309
309
:: std :: ptr :: write (raw_place , value );
310
- :: protocol :: Boxed :: finalize (place )
310
+ :: protocol :: Place :: finalize (place )
311
311
}
312
312
} }
313
313
}
314
314
315
315
// Note that while both desugarings are very similar, there are some
316
316
// slight differences. In particular, the placement-`in` desugaring
317
- // uses `InPlace ::finalize(place)`, which is a `finalize` method that
317
+ // uses `Place ::finalize(place)`, which is a `finalize` method that
318
318
// is overloaded based on the `place` argument (the type of which is
319
319
// derived from the `<place-expr>` input); on the other hand, the
320
320
// overloaded-`box` desugaring uses `Boxed::finalize(place)`, which is
@@ -341,16 +341,30 @@ mod protocol {
341
341
/// The client is responsible for two steps: First, initializing the
342
342
/// payload (it can access its address via `pointer`). Second,
343
343
/// converting the agent to an instance of the owning pointer, via the
344
- /// appropriate `finalize` method (see the `InPlace` .
344
+ /// `finalize` method.
345
345
///
346
346
/// If evaluating EXPR fails, then the destructor for the
347
347
/// implementation of Place to clean up any intermediate state
348
348
/// (e.g. deallocate box storage, pop a stack, etc).
349
- pub trait Place <Data : ? Sized > {
349
+ pub unsafe trait Place <Data : ? Sized > {
350
+ /// `Owner` is the type of the end value of `in PLACE { BLOCK }`
351
+ ///
352
+ /// Note that when `in PLACE { BLOCK }` is solely used for
353
+ /// side-effecting an existing data-structure,
354
+ /// e.g. `Vec::emplace_back`, then `Owner` need not carry any
355
+ /// information at all (e.g. it can be the unit type `()` in that
356
+ /// case).
357
+ type Owner ;
358
+
350
359
/// Returns the address where the input value will be written.
351
360
/// Note that the data at this address is generally uninitialized,
352
361
/// and thus one should use `ptr::write` for initializing it.
353
362
fn pointer (& mut self ) -> * mut Data ;
363
+
364
+ /// Converts self into the final value, shifting deallocation/cleanup
365
+ /// responsibilities (if any remain), over to the returned instance of
366
+ /// `Owner` and forgetting self.
367
+ unsafe fn finalize (self ) -> Self :: Owner ;
354
368
}
355
369
356
370
/// Interface to implementations of `in PLACE { BLOCK }`.
@@ -364,77 +378,49 @@ pub trait Place<Data: ?Sized> {
364
378
/// let value = { BLOCK };
365
379
/// unsafe {
366
380
/// std::ptr::write(raw_place, value);
367
- /// InPlace ::finalize(place)
381
+ /// Place ::finalize(place)
368
382
/// }
369
383
/// ```
370
384
///
371
385
/// The type of `in PLACE { BLOCK }` is derived from the type of `PLACE`;
372
386
/// if the type of `PLACE` is `P`, then the final type of the whole
373
- /// expression is `P::Place::Owner` (see the `InPlace` and `Boxed`
374
- /// traits).
387
+ /// expression is `P::Place::Owner` (see the `Place` trait).
375
388
///
376
389
/// Values for types implementing this trait usually are transient
377
390
/// intermediate values (e.g. the return value of `Vec::emplace_back`)
378
391
/// or `Copy`, since the `make_place` method takes `self` by value.
379
- pub trait Placer <Data : ? Sized > {
392
+ pub unsafe trait Placer <Data : ? Sized > {
380
393
/// `Place` is the intermedate agent guarding the
381
394
/// uninitialized state for `Data`.
382
- type Place : InPlace <Data >;
395
+ type Place : Place <Data >;
383
396
384
397
/// Creates a fresh place from `self`.
385
398
fn make_place (self ) -> Self :: Place ;
386
399
}
387
400
388
- /// Specialization of `Place` trait supporting `in PLACE { BLOCK }`.
389
- pub trait InPlace <Data : ? Sized >: Place <Data > {
390
- /// `Owner` is the type of the end value of `in PLACE { BLOCK }`
391
- ///
392
- /// Note that when `in PLACE { BLOCK }` is solely used for
393
- /// side-effecting an existing data-structure,
394
- /// e.g. `Vec::emplace_back`, then `Owner` need not carry any
395
- /// information at all (e.g. it can be the unit type `()` in that
396
- /// case).
397
- type Owner ;
398
-
399
- /// Converts self into the final value, shifting
400
- /// deallocation/cleanup responsibilities (if any remain), over to
401
- /// the returned instance of `Owner` and forgetting self.
402
- unsafe fn finalize (self ) -> Self :: Owner ;
403
- }
404
-
405
401
/// Core trait for the `box EXPR` form.
406
402
///
407
403
/// `box EXPR` effectively desugars into:
408
404
///
409
405
/// ```
410
- /// let mut place = BoxPlace ::make_place();
406
+ /// let mut place = Boxer ::make_place();
411
407
/// let raw_place = Place::pointer(&mut place);
412
408
/// let value = $value;
413
409
/// unsafe {
414
410
/// ::std::ptr::write(raw_place, value);
415
- /// Boxed ::finalize(place)
411
+ /// Place ::finalize(place)
416
412
/// }
417
413
/// ```
418
414
///
419
415
/// The type of `box EXPR` is supplied from its surrounding
420
416
/// context; in the above expansion, the result type `T` is used
421
417
/// to determine which implementation of `Boxed` to use, and that
422
- /// `<T as Boxed>` in turn dictates determines which
423
- /// implementation of `BoxPlace` to use, namely:
424
- /// `<<T as Boxed>::Place as BoxPlace>`.
425
- pub trait Boxed {
426
- /// The kind of data that is stored in this kind of box.
427
- type Data ; /* (`Data` unused b/c cannot yet express below bound.) */
428
- type Place ; /* should be bounded by BoxPlace<Self::Data> */
429
-
430
- /// Converts filled place into final owning value, shifting
431
- /// deallocation/cleanup responsibilities (if any remain), over to
432
- /// returned instance of `Self` and forgetting `filled`.
433
- unsafe fn finalize (filled : Self :: Place ) -> Self ;
434
- }
418
+ /// `<T as Boxer>` in turn dictates determines which
419
+ /// implementation of `Place` to use, namely:
420
+ /// `<<T as Boxer>::Place as Place>`.
421
+ pub unsafe trait Boxer <Data : ? Sized >: Sized {
422
+ type Place : Place <Data , Owner = Self >;
435
423
436
- /// Specialization of `Place` trait supporting `box EXPR`.
437
- pub trait BoxPlace <Data : ? Sized > : Place <Data > {
438
424
/// Creates a globally fresh place.
439
425
fn make_place () -> Self ;
440
426
}
@@ -465,39 +451,31 @@ mod impl_box_for_box {
465
451
BoxPlace { fake_box : Some (Box :: new (t )) }
466
452
}
467
453
468
- unsafe fn finalize <T >(mut filled : BoxPlace <T >) -> Box <T > {
469
- let mut ret = None ;
470
- mem :: swap (& mut filled . fake_box, & mut ret );
471
- ret . unwrap ()
454
+ unsafe impl <'a , T > proto :: Placer <T > for HEAP {
455
+ type Place = BoxPlace <T >;
456
+ fn make_place (self ) -> BoxPlace <T > { make_place () }
472
457
}
473
458
474
- impl <' a , T > proto :: Placer <T > for HEAP {
459
+ unsafe impl <T > proto :: Boxer <T > for Box < T > {
475
460
type Place = BoxPlace <T >;
476
- fn make_place (self ) -> BoxPlace <T > { make_place () }
461
+ fn make_place () -> BoxPlace <T > { make_place () }
477
462
}
478
463
479
464
impl <T > proto :: Place <T > for BoxPlace <T > {
465
+ type Owner = Box <T >;
466
+
480
467
fn pointer (& mut self ) -> * mut T {
481
468
match self . fake_box {
482
469
Some (ref mut b ) => & mut * * b as * mut T ,
483
470
None => panic! (" impossible" ),
484
471
}
485
472
}
486
- }
487
-
488
- impl <T > proto :: BoxPlace <T > for BoxPlace <T > {
489
- fn make_place () -> BoxPlace <T > { make_place () }
490
- }
491
473
492
- impl <T > proto :: InPlace <T > for BoxPlace <T > {
493
- type Owner = Box <T >;
494
- unsafe fn finalize (self ) -> Box <T > { finalize (self ) }
495
- }
496
-
497
- impl <T > proto :: Boxed for Box <T > {
498
- type Data = T ;
499
- type Place = BoxPlace <T >;
500
- unsafe fn finalize (filled : BoxPlace <T >) -> Self { finalize (filled ) }
474
+ unsafe fn finalize <T >(mut self ) -> Box <T > {
475
+ let mut ret = None ;
476
+ mem :: swap (& mut filled . fake_box, & mut ret );
477
+ ret . unwrap ()
478
+ }
501
479
}
502
480
}
503
481
@@ -515,6 +493,8 @@ mod impl_box_for_rc {
515
493
struct RcPlace <T > { fake_box : Option <Rc <T >> }
516
494
517
495
impl <T > proto :: Place <T > for RcPlace <T > {
496
+ type Owner = Rc <T >;
497
+
518
498
fn pointer (& mut self ) -> * mut T {
519
499
if let Some (ref mut b ) = self . fake_box {
520
500
if let Some (r ) = rc :: get_mut (b ) {
@@ -523,26 +503,24 @@ mod impl_box_for_rc {
523
503
}
524
504
panic! (" impossible" );
525
505
}
506
+
507
+ unsafe fn finalize (mut self ) -> Rc <T > {
508
+ let mut ret = None ;
509
+ mem :: swap (& mut filled . fake_box, & mut ret );
510
+ ret . unwrap ()
511
+ }
526
512
}
527
513
528
- impl <T > proto :: BoxPlace <T > for RcPlace <T > {
514
+ unsafe impl <T > proto :: Boxer <T > for RcPlace <T > {
515
+ type Place = RcPlace <T >;
516
+
529
517
fn make_place () -> RcPlace <T > {
530
518
unsafe {
531
519
let t : T = mem :: zeroed ();
532
520
RcPlace { fake_box : Some (Rc :: new (t )) }
533
521
}
534
522
}
535
523
}
536
-
537
- impl <T > proto :: Boxed for Rc <T > {
538
- type Data = T ;
539
- type Place = RcPlace <T >;
540
- unsafe fn finalize (mut filled : RcPlace <T >) -> Self {
541
- let mut ret = None ;
542
- mem :: swap (& mut filled . fake_box, & mut ret );
543
- ret . unwrap ()
544
- }
545
- }
546
524
}
547
525
548
526
// Third, we want something to demonstrate placement-`in`. Let us use
@@ -562,33 +540,24 @@ mod impl_in_for_vec_emplace_back {
562
540
fn emplace_back (& mut self ) -> VecPlacer <T > { VecPlacer { v : self } }
563
541
}
564
542
565
- impl <'a , T > proto :: Placer <T > for VecPlacer <'a , T > {
543
+ unsafe impl <'a , T > proto :: Placer <T > for VecPlacer <'a , T > {
566
544
type Place = VecPlace <'a , T >;
567
- fn make_place (self ) -> VecPlace <'a , T > { VecPlace { v : self . v } }
545
+ fn make_place (self ) -> VecPlace <'a , T > {
546
+ selv . v. reserve (1 );
547
+ VecPlace { v : self . v }
548
+ }
568
549
}
569
550
570
551
impl <'a , T > proto :: Place <T > for VecPlace <'a , T > {
552
+ type Owner = ();
571
553
fn pointer (& mut self ) -> * mut T {
572
554
unsafe {
573
- let idx = self . v. len ();
574
- self . v. push (mem :: zeroed ());
575
- & mut self . v[idx ]
555
+ self . v. as_mut_ptr (). offset (self . v. len ())
576
556
}
577
557
}
578
- }
579
- impl <'a , T > proto :: InPlace <T > for VecPlace <'a , T > {
580
- type Owner = ();
581
558
unsafe fn finalize (self ) -> () {
582
- mem :: forget (self );
583
- }
584
- }
585
-
586
- #[unsafe_destructor]
587
- impl <'a , T > Drop for VecPlace <'a , T > {
588
- fn drop (& mut self ) {
589
- unsafe {
590
- mem :: forget (self . v. pop ())
591
- }
559
+ // checked by reserve.
560
+ self . v. set_len (self . v. len () + 1 )
592
561
}
593
562
}
594
563
}
@@ -634,28 +603,33 @@ fn main() { }
634
603
635
604
macro_rules! box_ {
636
605
($ value : expr ) => { {
637
- let mut place = :: BoxPlace :: make ();
606
+ let mut place = :: Boxer :: make_place ();
638
607
let raw_place = :: Place :: pointer (& mut place );
639
608
let value = $ value ;
640
609
unsafe { :: std :: ptr :: write (raw_place , value ); :: Boxed :: fin (place ) }
641
610
} }
642
611
}
643
612
613
+
644
614
// (Support traits and impls for examples below.)
645
615
646
- pub trait BoxPlace <Data : ? Sized > : Place <Data > { fn make () -> Self ; }
647
- pub trait Place <Data : ? Sized > { fn pointer (& mut self ) -> * mut Data ; }
648
- pub trait Boxed { type Place ; fn fin (filled : Self :: Place ) -> Self ; }
616
+ trait Place <Data : ? Sized > {
617
+ type Owner ;
618
+ fn pointer (& mut self ) -> * mut Data ;
619
+ unsafe fn finalize (self ) -> Self :: Owner ;
620
+ }
621
+ unsafe trait Boxer <Data : ? Sized >: Sized {
622
+ type Place : Place <Data , Owner = Self >;
623
+ fn make_place () -> Self ;
624
+ }
649
625
650
626
struct BP <T : ? Sized > { _fake_box : Option <Box <T >> }
651
-
652
- impl <T > BoxPlace <T > for BP <T > { fn make () -> BP <T > { make_pl () } }
653
- impl <T : ? Sized > Place <T > for BP <T > { fn pointer (& mut self ) -> * mut T { pointer (self ) } }
654
- impl <T : ? Sized > Boxed for Box <T > { type Place = BP <T >; fn fin (x : BP <T >) -> Self { finaliz (x ) } }
655
-
656
- fn make_pl <T >() -> BP <T > { loop { } }
657
- fn finaliz <T : ? Sized >(mut _filled : BP <T >) -> Box <T > { loop { } }
658
- fn pointer <T : ? Sized >(_p : & mut BP <T >) -> * mut T { loop { } }
627
+ unsafe impl <T > Boxer <T > for BP <T > { fn make_place () -> BP <T > { loop { } } }
628
+ impl <T : ? Sized > Place <T > for BP <T > {
629
+ type Owner = Box <T >;
630
+ fn pointer (& mut self ) -> * mut T { loop { } }
631
+ fn finalize (x : BP <T >) -> Self { loop { } }
632
+ }
659
633
660
634
// START HERE
661
635
@@ -701,7 +675,7 @@ including the cases where type-inference fails in the desugaring.
701
675
/tmp/foo6.rs:7:1: 14:2 note: in expansion of box_!
702
676
/tmp/foo6.rs:37:64: 37:76 note: expansion site
703
677
/tmp/foo6.rs:9:25: 9:41 error: the trait `core::marker::Sized` is not implemented for the type `core::ops::Fn()` [E0277]
704
- /tmp/foo6.rs:9 let mut place = ::BoxPlace::make ();
678
+ /tmp/foo6.rs:9 let mut place = ::Boxer::make_place ();
705
679
^~~~~~~~~~~~~~~~
706
680
/tmp/foo6.rs:7:1: 14:2 note: in expansion of box_!
707
681
/tmp/foo6.rs:37:64: 37:76 note: expansion site
@@ -713,7 +687,7 @@ error: aborting due to 2 previous errors
713
687
/tmp/foo6.rs:7:1: 14:2 note: in expansion of box_!
714
688
/tmp/foo6.rs:52:51: 52:64 note: expansion site
715
689
/tmp/foo6.rs:9:25: 9:41 error: the trait `core::marker::Sized` is not implemented for the type `[T]` [E0277]
716
- /tmp/foo6.rs:9 let mut place = ::BoxPlace::make ();
690
+ /tmp/foo6.rs:9 let mut place = ::Boxer::make_place ();
717
691
^~~~~~~~~~~~~~~~
718
692
/tmp/foo6.rs:7:1: 14:2 note: in expansion of box_!
719
693
/tmp/foo6.rs:52:51: 52:64 note: expansion site
0 commit comments