@@ -160,7 +160,7 @@ tandem with types provided by the stdlib, such as `Box<T>`.
160160 foo(box some_expr());
161161 ```
162162 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) ` .
164164 This may also be due to weakness in the compiler, but that is not
165165 immediately obvious.
166166
@@ -295,26 +295,26 @@ macro_rules! in_ {
295295 let value = $ value ;
296296 unsafe {
297297 :: std :: ptr :: write (raw_place , value );
298- :: protocol :: InPlace :: finalize (place )
298+ :: protocol :: Place :: finalize (place )
299299 }
300300 } }
301301}
302302
303303macro_rules! box_ {
304304 ($ value : expr ) => { {
305- let mut place = :: protocol :: BoxPlace :: make_place ();
305+ let mut place = :: protocol :: Boxer :: make_place ();
306306 let raw_place = :: protocol :: Place :: pointer (& mut place );
307307 let value = $ value ;
308308 unsafe {
309309 :: std :: ptr :: write (raw_place , value );
310- :: protocol :: Boxed :: finalize (place )
310+ :: protocol :: Place :: finalize (place )
311311 }
312312 } }
313313}
314314
315315// Note that while both desugarings are very similar, there are some
316316// 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
318318// is overloaded based on the `place` argument (the type of which is
319319// derived from the `<place-expr>` input); on the other hand, the
320320// overloaded-`box` desugaring uses `Boxed::finalize(place)`, which is
@@ -341,16 +341,30 @@ mod protocol {
341341/// The client is responsible for two steps: First, initializing the
342342/// payload (it can access its address via `pointer`). Second,
343343/// converting the agent to an instance of the owning pointer, via the
344- /// appropriate `finalize` method (see the `InPlace` .
344+ /// `finalize` method.
345345///
346346/// If evaluating EXPR fails, then the destructor for the
347347/// implementation of Place to clean up any intermediate state
348348/// (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+
350359 /// Returns the address where the input value will be written.
351360 /// Note that the data at this address is generally uninitialized,
352361 /// and thus one should use `ptr::write` for initializing it.
353362 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 ;
354368}
355369
356370/// Interface to implementations of `in PLACE { BLOCK }`.
@@ -364,77 +378,49 @@ pub trait Place<Data: ?Sized> {
364378/// let value = { BLOCK };
365379/// unsafe {
366380/// std::ptr::write(raw_place, value);
367- /// InPlace ::finalize(place)
381+ /// Place ::finalize(place)
368382/// }
369383/// ```
370384///
371385/// The type of `in PLACE { BLOCK }` is derived from the type of `PLACE`;
372386/// 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).
375388///
376389/// Values for types implementing this trait usually are transient
377390/// intermediate values (e.g. the return value of `Vec::emplace_back`)
378391/// or `Copy`, since the `make_place` method takes `self` by value.
379- pub trait Placer <Data : ? Sized > {
392+ pub unsafe trait Placer <Data : ? Sized > {
380393 /// `Place` is the intermedate agent guarding the
381394 /// uninitialized state for `Data`.
382- type Place : InPlace <Data >;
395+ type Place : Place <Data >;
383396
384397 /// Creates a fresh place from `self`.
385398 fn make_place (self ) -> Self :: Place ;
386399}
387400
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-
405401/// Core trait for the `box EXPR` form.
406402///
407403/// `box EXPR` effectively desugars into:
408404///
409405/// ```
410- /// let mut place = BoxPlace ::make_place();
406+ /// let mut place = Boxer ::make_place();
411407/// let raw_place = Place::pointer(&mut place);
412408/// let value = $value;
413409/// unsafe {
414410/// ::std::ptr::write(raw_place, value);
415- /// Boxed ::finalize(place)
411+ /// Place ::finalize(place)
416412/// }
417413/// ```
418414///
419415/// The type of `box EXPR` is supplied from its surrounding
420416/// context; in the above expansion, the result type `T` is used
421417/// 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 >;
435423
436- /// Specialization of `Place` trait supporting `box EXPR`.
437- pub trait BoxPlace <Data : ? Sized > : Place <Data > {
438424 /// Creates a globally fresh place.
439425 fn make_place () -> Self ;
440426}
@@ -465,39 +451,31 @@ mod impl_box_for_box {
465451 BoxPlace { fake_box : Some (Box :: new (t )) }
466452 }
467453
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 () }
472457 }
473458
474- impl <' a , T > proto :: Placer <T > for HEAP {
459+ unsafe impl <T > proto :: Boxer <T > for Box < T > {
475460 type Place = BoxPlace <T >;
476- fn make_place (self ) -> BoxPlace <T > { make_place () }
461+ fn make_place () -> BoxPlace <T > { make_place () }
477462 }
478463
479464 impl <T > proto :: Place <T > for BoxPlace <T > {
465+ type Owner = Box <T >;
466+
480467 fn pointer (& mut self ) -> * mut T {
481468 match self . fake_box {
482469 Some (ref mut b ) => & mut * * b as * mut T ,
483470 None => panic! (" impossible" ),
484471 }
485472 }
486- }
487-
488- impl <T > proto :: BoxPlace <T > for BoxPlace <T > {
489- fn make_place () -> BoxPlace <T > { make_place () }
490- }
491473
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+ }
501479 }
502480}
503481
@@ -515,6 +493,8 @@ mod impl_box_for_rc {
515493 struct RcPlace <T > { fake_box : Option <Rc <T >> }
516494
517495 impl <T > proto :: Place <T > for RcPlace <T > {
496+ type Owner = Rc <T >;
497+
518498 fn pointer (& mut self ) -> * mut T {
519499 if let Some (ref mut b ) = self . fake_box {
520500 if let Some (r ) = rc :: get_mut (b ) {
@@ -523,26 +503,24 @@ mod impl_box_for_rc {
523503 }
524504 panic! (" impossible" );
525505 }
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+ }
526512 }
527513
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+
529517 fn make_place () -> RcPlace <T > {
530518 unsafe {
531519 let t : T = mem :: zeroed ();
532520 RcPlace { fake_box : Some (Rc :: new (t )) }
533521 }
534522 }
535523 }
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- }
546524}
547525
548526// Third, we want something to demonstrate placement-`in`. Let us use
@@ -562,33 +540,24 @@ mod impl_in_for_vec_emplace_back {
562540 fn emplace_back (& mut self ) -> VecPlacer <T > { VecPlacer { v : self } }
563541 }
564542
565- impl <'a , T > proto :: Placer <T > for VecPlacer <'a , T > {
543+ unsafe impl <'a , T > proto :: Placer <T > for VecPlacer <'a , T > {
566544 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+ }
568549 }
569550
570551 impl <'a , T > proto :: Place <T > for VecPlace <'a , T > {
552+ type Owner = ();
571553 fn pointer (& mut self ) -> * mut T {
572554 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 ())
576556 }
577557 }
578- }
579- impl <'a , T > proto :: InPlace <T > for VecPlace <'a , T > {
580- type Owner = ();
581558 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 )
592561 }
593562 }
594563}
@@ -634,28 +603,33 @@ fn main() { }
634603
635604macro_rules! box_ {
636605 ($ value : expr ) => { {
637- let mut place = :: BoxPlace :: make ();
606+ let mut place = :: Boxer :: make_place ();
638607 let raw_place = :: Place :: pointer (& mut place );
639608 let value = $ value ;
640609 unsafe { :: std :: ptr :: write (raw_place , value ); :: Boxed :: fin (place ) }
641610 } }
642611}
643612
613+
644614// (Support traits and impls for examples below.)
645615
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+ }
649625
650626struct 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+ }
659633
660634// START HERE
661635
@@ -701,7 +675,7 @@ including the cases where type-inference fails in the desugaring.
701675/tmp/foo6.rs:7:1: 14:2 note: in expansion of box_!
702676/tmp/foo6.rs:37:64: 37:76 note: expansion site
703677/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 ();
705679 ^~~~~~~~~~~~~~~~
706680/tmp/foo6.rs:7:1: 14:2 note: in expansion of box_!
707681/tmp/foo6.rs:37:64: 37:76 note: expansion site
@@ -713,7 +687,7 @@ error: aborting due to 2 previous errors
713687/tmp/foo6.rs:7:1: 14:2 note: in expansion of box_!
714688/tmp/foo6.rs:52:51: 52:64 note: expansion site
715689/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 ();
717691 ^~~~~~~~~~~~~~~~
718692/tmp/foo6.rs:7:1: 14:2 note: in expansion of box_!
719693/tmp/foo6.rs:52:51: 52:64 note: expansion site
0 commit comments