I would invite you to explain more about your idea first. For example:
why do you think it's safe?
why do you think this would be useful?
I believe you can make this just unsafe { *self.ptr = ManuallyDrop::take(&mut self.replacement) }. The compiler will take care of dropping the value at *self.ptr and ensure that it will be replaced by ManuallyDrop::take(&mut self.replacement) even if the dropping panics. Moreover there's no need for a panic bomb in that case because *self.ptr will be replaced in any case.
I think that in case the drop impl of T panics it would leave the place in a bad state. I also believe it is kind of more clear what is going on if the drop is explicit.
Why I believe it is safe? Unless you longjump, the T from &mut T is dropped, fulfilling the drop guarantee of Pin constructed. A replacement is just to not leave the reference in an inconsistent state, it is fairly trivial to get one in most cases imo. Idk about use cases, just sharing an idea, as I think it is both interesting and sound.
I took an inspiration from the fact the if a !Forgetis borrowing the value, it is effectively pinned until this !Forget value is dropped. For !Destruct(linear?) types the guarantee seems even more powerful.
It looks like the difference is whether the structure in place is moved before it’s pinned or not. But if the value is address-sensitive, presumably it should’ve already been pinned. So I can’t see a use case either.
I guess the only substantial difference is that the unsafe version only does one write (from the replacement into place) while the safe one must more one than one to swap the values at place and replacement, which could be less efficient.
Assigning to *self.ptr will drop its value, which runs its Drop code and that might panic. In that case the forget won't be reached and the bomb will be dropped.
This is a common patter when you want to run some cleanup code, or need to handle a panic differently than a normal return.