Commit adc3beb 1 parent ba8e997 commit adc3beb Copy full SHA for adc3beb
File tree 2 files changed +27
-3
lines changed
2 files changed +27
-3
lines changed Original file line number Diff line number Diff line change 1
1
//! Tock Cell types.
2
2
3
- #![ feature( const_fn) ]
3
+ #![ feature( const_fn, untagged_unions ) ]
4
4
#![ no_std]
5
5
6
6
pub mod map_cell;
Original file line number Diff line number Diff line change @@ -16,10 +16,34 @@ pub struct MapCell<T> {
16
16
occupied : Cell < bool > ,
17
17
}
18
18
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
+
19
43
impl < T > MapCell < T > {
20
- pub fn empty ( ) -> MapCell < T > {
44
+ pub const fn empty ( ) -> MapCell < T > {
21
45
MapCell {
22
- val : unsafe { mem :: uninitialized ( ) } ,
46
+ val : unsafe { uninitialized ( ) } ,
23
47
occupied : Cell :: new ( false ) ,
24
48
}
25
49
}
You can’t perform that action at this time.
0 commit comments