The basic idea is moving things in and out of Box without Box being magic (instead moving the magic into a DerefMove trait or similar).
The basic operations on the Box include:
-
Box<T((partially?) initialized)>
->Box<T(empty)>
-
Box<T(empty)>
->Box<T((partially?) initialized)>
- The ability to fold such operations.
For example, using syntax similar to our previous ?Uninit type proposals, say you have a Box<(String, String)>
, and you wanna move out the first item:
-
Box<(String, String)>
->Box<(String, String)()>
(aka: take a fully-initialized tuple and move it out, leaving a fully-deinitialized tuple) -
Box<(String, String)()>
->Box<(String, String)(1)>
(aka: take a fully-deinitialized tuple and move in to it, a partially-initialized tuple where only entry 1 is initialized)
This is, at least in the case of Box, equivalent to moving out only the second element.
Altho Uninit types help formalize this stuff, they're still not good enough. Here's what we're struggling with, consider a hypothetical non-generic type:
struct MyStruct(Vec<u8>);
and you can have Deref and DerefMut for it:
impl Deref for MyStruct {
type Target = Vec<u8>;
...
}
but for something like DerefMove to work, well... you're not changing the type of the Target, but the type of Self itself (which, does need to reflect on the type of the Target btw, and we're not sure how to handle that either). We can't think of any way of doing this within the (implied) framework we were working with when we wrote the previous "?Uninit types" stuff, unless we're missing something really obvious here.