// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Move references.
//!
//! A move reference represents an owned value that is stored "somewhere else".
//! We own the value, not the storage.
//!
//! A [`MoveRef<'a, T>`] represents a *permanent* unique reference to `T` for
//! the lifetime `'a`: it is the longest-lived *possible* reference to the
//! pointee, making it closer to a [`Box<T>`]
//!
//! Like [`&mut T`] but unlike [`Box<T>`], a [`MoveRef<T>`] is not responsible
//! for destroying its storage, meaning that it is storage agnostic. The storage
//! might be on the stack *or* on the heap; some RAII value on the stack is
//! responsible for destroying just the storage, once the [`MoveRef<T>`] itself
//! is gone.
//!
//! The main mechanism for obtaining [`MoveRef`]s is the [`moveit!()`] macro,
//! which is analogous to a theoretical `&move expr` operator. This macro
//! wraps [`DerefMove`], much like `&mut expr` wraps [`DerefMut`].
//!
//! Implementing [`DerefMove`] is a delicate affair; its documentation details
//! exactly how it should be done.
//!
//! # Drop Flags
//!
//! In order to be sound, a `MoveRef` must also hold a pointer to a drop flag,
//! which is used to detect if the `MoveRef` was dropped without destruction.
//!
//! In general, [`mem::forget`]ing a `MoveRef` is a very, very bad idea. In the
//! best case it will leak memory, but in some cases will crash the program in
//! order to observe safety guarantees.

use core::mem;
use core::ops::Deref;
use core::ops::DerefMut;
use core::pin::Pin;
use core::ptr;

#[cfg(doc)]
use {
  crate::{drop_flag, moveit},
  alloc::{boxed::Box, rc::Rc, sync::Arc},
  core::mem::{ManuallyDrop, MaybeUninit},
};

use crate::drop_flag::DropFlag;
use crate::slot::DroppingSlot;

/// A `MoveRef<'a, T>` represents an owned `T` whose storage location is valid
/// but unspecified.
///
/// See [the module documentation][self] for more details.
pub struct MoveRef<'a, T: ?Sized> {
  ptr: &'a mut T,
  drop_flag: DropFlag<'a>,
}

impl<'a, T: ?Sized> MoveRef<'a, T> {
  /// Creates a new `MoveRef<T>` out of a mutable reference.
  ///
  /// # Safety
  ///
  /// `ptr` must satisfy the *longest-lived* criterion: after the return value
  /// goes out of scope, `ptr` must also be out-of-scope. Calling this function
  /// correctly is non-trivial, and should be left to [`moveit!()`] instead.
  ///
  /// In particular, if `ptr` outlives the returned `MoveRef`, it will point
  /// to dropped memory, which is UB.
  ///
  /// `drop_flag`'s value must not be dead, and must be a drop flag governing
  /// the destruction of `ptr`'s storage in an appropriate manner as described
  /// in [`moveit::drop_flag`][crate::drop_flag].
  #[inline]
  pub unsafe fn new_unchecked(ptr: &'a mut T, drop_flag: DropFlag<'a>) -> Self {
    Self { ptr, drop_flag }
  }

  /// Converts a `MoveRef<T>` into a `Pin<MoveRef<T>>`.
  ///
  /// Because we own the referent, we are entitled to pin it permanently. See
  /// [`Box::into_pin()`] for a standard-library equivalent.
  #[inline]
  pub fn into_pin(this: Self) -> Pin<Self> {
    unsafe { Pin::new_unchecked(this) }
  }

  /// Returns this `MoveRef<T>` as a raw pointer, without creating an
  /// intermediate reference.
  ///
  /// The usual caveats for casting a reference to a pointer apply.
  #[inline]
  pub fn as_ptr(this: &Self) -> *const T {
    this.ptr
  }

  /// Returns this `MoveRef<T>` as a raw mutable pointer, without creating an
  /// intermediate reference.
  ///
  /// The usual caveats for casting a reference to a pointer apply.
  #[inline]
  pub fn as_mut_ptr(this: &mut Self) -> *mut T {
    this.ptr
  }

  #[allow(unused)]
  pub(crate) fn drop_flag(this: &Self) -> DropFlag<'a> {
    this.drop_flag
  }
}

