File tree Expand file tree Collapse file tree 2 files changed +27
-3
lines changed Expand file tree Collapse file tree 2 files changed +27
-3
lines changed Original file line number Diff line number Diff line change 11//! Tock Cell types.
22
3- #![ feature( const_fn) ]
3+ #![ feature( const_fn, untagged_unions ) ]
44#![ no_std]
55
66pub mod map_cell;
Original file line number Diff line number Diff line change @@ -16,10 +16,34 @@ pub struct MapCell<T> {
1616 occupied : Cell < bool > ,
1717}
1818
19+ // This function allows us to mimic `mem::uninitialized` in a way that can be marked `const`.
20+ // Specifically, we just want to allocate some memory the size of some particular `T` and we don't
21+ // care what's there---this happens to not be marked `cost` in the core library right now since
22+ // it's an LLVM intrinsic.
23+ //
24+ // This uses an unsafe union to do basically the same thing: the union will have the size of the
25+ // larger of the two fields (`T`, since `()` is zero-sized). It then initializes the union with the
26+ // `none` variant (of type `()`), but returns the `some` variant (which is of type `T`), thus
27+ // giving us back something of type `T` with some uninitialized memory.
28+ //
29+ // This is of course wildly unsafe, and should be used with the utmost caution---the value returned
30+ // is _not_ valid!
31+ //
32+ // Credit to @japaric: https://github.com/rust-lang/rust/pull/50150
33+ const unsafe fn uninitialized < T > ( ) -> T {
34+ #[ allow( unions_with_drop_fields) ]
35+ union U < T > {
36+ none : ( ) ,
37+ some : T ,
38+ }
39+
40+ U { none : ( ) } . some
41+ }
42+
1943impl < T > MapCell < T > {
20- pub fn empty ( ) -> MapCell < T > {
44+ pub const fn empty ( ) -> MapCell < T > {
2145 MapCell {
22- val : unsafe { mem :: uninitialized ( ) } ,
46+ val : unsafe { uninitialized ( ) } ,
2347 occupied : Cell :: new ( false ) ,
2448 }
2549 }
You can’t perform that action at this time.
0 commit comments