?Uninit types [exist today]. Also let's talk about DerefMove

Well, we do have drop flags already, and this is basically an extension of them. They're usually hidden from the user tho. Mainly you just don't want double-drop on panic. The main risk is when moving things out - if you simply reverted the type, then it'd potentially cause double-drop; so you can't revert the type.

In practice the deref_move should avoid panicking and the closure should be compiler-generated in such a way that it never panics. Optionally DerefMove could be unsafe to implement and impossible to call manually.

If it helps, tho: you can't pass one of these &mut T->U across a catch_unwind. They're not references - they're part of the function signature. So either you move the whole thing into the catch_unwind or you can't do &mut T->U on it. We believe this restriction applies today with Box?

Either you forbid it from panicking or you don't.

What if the user temporarily moves out of the &mut Self::Target->T::Target and does a potentially panicking check that needs the moved out value?

I think the simpliest solution here would be to consider passing a &mut T->U to a function as temporarily giving up its ownership. The function that receives it is temporarily responsible for dropping whatever is initialized when a panic happens. The parent should never drop the T when

Isn't this going to really complicate the type system? Wouldn't this make a function taking an &mut T->U not coercible to a function pointer?

Yes, currently you either move Box inside the closure or you don't. However this means not being able to actually have owning references with DerefMove

This is what drop flags (which we already have) are for. Oh, we misunderstood. Yes, that would have to be disallowed by the compiler, as it is today.

This whole DerefMove proposal kinda relies on being able to have function pointers with these &mut T->U thingies.

Okay good. Let's keep owning references out of the language. Trying to glue something (ownership) to its functional opposite (references) just sounds like a bad idea tbh. Rust seems to be pretty strongly built on the idea that ownership is mutually exclusive with references, at least.

Then that's not good. Arguments of function pointers/traits are assumed to be types. Changing this would mean having to re-design the Fn/FnMut/FnOnce traits

1 Like

Thankfully Fn/FnMut/FnOnce are already both special and basically opaque. Or at least were. How's it going for making them less opaque, anyway?

I think they're blocked on variadic generics, if we'll ever get them. Them being special/opaque is not a good reason to make them even more opaque/special.

1 Like

It's not, but we do feel like the benefits would outweigh the drawbacks. Granted, ppl don't think partially initialized types are worth it tho, even if they would solve the DerefMove problem and stuff.

Good thing you mentioned this. Because I would like to know what the benefits of partially initialized types would be – besides perhaps making Box less special. I'm essentially looking for the part that would go in the "motivation" section of an RFC. I think that would also help to focus the discussion.

Benefits:

  1. They enable Box and other DerefMove types to exist, like, at all, without having to make them special. Or at least we can't think of any other safe way you could make a DerefMove that supports the Box semantics of partial deinitialization and whatnot. Sure you could expose drop flags but then how would you figure out what to drop on complex, deeply nested structures? Box handles this by being special, so it's all taken care for you by the compiler, but if you're writing your own drop flag handling it gets a lot more complicated.
  2. They enable placement new. As in, at least with our proposal, you can't have PITs without placement new.
  3. Technically we do already have PITs today but they're extremely specially cased and not exposed as types. So this would formalize them.
  4. It's possible to allow destructuring out of Drop types with this proposal. Unsure if ppl want this enough for it to be a part of the proposal tho, so we'd prefer to leave it as a future option instead.
  5. More or less compatible with existing code. Shouldn't require an edition boundary, nor any other weirdness like having a drop method on DerefMove.

Also:

  1. Arguably, a lot of Drop's specialness/painness is closely related to the ability to partially move out of types. As already mentioned Drop turns off that ability, but also types that contain Drop types can't propagate implementing Drop because of that ability. We'd suggest being able to auto-impl Drop if a type contains Drop items, especially if this makes it possible to move things out of Drop types.
  2. Maybe, this could also be used to provide a stable escape hatch for #[may_dangle], by allowing Drop to be implemented with a PIT-fn? Not sure tbh.

(Mentioned to @Soni on the Rust Community Discord, but reposting here for the record)

Given those listed benefits, I would think it helpful to the proposal to demonstrait how PITs could be used to solve those particular issues. In particular, it may be advantageous to show how Box could be implemented using PITs. The other thing (though this could probably be included) would be showing how PITs could be used to work over the eyepatch.

We do need to learn more about the eyepatch tbh, that's why that one is a "maybe" rather than a "this would actually work"...