// Extremely dangerous casts used by DerefMove below.
impl<'a, T> MoveRef<'a, T> {
  /// Consumes `self`, blindly casting the inner pointer to `U`.
  pub(crate) unsafe fn cast<U>(mut self) -> MoveRef<'a, U> {
    let mr = MoveRef {
      ptr: &mut *Self::as_mut_ptr(&mut self).cast(),
      drop_flag: self.drop_flag,
    };
    mem::forget(self);
    mr
  }
}

impl<'a, T> MoveRef<'a, T> {
  /// Consume the `MoveRef<T>`, returning the wrapped value.
  #[inline]
  pub fn into_inner(this: Self) -> T {
    unsafe {
      let val = ptr::read(this.ptr);
      let _ = this.cast::<()>();
      val
    }
  }
}

impl<T: ?Sized> Deref for MoveRef<'_, T> {
  type Target = T;

  #[inline]
  fn deref(&self) -> &Self::Target {
    self.ptr
  }
}

impl<T: ?Sized> DerefMut for MoveRef<'_, T> {
  #[inline]
  fn deref_mut(&mut self) -> &mut Self::Target {
    self.ptr
  }
}

impl<T: ?Sized> Drop for MoveRef<'_, T> {
  #[inline]
  fn drop(&mut self) {
    self.drop_flag.dec_and_check_if_died();
    unsafe { ptr::drop_in_place(self.ptr) }
  }
}

impl<'a, T> From<MoveRef<'a, T>> for Pin<MoveRef<'a, T>> {
  #[inline]
  fn from(x: MoveRef<'a, T>) -> Self {
    MoveRef::into_pin(x)
  }
}

/// A trait for getting a pinned [`MoveRef`] for some pointer type `Self`.
///
/// Conceptually, this trait is similar to [`DerefMove`], except that where
/// [`DerefMove::deref_move`] produces a `MoveRef<T>`, [`AsMove::as_move`] produces a
/// `Pin<MoveRef<T>>`.
///
/// `DerefMove` can be seen as a refinement of `AsMove` where stronger guarantees about the memory
/// behavior (specifically the Pin-safety) of `Self` are present.
///
/// Codifying this notion is the fact that `DerefMove` requires that `Self: DerefMut + AsMove`,
/// whereas `AsMove` only requires the weaker constraints of `Self: Deref`.
///
/// Although `AsMove` is a supertrait of `DerefMove`, but `DerefMove` is *not* a supertrait of
/// `AsMove`, the two traits are nevertheless intended to have their impls for a given type defined
/// together *simultanteously*.
///
/// It is expected in this situation that the impl for one of the traits will be (trivially) defined
/// in terms of the other, depending on the API for the pointer type `Self` with respect to
/// [`DerefMut`].
///
/// For example, the `Box<T>: AsMove` impl is defined in terms of the `Box<T>: DerefMove` impl,
/// because it is always the case that `Box<T>: DerefMut` regardless of whether `T: Unpin`. Hence,
/// `Box<T>: AsMove` simply performs the `Box<T>: DerefMove` operation then subsequently
/// (and trivially) pins the resulting `MoveRef<T>` with [`MoveRef::into_pin`].
///
/// On the other hand, the `cxx::UniquePtr<T>: DerefMove` impl is defined in terms of the
/// `UniquePtr<T>: AsMove` impl, because a `cxx::UniquePtr<T>: DerefMut` only if `T: Unpin`. Given
/// that `cxx::UniquePtr<T>` behaves like `Pin<Box<T>>` with respect to `DerefMut`, it is always
/// possible to safely produce a `Pin<MoveRef<T>>`, but *not* always possible to safely produce a
/// `MoveRef<T>`. Hence, when `T: Unpin`, only then `cxx::UniquePtr<T>: DerefMove` is defined,
/// which simply performs the `cxx::UniquePtr<T>: AsMove` operation then subsequently
/// (and trivially) unpins the resulting `Pin<MoveRef<T>>` with [`Pin::into_inner`].
pub trait AsMove: Deref + Sized {
  /// The "pure storage" form of `Self`, which owns the storage but not the
  /// pointee.
  type Storage: Sized;

  /// Gets a pinned `MoveRef` out of `Self`.
  ///
  /// This function is best paired with [`moveit!()`]:
  /// ```
  /// # use core::pin::Pin;
  /// # use moveit::{moveit, slot::DroppingSlot, move_ref::AsMove};
  /// let ptr = Box::pin(5);
  /// moveit::slot!(#[dropping] storage);
  /// ptr.as_move(storage);
  /// ```
  /// Taking a trip through [`moveit!()`] is unavoidable due to the nature of
  /// `MoveRef`.
  ///
  /// Compare with [`Pin::as_mut()`].
  fn as_move<'frame>(
    self,
    storage: DroppingSlot<'frame, Self::Storage>,
  ) -> Pin<MoveRef<'frame, Self::Target>>
  where
    Self: 'frame;
}

impl<'f, T: ?Sized> AsMove for MoveRef<'f, T> {
  type Storage = ();

  #[inline]
  fn as_move<'frame>(
    self,
    storage: DroppingSlot<'frame, Self::Storage>,
  ) -> Pin<MoveRef<'frame, Self::Target>>
  where
    Self: 'frame,
  {
    MoveRef::into_pin(DerefMove::deref_move(self, storage))
  }
}

impl<P: DerefMove> AsMove for Pin<P> {
  type Storage = P::Storage;

  #[inline]
  fn as_move<'frame>(
    self,
    storage: DroppingSlot<'frame, Self::Storage>,
  ) -> Pin<MoveRef<'frame, Self::Target>>
  where
    Self: 'frame,
  {
    unsafe {
      // SAFETY:
      //
      // It is safe to unwrap the `Pin` because `deref_move()` must not move out of the actual
      // storage, merely shuffle pointers around, and immediately after the call to `deref_move()`
      // we repin with `MoveRef::into_pin`, so the `Pin` API invariants are not violated later.
      MoveRef::into_pin(P::deref_move(Pin::into_inner_unchecked(self), storage))
    }
  }
}

/// Moving dereference operations.
///
/// *Note: This trait is intended to be defined in conjunction with [`AsMove`],
/// and there is a subtle interdependency between the two traits. We recommend
/// also reading it's documentation for a better understanding of how these
/// traits fit together.*
///
/// This trait is the `&move` analogue of [`Deref`], for taking a pointer that
/// is the *sole owner* its pointee and converting it to a [`MoveRef`]. In
/// particular, a pointer type `P` owns its contents if dropping it would cause
/// its pointee's destructor to run.
///
/// For example:
/// - [`MoveRef<T>`] implements `DerefMove` by definition.
/// - [`Box<T>`] implements `DerefMove`, since it drops the `T` in its
///   destructor.
/// - [`&mut T`] does *not* implement `DerefMove`, because it is
///   necessarily a borrow of a longer-lived, "truly owning" reference.
/// - [`Rc<T>`] and [`Arc<T>`] do *not* implement `DerefMove`, because even
///   though they own their pointees, they are not the *sole* owners. Dropping
///   a reference-counted pointer need not run the destructor if other pointers
///   are still alive.
/// - [`Pin<P>`] for `P: DerefMove` implements `DerefMove` only when
///   `P::Target: Unpin`, since `DerefMove: DerefMut`.
///
/// # Principle of Operation
///
/// Unfortunately, because we don't yet have language support for `&move`, we
/// need to break the implementation into two steps:
/// - Inhibit the "inner destructor" of the pointee, so that the smart pointer
///   is now managing dumb bytes. This is usually accomplished by converting the
///   pointee type to [`MaybeUninit<T>`].
/// - Extract a [`MoveRef`] out of the "deinitialized" pointer.
///
/// The first part of this consists of converting the pointer into the
/// "partially deinitialized" form, represented by the type
/// [`AsMove::Storage`]: it is the pointer as "pure storage".
///
/// This pointer should be placed into the [`DroppingSlot`] passed into
/// `deref_move`, so that it has a fixed lifetime for the duration of the frame
/// that the [`MoveRef`] will exist for. The [`DroppingSlot`] will also provide
/// a drop flag to use to build the returned [`MoveRef`].
///
/// The mutable reference returned by the [`DroppingSlot`] should then be
/// converted into a [`MoveRef`]. The end result is that the [`DroppingSlot`]
/// owns the "outer" part of the pointer, while the [`MoveRef`] owns the "inner"
/// part. The `'frame` lifetime enforces the correct destruction order of these
/// two parts, since the [`MoveRef`] borrows the [`DroppingSlot`].
///
/// The [`moveit!()`] macro helps by constructing the [`DroppingSlot`] for you.
///
/// ## Worked Example: [`Box<T>`]
///
/// To inhibit the inner destructor of [`Box<T>`], we can use `Box<MaybeUninit<T>>`
/// as [`AsMove::Storage`]. [`MaybeUninit`] is preferred over [`ManuallyDrop`],
/// since it helps avoid otherwise scary aliasing problems with `Box<&mut T>`.
///
/// The first step is to "cast" `Box<T>` into `Box<MaybeUninit<T>>` via
/// [`Box::into_raw()`] and [`Box::from_raw()`]. This is then placed into the
/// final storage location using [`DroppingSlot::put()`].
///
/// This returns a `&mut Box<MaybeUninit<T>>` and a [`DropFlag`]; the former is
/// converted into an `&mut T` via [`MaybeUninit::assume_init_mut()`].
///
/// Finally, [`MoveRef::new_unchecked()`] is used to combine these into the
/// return value.
///
/// The first step is safe because we construct a `MoveRef` to reinstate the
/// destructor at the end of the function. The second step is safe because
/// we know, a priori, that the `Box` contains an initialized value. The final
/// step is safe, because we know, a priori, that the `Box` owns its pointee.
///
/// The use of the drop flag in this way makes it so that dropping the resulting
/// `MoveRef` will leak the storage on the heap, exactly the same way as if we
/// had leaked a `Box`.
///
/// ## Worked Example: [`MoveRef<T>`]
///
/// We don't need to inhibit any destructors: we just need to convert a
/// `MoveRef<MoveRef<T>>` into a `MoveRef<T>`, which we can do by using
/// [`MoveRef::into_inner()`]. [`AsMove::Storage`] can be whatever, so we
/// simply choose [`()`] for this; the choice is arbitrary.
///
/// # Safety
///
/// Implementing `DerefMove` correctly requires that the uniqueness requirement
/// of [`MoveRef`] is upheld. In particular, the following function *must not*
/// violate memory safety:
/// ```
/// # use moveit::{DerefMove, MoveRef, moveit};
/// fn move_out_of<P>(p: P) -> P::Target
/// where
///   P: DerefMove,
///   P::Target: Sized,
/// {
///   unsafe {
///     // Replace `p` with a move reference into it.
///     moveit!(let p = &move *p);
///     
///     // Move out of `p`. From this point on, the `P::Target` destructor must
///     // run when, and only when, the function's return value goes out of
///     // scope per the usual Rust rules.
///     //
///     // In particular, the original `p` or any pointer it came from must not
///     // run the destructor when they go out of scope, under any circumstance.
///     MoveRef::into_inner(p)
///   }
/// }
/// ```
///
/// `deref_move()` must also be `Pin`-safe; even though it does not accept a
/// pinned reference, it must take care to not move its contents at any time.
/// In particular, the implementation of [`AsMove::as_move()`] must be safe by
/// definition.
pub unsafe trait DerefMove: DerefMut + AsMove {
  /// Moves out of `self`, producing a [`MoveRef`] that owns its contents.
  ///
  /// `storage` is a location *somewhere* responsible for rooting the lifetime
  /// of `*this`'s storage. The location is unimportant, so long as it outlives
  /// the resulting [`MoveRef`], which is enforced by the type signature.
  ///
  /// [`moveit!()`] provides a convenient syntax for calling this function.
  fn deref_move<'frame>(
    self,
    storage: DroppingSlot<'frame, Self::Storage>,
  ) -> MoveRef<'frame, Self::Target>
  where
    Self: 'frame;
}

unsafe impl<'a, T: ?Sized> DerefMove for MoveRef<'a, T> {
  #[inline]
  fn deref_move<'frame>(
    self,
    _storage: DroppingSlot<'frame, Self::Storage>,
  ) -> MoveRef<'frame, Self::Target>
  where
    Self: 'frame,
  {
    self
  }
}

/// Note that `DerefMove` cannot be used to move out of a `Pin<P>` when `P::Target: !Unpin`.
/// ```compile_fail
/// # use crate::{moveit::{Emplace, MoveRef, moveit}};
/// # use core::{marker::PhantomPinned, pin::Pin};
/// // Fails to compile because `Box<PhantomPinned>: Deref<Target = PhantomPinned>` and `PhantomPinned: !Unpin`.
/// let ptr: Pin<Box<PhantomPinned>> = Box::emplace(moveit::new::default::<PhantomPinned>());
/// moveit!(let mref = &move *ptr);
///
/// // Fails to compile because `MoveRef<PhantomPinned>: Deref<Target = PhantomPinned>` and `PhantomPinned: !Unpin`.
/// moveit! {
///   let mref0: Pin<MoveRef<PhantomPinned>> = moveit::new::default::<PhantomPinned>();
///   let mref1 = &move *mref0;
/// }
unsafe impl<P> DerefMove for Pin<P>
where
  P: DerefMove, // needed for `AsMove: Pin<P>` for the call to `Self::as_move`
  P::Target: Unpin, // needed for the call to `Pin::into_inner`
{
  #[inline]
  fn deref_move<'frame>(
    self,
    storage: DroppingSlot<'frame, Self::Storage>,
  ) -> MoveRef<'frame, Self::Target>
  where
    Self: 'frame,
  {
    Pin::into_inner(self.as_move(storage))
  }
}

#[doc(hidden)]
pub mod __macro {
  use super::*;
  use core::marker::PhantomData;

  /// Type-inference helper for `moveit!`.
  pub struct DerefPhantom<T>(PhantomData<*const T>);
  impl<T: DerefMove> DerefPhantom<T> {
    #[inline]
    pub fn new(_: &T) -> Self {
      Self(PhantomData)
    }

    #[inline]
    pub fn deref_move<'frame>(
      self,
      this: T,
      storage: DroppingSlot<'frame, T::Storage>,
    ) -> MoveRef<'frame, T::Target>
    where
      Self: 'frame,
    {
      T::deref_move(this, storage)
    }
  }
}

/// Performs an emplacement operation.
///
/// This macro allows for three exotic types of `let` bindings:
/// ```
/// # use moveit::{moveit, new, move_ref::MoveRef};
/// # use core::pin::Pin;
/// let bx = Box::new(42);
///
/// moveit! {
///   // Use a `New` to construct a new value in place on the stack. This
///   // produces a value of type `Pin<MoveRef<_>>`.
///   let x = new::default::<i32>();
///   
///   // Move out of an existing `DerefMove` type, such as a `Box`. This has
///   // type `MoveRef<_>`, but can be pinned using `MoveRef::into_pin()`.
///   let y = &move *bx;
///   
///   // Create a `MoveRef` of an existing type on the stack. This also has
///   // type `MoveRef<_>`.
///   let z = &move y;
/// }
/// ```
///
/// All three `lets`, including in-place construction, pin to the stack.
/// Consider using something like [`Box::emplace()`] to perform construction on
/// the heap.
///
/// This macro also has *temporary* forms, where rather than creating a binding,
/// a temporary (which cannot outlive its complete expression) is created:
///
/// ```
/// # use moveit::{moveit, new, move_ref::MoveRef};
/// # use core::pin::Pin;
/// fn do_thing(x: Pin<MoveRef<i32>>) {
///   // ...
/// # let _ = x;
/// }
///
/// do_thing(moveit!(new::of(42)));
/// ```
///
/// Note that these bindings cannot outlive the subexpression:
/// ```compile_fail
/// # use moveit::{moveit, new};
/// let x = moveit!(new::of(42));
/// let y = *x;  // Borrow checker error.
/// ```
///
/// [`Box::emplace()`]: crate::new::Emplace::emplace
#[macro_export]
macro_rules! moveit {
  (let $name:ident $(: $ty:ty)? = &move *$expr:expr $(; $($rest:tt)*)?) => {
    $crate::moveit!(@move $name, $($ty)?, $expr);
    $crate::moveit!($($($rest)*)?);
  };
  (let mut $name:ident $(: $ty:ty)? = &move *$expr:expr $(; $($rest:tt)*)?) => {
    $crate::moveit!(@move(mut) $name, $($ty)?, $expr);
    $crate::moveit!($($($rest)*)?);
  };
  (let $name:ident $(: $ty:ty)? = &move $expr:expr $(; $($rest:tt)*)?) => {
    $crate::moveit!(@put $name, $($ty)?, $expr);
    $crate::moveit!($($($rest)*)?);
  };
  (let mut $name:ident $(: $ty:ty)? = &move $expr:expr $(; $($rest:tt)*)?) => {
    $crate::emplace!(@put(mut) $name, $($ty)?, $expr);
    $crate::emplace!($($($rest)*)?);
  };
  (let $name:ident $(: $ty:ty)? = $expr:expr $(; $($rest:tt)*)?) => {
    $crate::moveit!(@emplace $name, $($ty)?, $expr);
    $crate::moveit!($($($rest)*)?);
  };
  (let mut $name:ident $(: $ty:ty)? = $expr:expr $(; $($rest:tt)*)?) => {
    $crate::moveit!(@emplace(mut) $name, $($ty)?, $expr);
    $crate::moveit!($($($rest)*)?);
  };
  ($(;)?) => {};

  (&move *$expr:expr) => {
    $crate::move_ref::DerefMove::deref_move(
      $expr, $crate::slot!(#[dropping]),
    )
  };

  (&move $expr:expr) => {$crate::slot!().put($expr)};
  ($expr:expr) => {$crate::slot!().emplace($expr)};

  (@move $(($mut:tt))? $name:ident, $($ty:ty)?, $expr:expr) => {
    $crate::slot!(#[dropping] storage);

    #[allow(unused_mut)]
    let $($mut)? $name $(: $ty)? = $crate::move_ref::DerefMove::deref_move($expr, storage);
  };
  (@put $(($mut:tt))? $name:ident, $($ty:ty)?, $expr:expr) => {
    $crate::slot!(slot);
    let $($mut)? $name $(: $ty)? = slot.put($expr);
  };
  (@emplace $(($mut:tt))? $name:ident, $($ty:ty)?, $expr:expr) => {
    $crate::slot!(slot);
    let $($mut)? $name $(: $ty)? = slot.emplace($expr);
  };
}

#[cfg(test)]
pub(crate) mod test {
  use crate::new;
  use crate::MoveNew;
  use crate::New;

  use super::*;
  use std::alloc;
  use std::alloc::Layout;
  use std::marker::PhantomPinned;
  use std::mem::MaybeUninit;

  #[test]
  fn deref_move_of_move_ref() {
    moveit! {
      let x: MoveRef<Box<i32>> = &move Box::new(5);
      let y: MoveRef<Box<i32>> = &move *x;
    }
    let _ = y;
  }

  #[test]
  fn deref_move_of_box() {
    let x = Box::new(5);
    moveit!(let y: MoveRef<i32> = &move *x);
    let _ = y;
  }

  #[test]
  fn move_ref_into_inner() {
    moveit!(let x: MoveRef<Box<i32>> = &move Box::new(5));
    let _ = MoveRef::into_inner(x);
  }

  #[test]
  #[should_panic]
  fn unforgettable() {
    moveit!(let x: MoveRef<i32> = &move 42);
    mem::forget(x);
  }

  #[test]
  #[should_panic]
  fn unforgettable_temporary() {
    mem::forget(moveit!(&move 42));
  }

  #[test]
  fn forgettable_box() {
    let mut x = Box::new(5);

    // Save the pointer for later, so that we can free it to make Miri happy.
    let ptr = x.as_mut() as *mut i32;

    moveit!(let y: MoveRef<i32> = &move *x);

    // This should leak but be otherwise safe.
    mem::forget(y);

    // Free the leaked pointer; Miri will notice if this turns out to be a
    // double-free.
    unsafe {
      alloc::dealloc(ptr as *mut u8, Layout::new::<i32>());
    }
  }

  #[test]
  fn forgettable_box_temporary() {
    let mut x = Box::new(5);

    // Save the pointer for later, so that we can free it to make Miri happy.
    let ptr = x.as_mut() as *mut i32;

    // This should leak but be otherwise safe.
    mem::forget(moveit!(&move *x));

    // Free the leaked pointer; Miri will notice if this turns out to be a
    // double-free.
    unsafe {
      alloc::dealloc(ptr as *mut u8, Layout::new::<i32>());
    }
  }

  // This type is reused in test code in cxx_support.
  #[derive(Default)]
  pub(crate) struct Immovable {
    _pin: PhantomPinned,
  }

  impl Immovable {
    pub(crate) fn new() -> impl New<Output = Self> {
      new::default()
    }
  }

  unsafe impl MoveNew for Immovable {
    unsafe fn move_new(
      _src: Pin<MoveRef<Self>>,
      _this: Pin<&mut MaybeUninit<Self>>,
    ) {
    }
  }

  #[test]
  fn test_mov() {
    moveit! {
      let foo = Immovable::new();
      let _foo = new::mov(foo);
    }
  }
}
