// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#![cfg_attr(not(test), no_std)]
#![feature(negative_impls)]
//! Traits for memory management operations on wrapped C++ objects, based on
//! moveit.
//!
//! # Comparison with moveit
//!
//! ## Non-destructive move
//!
//! Unlike moveit, C++ moves are never Rust moves.
//!
//! This is important because it dramatically simplifies the mental model and
//! code involved. Everything to do with DerefMove can be removed. Furthermore,
//! it makes it *more useful*.
//!
//! In particular, imagine trying to write a *Rust* implementation of the
//! following C++ function:
//!
//! ```c++
//! void Swap(CxxClass& x, CxxClass& y) {
//!   CxxClass tmp = std::move(x);
//!   x = std::move(y);
//!   y = std::move(tmp);
//! }
//! ```
//!
//! With destructive moves we're in a bind: any move from x destroys its source,
//! leaving us with nothing to assign to. C++ moves are non-destructive. Traits
//! modeling C++ moves, therefore, in order to be most compatible, should also
//! be non-destructive.
//!
//! Here is an implementation using the traits in this file, in pure Rust:
//!
//! ```
//! fn swap(mut x: Pin<&mut CxxClass>, mut y: Pin<&mut CxxClass>) {
//!  emplace!{ let mut tmp = mov!(x.as_mut()); }
//!  x.assign(mov!(y.as_mut()));
//!  y.assign(mov!(tmp));
//! }
//! ```
//!
//! ## Curried `Ctor` traits
//!
//! Rather than `CopyCtor::copy_ctor` and `MoveCtor::move_ctor`, this crate
//! embraces `Ctor` itself as the single unique way to initialize everything.
//! And so copy-constructible types are not things which implement `CopyCtor`,
//! but rather, things which implement `CtorNew<&T>`. Similarly,
//! move-constructible things implement `CtorNew<RvalueReference<'_, T>>`.
//!
//! ## Blanket impls
//!
//! So that Rust types can be used against C++ functions (even templated ones),
//! the copy and move traits have blanket impls for all suitable Unpin types.
//!
//! More significantly, we take the position that all Unpin types are their own
//! `Ctor`. This makes `Ctor`-based initialization nearly a perfect superset of
//! normal initialization rules: for a non-self-referential Rust type (an Unpin
//! type), it looks the same as normal, but for C++-like !Unpin types we use
//! custom `Ctor` values to initialize in-place.
//!
//! Blanket implementing based on `Unpin` means that we're treating `T : Unpin`
//! as effectively meaning "T is safe to deal with by value", which is close to,
//! but not quite, what it means. (There are some types which are !Unpin but
//! would be safe to treat as normal rust types. Unfortunately, there is no way
//! to detect them.)
//!
//! ## Overload trait
//!
//! This module also includes a prototype alternative API which more directly
//! models overloaded constructors: `T : CtorNew<(A, B, C)>` is roughly
//! equivalent to the C++ "T has a constructor taking arguments of type A, B,
//! and C".
//!
//! ## StackBox
//!
//! Moveit needs a StackBox type which is comparable to Box, except stored on
//! the stack -- in particular, which implements OuterDrop and the like.
//!
//! Since DerefMove is not used here, we instead are able to export only a
//! Pin<&mut T> to users.
//!
//! One still needs something similar to `Slot` or `StackBox`: a `MaybeUninit`
//! type which will run drop. This isn't exposed to users directly if they are
//! simply storing in a local variable.
//!
//! ## Structs and the `ctor!` macro
//!
//! `ctor` adds a `ctor!` macro to make it easy to initialize a struct
//! that contains non-trivially-relocatable fields.
//!
//! ## Features
//!
//! This library requires the following unstable features enabled in users:
//!
//! **negative_impls:**
//! This is used to allow trait coherence checking for `!Unpin` types. A
//! "blanket impl for all `Unpin` types is used to make them constructible with
//! `ctor`, and Rust believes this may conflict with types that use
//! `PhantomPinned`. It knows no conflict exists if, instead, types impl
//! `!Unpin`.

extern crate alloc;

use alloc::boxed::Box;
use core::marker::{PhantomData, Unpin};
use core::mem::{ManuallyDrop, MaybeUninit};
use core::ops::{Deref, DerefMut};
use core::pin::Pin;

pub use ctor_proc_macros::*;

/// The string constant for #[must_use] to describe why you must use a `Ctor`.
macro_rules! must_use_ctor {
    () => {
        "A Ctor is not invoked unless emplaced, using e.g. `emplace!{}`, or `Box::emplace()`."
    };
}

/// The string constant for #[must_use] to describe why you must use a
/// `Ctor`/`Assign` source.
macro_rules! must_use_ctor_assign {
    ($name:literal) => {
        concat!(
            $name,
            " is not invoked unless emplaced, using e.g. `emplace!{}`, or `Box::emplace()`, or",
            " unless assigned from, using `.assign()`."
        )
    };
}

// ======================
// ~Unchanged from moveit
// ======================

#[must_use = must_use_ctor!()]
pub trait Ctor {
    type Output;
    unsafe fn ctor(self, dest: Pin<&mut MaybeUninit<Self::Output>>);

    /// Returns a chained Ctor, which will invoke `f` after construction.
    ///
    /// for example, these two snippets are equivalent:
    ///
    /// ```
    /// emplace! { let x = y; }
    /// x.mutating_method();
    /// ```
    ///
    /// ```
    /// emplace! { let x = y.ctor_then(|mut inited| inited.mutating_method()); }
    /// ```
    fn ctor_then<F: FnOnce(Pin<&mut Self::Output>)>(self, f: F) -> CtorThen<Self, F>
    where
        Self: Sized,
    {
        CtorThen { ctor: self, f }
    }
}

pub trait Emplace<T>: Sized {
    fn emplace<C: Ctor<Output = T>>(c: C) -> Pin<Self>;
}

impl<T> Emplace<T> for Box<T> {
    fn emplace<C: Ctor<Output = T>>(ctor: C) -> Pin<Box<T>> {
        let mut uninit = Box::new(MaybeUninit::<T>::uninit());
        unsafe {
            let pinned = Pin::new_unchecked(&mut *uninit);
            ctor.ctor(pinned);
            Pin::new_unchecked(Box::from_raw(Box::into_raw(uninit).cast::<T>()))
        }
    }
}

#[must_use = must_use_ctor!()]
pub struct FnCtor<Output, F: FnOnce(Pin<&mut MaybeUninit<Output>>)>(pub F, PhantomData<fn(Output)>);
impl<Output, F: FnOnce(Pin<&mut MaybeUninit<Output>>)> FnCtor<Output, F> {
    pub fn new(f: F) -> Self {
        Self(f, PhantomData)
    }
}

impl<Output, F: FnOnce(Pin<&mut MaybeUninit<Output>>)> Ctor for FnCtor<Output, F> {
    type Output = Output;

    unsafe fn ctor(self, dest: Pin<&mut MaybeUninit<Output>>) {
        self.0(dest);
    }
}

/// !Unpin to override the blanket Ctor impl.
impl<Output, F> !Unpin for FnCtor<Output, F> {}

/// Copy type.
///
/// This creates a new `P::Target` by copying -- either copy-construction
/// (construction from `&*P`), or copy-assignment (assignment from &*P`). It can
/// also be used directly as a `Ctor`.
///
/// Note: this does not actually copy `P` until it is used.
#[must_use = must_use_ctor_assign!("Copy")]
pub struct Copy<P: Deref>(P);

impl<Output: for<'a> CtorNew<&'a Output>, P: Deref<Target = Output>> Ctor for Copy<P> {
    type Output = Output;

    unsafe fn ctor(self, dest: Pin<&mut MaybeUninit<Output>>) {
        Output::ctor_new(&*self.0).ctor(dest);
    }
}

/// !Unpin to override the blanket Ctor impl.
impl<P> !Unpin for Copy<P> {}

/// Returns a `Copy` which can be used as a `CtorNew` or `Assign` source, or as
/// a `Ctor` directly.
///
/// Note: this does not actually copy the parameter until it is used.
pub fn copy<T: for<'a> CtorNew<&'a T>, P: Deref<Target = T>>(src: P) -> Copy<P> {
    Copy(src)
}

// ================================
// DerefMut based move construction
// ================================

/// Rvalue Reference (move-reference) type.
///
/// This creates a new `T` by moving -- either move-construction (construction
/// from `RvalueReference(&*P)`), or move-assignment (assignment from
/// `RvalueReference(&*P)`).
///
/// Note: this does not actually move until it is used.
#[must_use = must_use_ctor_assign!("RvalueReference")]
#[repr(transparent)]
pub struct RvalueReference<'a, T>(pub Pin<&'a mut T>);

impl<T> RvalueReference<'_, T> {
    pub fn as_const(&self) -> ConstRvalueReference<'_, T> {
        ConstRvalueReference(&*self.0)
    }

    pub fn as_mut(&mut self) -> Pin<&mut T> {
        self.0.as_mut()
    }

    pub fn get_ref(&self) -> &T {
        // It would be nice to return &'a T, but that would not be sound, and as a
        // result Pin makes it impossible (in safe code). Consider:
        //
        //   let my_pin: Pin<&mut T> = ...;
        //   let my_borrow = RvalueReference(my_pin.as_mut()).get_ref();
        //
        // The lifetime of my_borrow CANNOT be 'a, but instead MUST be scoped to the
        // reborrowed lifetime of the pin, or else it would violate the aliasing
        // rules by coexisting with my_pin. Thus, get_ref must return &T, not
        // &'a T. (For the same reason, as_const returns a ConstRvalueReference
        // whose lifetime is bound by self, not 'a.)
        &*self.0
    }
}

impl<T> Deref for RvalueReference<'_, T> {
    type Target = T;
    fn deref(&self) -> &Self::Target {
        self.get_ref()
    }
}

impl<'a, T> Ctor for RvalueReference<'a, T>
where
    T: CtorNew<Self>,
{
    type Output = T;

    unsafe fn ctor(self, dest: Pin<&mut MaybeUninit<T>>) {
        T::ctor_new(self).ctor(dest);
    }
}

/// Converts to an RvalueReference.
///
/// Do not use this trait directly, instead, cast to an RvalueReference using
/// the `mov!()` macro.
pub trait DerefRvalueReference: Deref
where
    Self::Target: Sized,
{
    fn deref_rvalue_reference(&mut self) -> RvalueReference<'_, Self::Target>;
}

impl<T> DerefRvalueReference for Pin<T>
where
    T: DerefMut,
    Self::Target: Sized,
{
    fn deref_rvalue_reference(&mut self) -> RvalueReference<'_, Self::Target> {
        RvalueReference(self.as_mut())
    }
}

impl<T> DerefRvalueReference for &mut T
where
    T: Unpin,
    Self::Target: Sized,
{
    fn deref_rvalue_reference(&mut self) -> RvalueReference<'_, Self::Target> {
        RvalueReference(Pin::new(self))
    }
}

/// !Unpin to override the blanket `Ctor` impl.
impl<'a, T> !Unpin for RvalueReference<'a, T> {}

/// Const rvalue reference (move-reference) type. Usually not very helpful.
///
/// This implicitly converts to `T` by const-moving -- either
/// const-move-construction (construction from `ConstRvalueReference(&x)`), or
/// const-move-assignment (assignment from `ConstRvalueReference(&x)`).
#[must_use = must_use_ctor_assign!("ConstRvalueReference")]
#[repr(transparent)]
pub struct ConstRvalueReference<'a, T>(pub &'a T);

impl<'a, T> ConstRvalueReference<'a, T> {
    pub fn get_ref(&mut self) -> &'a T {
        self.0
    }
}

impl<T> Deref for ConstRvalueReference<'_, T> {
    type Target = T;
    fn deref(&self) -> &Self::Target {
        self.0
    }
}

impl<'a, T> Ctor for ConstRvalueReference<'a, T>
where
    T: CtorNew<Self>,
{
    type Output = T;

    unsafe fn ctor(self, dest: Pin<&mut MaybeUninit<T>>) {
        T::ctor_new(self).ctor(dest);
    }
}

/// !Unpin to override the blanket `Ctor` impl.
impl<'a, T> !Unpin for ConstRvalueReference<'a, T> {}

/// Creates a "to-be-moved" pointer for `src`.
///
/// In other words, this is analogous to C++ `std::move`, except that this can
/// directly create an `RvalueReference<T>` out of e.g. a `Pin<Box<T>>`. The
/// resulting `RvalueReference` has the lifetime of a temporary, after which the
/// parameter is destroyed.
///
/// The resulting `RvalueReference` can be used as a `CtorNew` or `Assign`
/// source, or as a `Ctor` directly.
///
/// Note: this does not actually move the parameter until it is used.
#[macro_export]
macro_rules! mov {
    ($p:expr) => {
        $crate::DerefRvalueReference::deref_rvalue_reference(&mut { $p })
    };
}

#[macro_export]
macro_rules! const_mov {
    ($p:expr) => {
        $crate::ConstRvalueReference(&*{ $p })
    };
}

// =============
// Blanket impls
// =============
//
// For interop with C++ templates that may need to take Rust types, we will want
// blanket impls for Rust types where it is safe to do so.

/// All Rust types are their own constructor, if it is known to be safe (i.e.
/// Unpin).
///
/// (Note that this is an approximation: some types are safe to deal with by
/// value, as long as they have never been pinned. In `ctor`, we assume
/// that *anything* which is `!Unpin` is only safe to initialize via a manually
/// provided `Ctor`.)
///
/// (Note: to avoid overlapping impls, every type that implements `Ctor` by hand
/// must be `!Unpin`.)
///
/// This allows code to safely accept direct initialization of `Unpin` Rust
/// values, while also accepting `Ctor`-based initialization for `!Unpin`
/// values: use `Ctor`-based initialization for both, and as a special case,
/// `Ctor`-based initialization looks identical to direct initialization when
/// the value is `Unpin`. For example, the `ctor!` macro looks like direct
/// initialization for everything `Unpin`.
///
/// A contrasting design might be to have a separate initialization syntax for
/// direct vs `Ctor`-based initialization. However, that would still likely need
/// to be restricted to `Unpin` types for safety.
impl<T: Unpin> Ctor for T {
    type Output = T;
    unsafe fn ctor(self, mut dest: Pin<&mut MaybeUninit<Self>>) {
        dest.as_mut_ptr().write(self);
    }
}

/// Constructs via a Rust move.
#[must_use = must_use_ctor!()]
pub struct RustMoveCtor<T>(T);
impl<T> !Unpin for RustMoveCtor<T> {}
impl<T> Ctor for RustMoveCtor<T> {
    type Output = T;
    unsafe fn ctor(self, dest: Pin<&mut MaybeUninit<T>>) {
        Pin::into_inner_unchecked(dest).as_mut_ptr().write(self.0);
    }
}

/// All Rust types are C++-default-constructible if safe (i.e. Unpin + Default).
impl<T: Unpin + Default + Sized> CtorNew<()> for T {
    type CtorType = RustMoveCtor<Self>;
    fn ctor_new(_: ()) -> Self::CtorType {
        RustMoveCtor(Default::default())
    }
}

/// All Unpin Rust types are C++-copyable if they are Rust-cloneable.
///
/// (Unpin is required for safety; otherwise, this would violate the Pin
/// guarantee.)
impl<T: Unpin + Clone> CtorNew<&T> for T {
    type CtorType = RustMoveCtor<Self>;
    fn ctor_new(src: &Self) -> Self::CtorType {
        RustMoveCtor(src.clone())
    }
}

// ===========
// ctor_then()
// ===========

/// A `Ctor` which constructs using `self.ctor`, and then invokes `f` on the
/// resulting object.
///
/// This struct is created by the `ctor_then` method on `Ctor`. See its
/// documentation for more.
#[must_use = must_use_ctor!()]
pub struct CtorThen<C: Ctor, F: FnOnce(Pin<&mut C::Output>)> {
    ctor: C,
    f: F,
}

impl<C: Ctor, F: FnOnce(Pin<&mut C::Output>)> Ctor for CtorThen<C, F> {
    type Output = C::Output;
    unsafe fn ctor(self, mut dest: Pin<&mut MaybeUninit<Self::Output>>) {
        self.ctor.ctor(dest.as_mut());
        let dest = Pin::new_unchecked(Pin::into_inner_unchecked(dest).assume_init_mut());
        (self.f)(dest)
    }
}

impl<C: Ctor, F: FnOnce(Pin<&mut C::Output>)> !Unpin for CtorThen<C, F> {}

// ========
// emplace!
// ========
//
// The emplace!{} macro is now a little simpler, as it doesn't require StackBox
// in the public interface: it can use &mut.

/// Emplace a constructor into a local or temporary.
/// Syntax: `emplace! { let mut varname = expr() }`, where `expr()` evaluates to
/// a `Ctor<Output=T>`. `varname` will be a `Pin<&mut T>`.
///
/// If the emplaced value will just be used for the duration of one statement,
/// the `emplace!(ctor)` syntax can be used instead, to emplace the ctor into a
/// temporary. e.g. `foo(emplace!(ctor))` to pass a pinned reference to the
/// emplaced value to a function.
#[macro_export]
macro_rules! emplace {
    ($expr:expr) => {
        $crate::Slot::unsafe_new().unsafe_construct($expr).unsafe_as_pin_unchecked()
    };
    (@emplace_one let [$($mut_:tt)?] $var:ident [$($type_:tt)*]= $expr:expr;) => {
        let mut $var = $crate::Slot::unsafe_new();
        $var.unsafe_construct($expr);
        let $($mut_)* $var $($type_)* = $var.unsafe_as_pin_unchecked();
    };
    // Base case for repeated lets: empty emplace.
    () => {};
    // Recursive case: let [mut] x [: T] = ...;
    // There are four different combinations of mutability and explicit type parameter, we have to
    // match all of them.
    (let mut $var:ident : $t:ty = $expr:expr; $($remaining_lets:tt)*) => {
        $crate::emplace! {@emplace_one let [mut] $var [:$t] = $expr;}
        $crate::emplace! {$($remaining_lets)*};
    };
    (let mut $var:ident = $expr:expr; $($remaining_lets:tt)*) => {
        $crate::emplace! {@emplace_one let [mut] $var []= $expr;}
        $crate::emplace! {$($remaining_lets)*};
    };
    (let $var:ident : $t:ty  = $expr:expr; $($remaining_lets:tt)*) => {
        $crate::emplace! {@emplace_one let [] $var [:$t] = $expr;}
        $crate::emplace! {$($remaining_lets)*};
    };
    (let $var:ident = $expr:expr; $($remaining_lets:tt)*) => {
        $crate::emplace! {@emplace_one let [] $var [] = $expr;}
        $crate::emplace! {$($remaining_lets)*};
    };
}

// ====
// Slot
// ====
//
// Alternate design: we could expose without the is_initialized flag, which
// would require that all users initialize the type before drop. We may still
// need such a type for interop, since that can be repr(transparent). But it is
// *exceptionally* dangerous, as it requires that all code paths will initialize
// before drop. For example, it means that Ctor is not allowed to panic.
//
// Hypothesis: at least for local variables and reasoning, rustc will be able to
// elide the bool and be equally performant, while also being substantially
// safer.

/// A pinned optional type, which can store in-place constructed objects.
///
/// To create a slot safely, it must be constructed in place, using (for
/// example) the `emplace!` macro. It then can operate as a structurally pinned
/// variant of `Option`, allowing for pinned access to the interior.
///
/// Examples:
///
/// ```
/// // Slots can be used to implement a "slotted return value".
/// fn slotted_return(slot: Pin<&mut Slot<u32>>) -> Pin<&mut u32> {
///     slot.replace(42)
/// }
///
/// emplace! {let slot = Slot::uninit(); }
/// let rv = slotted_return(slot);
/// assert_eq!(*rv, 42);
/// ```
///
/// ```
/// // Slots can also be used for plain output parameters.
/// fn slotted_out_param(slot: Pin<&mut Slot<u32>>) {
///     slot.replace(42);
/// }
///
/// emplace! {let mut slot = Slot::uninit(); }
/// slotted_out_param(slot.as_mut());
/// assert_eq!(*slot.as_opt().unwrap(), 42);
/// ```
pub struct Slot<T> {
    is_initialized: bool,
    maybe_uninit: MaybeUninit<T>,
}

impl<T> Drop for Slot<T> {
    fn drop(&mut self) {
        unsafe { Pin::new_unchecked(self) }.clear()
    }
}

impl<T> !Unpin for Slot<T> {}

impl<T> Slot<T> {
    pub fn uninit() -> impl Ctor<Output = Self> {
        RustMoveCtor(Self::unsafe_new())
    }

    pub fn new(value: impl Ctor<Output = T>) -> impl Ctor<Output = Self> {
        RustMoveCtor(Self::unsafe_new()).ctor_then(|slot| {
            slot.replace(value);
        })
    }

    pub fn clear(self: Pin<&mut Self>) {
        if self.is_initialized {
            let Self { is_initialized, maybe_uninit } = unsafe { Pin::into_inner_unchecked(self) };
            unsafe {
                core::ptr::drop_in_place(maybe_uninit.as_mut_ptr());
            }
            *is_initialized = false;
        }
    }

    pub fn replace(mut self: Pin<&mut Self>, value: impl Ctor<Output = T>) -> Pin<&mut T> {
        self.as_mut().clear();
        {
            let Self { is_initialized, maybe_uninit } =
                unsafe { Pin::into_inner_unchecked(self.as_mut()) };
            unsafe {
                value.ctor(Pin::new_unchecked(maybe_uninit));
            }
            *is_initialized = true;
        }
        self.as_opt_mut().unwrap()
    }

    pub fn as_opt_mut(self: Pin<&mut Self>) -> Option<Pin<&mut T>> {
        if self.is_initialized {
            Some(unsafe { Pin::into_inner_unchecked(self) }.unsafe_as_pin_unchecked())
        } else {
            None
        }
    }

    pub fn as_opt(&self) -> Option<&T> {
        if self.is_initialized {
            Some(unsafe { self.maybe_uninit.assume_init_ref() })
        } else {
            None
        }
    }
}

// Hidden: these are only for use by safety macros.
#[doc(hidden)]
impl<T> Slot<T> {
    pub fn unsafe_new() -> Self {
        Slot { is_initialized: false, maybe_uninit: MaybeUninit::uninit() }
    }

    // The following two functions are not marked `unsafe` so that they can be
    // called from a single expression in a macro, without an `unsafe{}` block
    // which would also cover macro parameters.
    //
    // One alternative would be an immediately-invoked lambda, but this forces type
    // inference, which leads to confusing error messages when it isn't
    // inferrable. And, since this is a lambda, the type is not known concretely
    // to begin with!
    //
    // We could instead use a generic function with `impl Ctor` and the like, but
    // this function would be unsafe... leading back to the very original
    // problem!
    //
    // So here we bite the bullet: these functions should ideally be marked
    // "unsafe", but, seeing as they are only invoked from a macro, and that
    // macro needs to invoke expressions in calls to these functions, they are
    // only *named* "unsafe_foo" instead.

    /// Safety: must not have already been constructed, as that would violate
    /// the pin guarantee.
    pub fn unsafe_construct(&mut self, ctor: impl Ctor<Output = T>) -> &mut Self {
        unsafe { ctor.ctor(Pin::new_unchecked(&mut self.maybe_uninit)) };
        self.is_initialized = true;
        self
    }

    /// Safety: pin guarantee, assumes init.
    pub fn unsafe_as_pin_unchecked(&mut self) -> Pin<&mut T> {
        unsafe { Pin::new_unchecked(self.maybe_uninit.assume_init_mut()) }
    }
}

#[doc(hidden)]
pub mod macro_internal {
    use super::*;
    pub use core::mem::MaybeUninit;
    pub use core::pin::Pin;

    /// Workaround for more_qualified_paths.
    /// Instead of `<Foo as Bar>::Assoc { ... }`, which requires that feature,
    /// we can use `Identity<<Foo as Bar>::Assoc> { ... }`.
    ///
    /// See https://github.com/rust-lang/rust/issues/86935#issuecomment-1146670057
    ///
    /// TODO(jeanpierreda): Delete this when the feature is stabilized.
    pub type Identity<T> = T;

    /// Trait which causes compilation error if a `#[recursively_pinned]` struct
    /// impls `Drop`.
    ///
    /// Idea from https://docs.rs/pin-project/latest/pin_project/attr.pin_project.html#safety
    pub trait DoNotImplDrop {}
    #[allow(drop_bounds)]
    impl<T: Drop> DoNotImplDrop for T {}

    /// Drops a pointer when dropped.
    ///
    /// Safety: this will drop the pointer, so this is only safe if no other
    /// code will access the pointer afterwards. This includes drop: the
    /// pointer must itself be in a ManuallyDrop.
    pub struct UnsafeDropGuard<T>(*mut T);
    impl<T> Drop for UnsafeDropGuard<T> {
        fn drop(&mut self) {
            unsafe { core::ptr::drop_in_place(self.0) };
        }
    }

    /// Initializes a field, and returns a drop guard which will drop that
    /// field.
    ///
    /// Intended use: when initializing a struct field-by-field, each
    /// initialized field should be guarded in case of panic. Once the
    /// struct is completely initialized, the drop guards can be forgotten
    /// with `std::mem::forget()`. See the `ctor!` macro, where this is used.
    ///
    /// Safety: the field must satisfy the Pin guarantee.
    pub unsafe fn init_field<T>(field: *mut T, ctor: impl Ctor<Output = T>) -> impl Drop {
        // safety: MaybeUninit<T> is the same layout as T, the caller guarantees it's
        // pinned.
        let maybe_uninit = field as *mut MaybeUninit<T>;
        let pinned = Pin::new_unchecked(&mut *maybe_uninit);
        Ctor::ctor(ctor, pinned);
        UnsafeDropGuard(field)
    }

    pub fn require_recursively_pinned<_T: RecursivelyPinned>() {}
}

// =====================
// #[recursively_pinned]
// =====================

/// The `RecursivelyPinned` trait asserts that when the struct is pinned, every
/// field is also pinned.
///
/// This trait is automatically implemented for any `#[recursively_pinned]`
/// struct.
///
/// ## Safety
///
/// Only use if you never directly access fields of a pinned object. For
/// example, with the pin-project crate, all fields should be marked `#[pin]`.
pub unsafe trait RecursivelyPinned {
    /// An associated type with the same fields, minus any which are not
    /// initialized by the `ctor!()` macro.
    ///
    /// For example, the following struct `CtorOnly` can be constructed by value
    /// using `ctor!()`, but not using normal Rust initialization.
    /// Effectively, the struct is forced into only ever existing in a
    /// pinned state.
    ///
    /// ```
    /// // (Alternatively, `#[non_exhaustive]` may be used instead of the private field.)
    /// pub struct CtorOnly {
    ///   pub field: i32,
    ///   _must_construct_using_ctor: [(); 0],
    /// }
    ///
    /// // The same struct, but without the private field.
    /// // (Alternatively, without `#[non_exhaustive]`.)
    /// pub struct CtorOnlyFields {
    ///   pub field: i32,
    /// }
    ///
    /// unsafe impl RecursivelyPinned for CtorOnly {
    ///   type CtorInitializedFields = CtorOnlyFields;
    /// }
    /// ```
    ///
    /// By using `CtorInitializedFields` paired with a private field (or
    /// `#[non_exhaustive]`), the following code is now invalid:
    ///
    /// ```ignore
    /// # // TODO(jeanpierreda): make this tested, somehow.
    /// // Fails to compile: did not specify _must_construct_using_ctor, and cannot,
    /// // because it is private
    /// let x = CtorOnly {field: 3};
    /// ```
    ///
    /// While construction using `ctor!()` works fine:
    ///
    /// ```ignore
    /// emplace!{let x = ctor!(CtorOnly {field: 3})}
    /// ```
    ///
    /// The size and layout of `CtorInitializedFields` is ignored; it only
    /// affects which field names are required for complete `ctor!()`
    /// initialization. Any fields left out of the `CtorInitializedFields` type
    /// will not be initialized, so they should generally be zero-sized.
    type CtorInitializedFields;
}

/// The drop trait for `#[recursively_pinned(PinnedDrop)]` types.
///
/// It is never valid to implement `Drop` for a recursively-pinned type, as this
/// would be unsound: the `&mut self` in `drop` would allow the pin guarantee to
/// be violated.
///
/// Instead, if such a struct is to implement drop, it must pass `PinnedDrop` to
/// `recursively_pinned`, and implement the `PinnedDrop` trait.
///
/// See also the [analogous `pin_project` feature](https://docs.rs/pin-project/latest/pin_project/attr.pinned_drop.html)
pub trait PinnedDrop {
    /// Run the drop logic for self.
    ///
    /// ## Safety
    ///
    /// If called from anywhere other than the automatically-generated
    /// `Drop::drop`, the behavior is undefined.
    ///
    /// To manually drop the value, use `ManuallyDrop` or use
    /// `std::ptr::drop_in_place` (etc.) instead.
    unsafe fn pinned_drop(self: Pin<&mut Self>);
}

// =====
// ctor!
// =====

/// The `ctor!` macro evaluates to a `Ctor` for a Rust struct, with
/// user-specified fields.
///
/// (This was inspired by, but takes no code from, https://crates.io/crates/project-uninit.)
///
/// Example use:
///
/// ```
/// fn new() -> impl Ctor<Output=MyStruct> {
///   ctor!(MyStruct {field_1: default_ctor(), field_2: 42})
/// }
///
/// // Actually invoke the Ctor to create a new MyStruct:
/// emplace! { let mut my_struct = MyStruct::new(); }
/// ```
#[macro_export]
macro_rules! ctor {
    // Note: we're using `ident (::ident)*` for the type names because neither `ident` nor `path`
    // really work perfectly -- `ident` is great, except that `foo::bar` isn't an ident. `path` is
    // great, except that e.g. parentheses can't follow a path. (This is not fixable: FnOnce(T) is
    // also a path, so parens can't follow paths due to the ambiguous parse). Thus... we use ident,
    // and manually reconstruct the path.
    //
    // TODO(jeanpierreda): support <X as Y> and foo<Z> in paths.
    //
    // tt is used for the field names, because this allows for both integer fields for tuple
    // structs, and named fields for non-tuple structs.
    ( $t:ident $(:: $ts:ident)* {$( $name:tt: $sub_ctor:expr ),* $(,)?} ) => {
        {
            use $t $(:: $ts)* as Type;
            $crate::FnCtor::new(|x: $crate::macro_internal::Pin<&mut $crate::macro_internal::MaybeUninit<Type>>| {
                // Unused if Type is fieldless.
                #[allow(unused_imports)] use ::core::ptr::addr_of_mut;
                struct DropGuard;
                let drop_guard = DropGuard;
                let x_mut = unsafe{$crate::macro_internal::Pin::into_inner_unchecked(x)}.as_mut_ptr();
                let _ = &x_mut; // silence unused_variables warning if Type is fieldless.

                // Enforce that the ctor!() expression resembles a valid direct initialization
                // expression, by using the names in a conventional literal.
                // For structs, this fails to compile unless the names are fully exhaustive.
                // For unions, it fails to compile unless precisely one name is used.
                // In both cases, this ensures that we only compile when expressions corresponding
                // to normal init are used, with unsurprising semantics.
                let _ = |x: Type| {
                    let _ = &x; // silence unused_variables warning if Type is fieldless.
                    // If this fails to compile, not every field was specified in the ctor! invocation.
                    // The `panic!(...)` allows us to avoid moving out of x, while still pretending to
                    // fill in each field.
                    #[allow(unreachable_code, unused_unsafe)] $crate::macro_internal::Identity::<
                        <Type as $crate::RecursivelyPinned>::CtorInitializedFields> {
                            // unsafe {} block is in case this is a *union* literal, rather than
                            // a struct literal.
                            $($name: panic!("{}", unsafe {&x.$name} as *const _ as usize),)*
                        };
                };

                // Enforce that the type is RecursivelyPinned.
                $crate::macro_internal::require_recursively_pinned::<Type>();

                $(
                    let sub_ctor = $sub_ctor;
                    let field_drop = unsafe {
                        $crate::macro_internal::init_field(
                            // safety: this is almost verbatim the same as the second example at
                            // https://doc.rust-lang.org/nightly/std/ptr/macro.addr_of_mut.html
                            addr_of_mut!((*x_mut).$name),
                            sub_ctor)
                    };
                    let drop_guard = (drop_guard, field_drop);
                )*
                ::core::mem::forget(drop_guard);
            })
        }
    };

    // Unit struct ctor.
    ($t:ident $(:: $ts:ident)*) => {$crate::ctor!($t $(:: $ts)* {  })};

    // Conventional tuple struct syntax (with parens, no integer names) supported for < 8 fields.
    // Otherwise, use MyTupleStruct{0: ..., 1: ...} syntax, which works for any number of fields.
    // Generated as so:
    /* python3 -c 'for i in range(8):
        ctor_ins = ", ".join(f"$ctor_{j}:expr" for j in range(i))
        ctor_outs = ", ".join(f"{j}: $ctor_{j}" for j in range(i))
        print(f"    ($t:ident $(:: $ts:ident)* ({ctor_ins})) => {{$crate::ctor!($t $(:: $ts)* {{ {ctor_outs} }})}};")' */
    ($t:ident $(:: $ts:ident)* ()) => {$crate::ctor!($t $(:: $ts)* {  })};
    ($t:ident $(:: $ts:ident)* ($ctor_0:expr)) => {$crate::ctor!($t $(:: $ts)* { 0: $ctor_0 })};
    ($t:ident $(:: $ts:ident)* ($ctor_0:expr, $ctor_1:expr)) => {$crate::ctor!($t $(:: $ts)* { 0: $ctor_0, 1: $ctor_1 })};
    ($t:ident $(:: $ts:ident)* ($ctor_0:expr, $ctor_1:expr, $ctor_2:expr)) => {$crate::ctor!($t $(:: $ts)* { 0: $ctor_0, 1: $ctor_1, 2: $ctor_2 })};
    ($t:ident $(:: $ts:ident)* ($ctor_0:expr, $ctor_1:expr, $ctor_2:expr, $ctor_3:expr)) => {$crate::ctor!($t $(:: $ts)* { 0: $ctor_0, 1: $ctor_1, 2: $ctor_2, 3: $ctor_3 })};
    ($t:ident $(:: $ts:ident)* ($ctor_0:expr, $ctor_1:expr, $ctor_2:expr, $ctor_3:expr, $ctor_4:expr)) => {$crate::ctor!($t $(:: $ts)* { 0: $ctor_0, 1: $ctor_1, 2: $ctor_2, 3: $ctor_3, 4: $ctor_4 })};
    ($t:ident $(:: $ts:ident)* ($ctor_0:expr, $ctor_1:expr, $ctor_2:expr, $ctor_3:expr, $ctor_4:expr, $ctor_5:expr)) => {$crate::ctor!($t $(:: $ts)* { 0: $ctor_0, 1: $ctor_1, 2: $ctor_2, 3: $ctor_3, 4: $ctor_4, 5: $ctor_5 })};
    ($t:ident $(:: $ts:ident)* ($ctor_0:expr, $ctor_1:expr, $ctor_2:expr, $ctor_3:expr, $ctor_4:expr, $ctor_5:expr, $ctor_6:expr)) => {$crate::ctor!($t $(:: $ts)* { 0: $ctor_0, 1: $ctor_1, 2: $ctor_2, 3: $ctor_3, 4: $ctor_4, 5: $ctor_5, 6: $ctor_6 })};

}

// ==========
// CtorNew traits
// ==========
//
// Finally, we introduce some new traits for assignment.

/// Destroy-then-reconstruct. Sidesteps `operator=`, instead reconstructing
/// in-place.
///
/// If the object cannot be destroyed/reconstructed in place (e.g. it is a base
/// class subobject), the behavior is undefined.
///
/// If `ctor` unwinds, the process will crash.
///
/// This is a bit more fragile than, and a lot less common than, `operator=`,
/// but allows for taking advantage of copy/move elision more aggressively,
/// rather than requiring materialization into a temporary before triggering
/// assignment.
///
/// That means that e.g. instead of calling `x.assign(&*emplace!(foo))`, you can
/// directly call `x.reconstruct_unchecked(foo)` -- provided you are OK with the
/// differing constructor/destructor ordering, and satisfy safety criteria.
///
/// # Safety
///
/// Dividing sources of UB by language ruleset:
///
/// **C++**: The behavior is undefined if `self` is a base class subobject
/// or `[[no_unique_address]]` member.
///
/// See: http://eel.is/c++draft/basic.life#8
///
/// And see https://chat.google.com/room/AAAAl3r59xQ/auNOifgQa1c for discussion.
///
/// **Rust**: This is safe. Note that since this calls `drop()` on
/// the pinned pointer, it satisfies the pin guarantee, and is allowed to then
/// re-init it with something else. In effect, this is just the in-place Ctor
/// version of the existing method `Pin<T>::set(T)`.
pub trait ReconstructUnchecked: Sized {
    /// # Safety
    /// See trait documentation.
    unsafe fn reconstruct_unchecked(self: Pin<&mut Self>, ctor: impl Ctor<Output = Self>) {
        let self_ptr = Pin::into_inner_unchecked(self) as *mut _;
        core::ptr::drop_in_place(self_ptr);
        abort_on_unwind(move || {
            let maybe_uninit_self = &mut *(self_ptr as *mut MaybeUninit<Self>);
            ctor.ctor(Pin::new_unchecked(maybe_uninit_self));
        });
    }
}

impl<T> ReconstructUnchecked for T {}

/// Destroy-then-reconstruct. Sidesteps `operator=`, instead reconstructing
/// in-place.
///
/// If `ctor` unwinds, the process will crash.
///
/// This is a bit more fragile than, and a lot less common than, `operator=`,
/// but allows for taking advantage of copy/move elision more aggressively,
/// rather than requiring materialization into a temporary before triggering
/// assignment.
///
/// That means that e.g. instead of calling `x.assign(&*emplace!(foo))`, you can
/// directly call `x.reconstruct(foo)` -- provided you are OK with the differing
/// constructor/destructor ordering.
///
/// # Implementation safety
///
/// Implementors must ensure that it is safe to destroy and reconstruct the
/// object. Most notably, if `Self` is a C++ class, it must not be a base class.
/// See http://eel.is/c++draft/basic.life#8
///
/// # Safety
///
/// Note that this is not safe to call on `[[no_unique_address]]` member
/// variables, but the interface is marked safe, because those can only be
/// produced via unsafe means.
pub unsafe trait Reconstruct: ReconstructUnchecked {
    fn reconstruct(self: Pin<&mut Self>, ctor: impl Ctor<Output = Self>) {
        unsafe { self.reconstruct_unchecked(ctor) };
    }
}

/// Safety: anything implementing `Unpin` is Rust-assignable, and
/// Rust-assignment is inherently destroy+reconstruct.
unsafe impl<T: Unpin> Reconstruct for T {}

/// Run f, aborting if it unwinds.
///
/// Because this aborts on unwind, f is not required to be unwind-safe.
#[inline]
fn abort_on_unwind<T, F: FnOnce() -> T>(f: F) -> T {
    // Here is another way we COULD implement abort_on_panic:

    // let f = std::panic::AssertUnwindSafe(f);
    // let result = std::panic::catch_unwind(move || f.0());
    // if result.is_err() {
    //     std::process::abort();
    // }

    // It turns out this is a bad idea, because FFI unwinding, if/when added to
    // Rust, will sidestep catch_unwind, but NOT sidestep drop. So a C++
    // exception thrown in a Ctor might not get converted to a panic, but
    // instead to raw foreign unwinding, and drop impls in parent scopes
    // would be run. Since abort_on_unwind is intended to prevent *any* code from
    // executing and seeing temporarily-invalid state, this is incorrect.
    //
    // See e.g.: https://rust-lang.github.io/rfcs/2945-c-unwind-abi.html
    //
    // Instead, the only correct way to protect code from unwinding, even from
    // foreign unwinding, is via drop, as so:

    /// A safety guard which panics if dropped, converting unwinds into aborts.
    ///
    /// In general, you can't, as the *author* of drop(), assume that it will be
    /// called: callers can just call std::mem::forget(), among other
    /// things. However, as the *user*, you can know that drop is called for
    /// unmoved values at the end of a drop scope. Drop is a defined behavior.
    /// So while there is ordinarily a prohibition on relying on drop for
    /// safety, that only occurs for API owners that are allowing values to
    /// be used in arbitrary ways (including forget). Here, we are API
    /// *users* as well, and specifically using the Bomb in a way that
    /// guarantees its drop will be called in a particular circumstance.
    ///
    /// See https://doc.rust-lang.org/reference/destructors.html, specifically this: "When control
    /// flow leaves a drop scope all variables associated to that scope are
    /// dropped in reverse order of declaration (for variables) or creation
    /// (for temporaries)."
    struct Bomb;
    impl Drop for Bomb {
        fn drop(&mut self) {
            panic!("Unwinding occurred when no safe recovery is possible.");
        }
    }

    let bomb = Bomb;
    let rv = f();
    core::mem::forget(bomb);
    rv
}

/// Overloaded assignment operator.
///
/// Conventionally, C++ copy-assignment is Assign<&T>, and C++ move-assignment
/// is Assign<RvalueReference<'_, T>>.
pub trait Assign<From> {
    fn assign(self: Pin<&mut Self>, src: From);
}

/// Assignment from a Copy desugars to an assignment from a &T.
impl<T: for<'a> Assign<&'a T>, P: Deref<Target = T>> Assign<Copy<P>> for T {
    fn assign(self: Pin<&mut Self>, src: Copy<P>) {
        self.assign(&*src.0);
    }
}

// TODO(jeanpierreda): Make these less repetitive.

impl<'a, T: Unpin + CtorNew<&'a T>> Assign<&'a T> for T {
    fn assign(mut self: Pin<&mut Self>, src: &'a Self) {
        if core::mem::needs_drop::<Self>() {
            let mut constructed = MaybeUninit::uninit();
            unsafe {
                T::ctor_new(src).ctor(Pin::new(&mut constructed));
                *self = constructed.assume_init();
            }
        } else {
            self.reconstruct(T::ctor_new(src));
        }
    }
}

impl<'a, T: Unpin + CtorNew<RvalueReference<'a, T>>> Assign<RvalueReference<'a, T>> for T {
    fn assign(mut self: Pin<&mut Self>, src: RvalueReference<'a, Self>) {
        if core::mem::needs_drop::<Self>() {
            let mut constructed = MaybeUninit::uninit();
            unsafe {
                T::ctor_new(src).ctor(Pin::new(&mut constructed));
                *self = constructed.assume_init();
            }
        } else {
            self.reconstruct(T::ctor_new(src));
        }
    }
}

impl<'a, T: Unpin + CtorNew<ConstRvalueReference<'a, T>>> Assign<ConstRvalueReference<'a, T>>
    for T
{
    fn assign(mut self: Pin<&mut Self>, src: ConstRvalueReference<'a, Self>) {
        if core::mem::needs_drop::<Self>() {
            let mut constructed = MaybeUninit::uninit();
            unsafe {
                T::ctor_new(src).ctor(Pin::new(&mut constructed));
                *self = constructed.assume_init();
            }
        } else {
            self.reconstruct(T::ctor_new(src));
        }
    }
}

/// Overloaded assignment operator, but for Unpin types
///  TODO(b/219963671): use specialization instead of a distinct trait
pub trait UnpinAssign<From> {
    fn unpin_assign(&mut self, src: From);
}

// =======================
// Constructor overloading
// =======================
//
// Constructors are unique among C++ functions in that overloading is common,
// *not avoidable*, and involves a nameless function best captured by a trait.
// In other words, it is the ideal choice for having a more generic trait as
// with From/Into.
//
// For exploration purposes, so that we can play with both approaches at the
// same time, this is built on *top* of the traits above.

/// Overloaded constructor trait.
///
/// `T : CtorNew<(A, B, C)>` is roughly equivalent to the C++ "T has a
/// constructor taking arguments of type A, B, and C". As an obvious special
/// case, for singleton tuples, you may use `CtorNew<A>`.
pub trait CtorNew<ConstructorArgs> {
    type CtorType: Ctor<Output = Self>;

    fn ctor_new(args: ConstructorArgs) -> Self::CtorType;
}

// ====
// Misc
// ====

/// A constructor for `PhantomPinned`.
///
/// ## Why doesn't `PhantomPinned` implement `Ctor<Output=Self>` ?
///
/// A self-impl, where `PhantomPinned : Ctor<Output=PhantomPinned>` would also
/// have been safe, even though `PhantomPinned` is `!Unpin`, because it's just a
/// marker. However, the trait coherence rules are not happy about this:
///
/// ```
/// // crate_1
/// #![feature(negative_impls)]
/// pub struct Foo;
/// impl !Unpin for Foo {}
/// ```
///
/// ```
/// // crate_2
/// trait MyTrait {}
/// impl<T: Unpin> MyTrait for T{}
/// impl MyTrait for crate_1::Foo {}
/// ```
///
/// (In our case, `Foo` is `std::marker::PhantomPinned`, and `MyTrait` is
/// `Ctor`)
///
/// Within `crate_1`, Rust understands that `Foo` is `!Unpin`. So `impl MyTrait
/// for Foo {}` is valid in `crate_1`. However, outside of `crate_1`, Rust
/// decides it doesn't know whether `Foo` implements `Unpin` or not, and so
/// incorrectly believes that the impls may conflict.
///
/// So while it is perfectly feasible to implement self-construction for any
/// type locally, we cannot give foreign impls.
pub struct PhantomPinnedCtor;
impl Ctor for PhantomPinnedCtor {
    type Output = core::marker::PhantomPinned;
    unsafe fn ctor(self, dest: Pin<&mut MaybeUninit<Self::Output>>) {
        RustMoveCtor(core::marker::PhantomPinned).ctor(dest)
    }
}
impl !Unpin for PhantomPinnedCtor {}

/// A constructor for ManuallyDrop<T>, given a constructor for T.
///
/// ManuallyDrop is special as the only non-Copy type allowed in a union, so we
/// specifically support its use, even though it is not guaranteed to be
/// structurally pinned.
#[must_use = must_use_ctor!()]
pub struct ManuallyDropCtor<T: Ctor>(T);

impl<T: Ctor> ManuallyDropCtor<T> {
    /// Safety: this structurally pins the contents of ManuallyDrop.
    /// Therefore, it is not safe to use with anything that assumes that
    /// ManuallyDrop is not structurally pinned.
    pub unsafe fn new(x: T) -> Self {
        ManuallyDropCtor(x)
    }
}

impl<T: Ctor> Ctor for ManuallyDropCtor<T> {
    type Output = ManuallyDrop<T::Output>;
    unsafe fn ctor(self, dest: Pin<&mut MaybeUninit<Self::Output>>) {
        // Safety: ManuallyDrop<T> and T have the same layout.
        let dest = Pin::into_inner_unchecked(dest);
        let dest = &mut *(dest as *mut _ as *mut MaybeUninit<T::Output>);
        let dest = Pin::new_unchecked(dest);
        self.0.ctor(dest);
    }
}

impl<T: Ctor> !Unpin for ManuallyDropCtor<T> {}

/// A utility trait to add lifetime bounds to an `impl Ctor`.
///
/// When returning trait impls, captures don't work as one would expect;
/// see https://github.com/rust-lang/rust/issues/66551
///
/// For example, this function does not compile:
///
/// ```compile_fail
/// fn adder<'a, 'b>(x: &'a i32, y: &'b i32) -> impl Fn() -> i32 + 'a + 'b {
///   move || *a + *b
/// }
/// ```
///
/// However, using Captures, we can write the following, which _does_ compile:
///
/// ```
/// fn adder<'a, 'b>(x: &'a i32, y: &'b i32) -> impl Fn() -> i32 + Captures<'a> + Captures<'b> {
///   move || *a + *b
/// }
/// ```
///
/// Since `Ctor` is a in essence glorified `impl Fn(...)`, and will often need
/// to retain function inputs, this helper trait is provided for such a use.
pub trait Captures<'a> {}
impl<'a, T> Captures<'a> for T {}

#[cfg(test)]
mod test {
    use super::*;
    use std::cell::RefCell;
    use std::pin::Pin;
    use std::sync::Mutex;

    #[test]
    fn test_default_rust_type() {
        emplace! {let x = u32::ctor_new(());}
        assert_eq!(*x, 0);
    }

    #[test]
    fn test_copy_rust_type() {
        let x: u32 = 42;
        let mut y = Box::emplace(copy(&x));
        assert_eq!(x, 42);
        assert_eq!(*y, 42);

        // Can also mutate:
        let x = 50;
        y.as_mut().assign(&x);
        assert_eq!(x, 50);
        assert_eq!(*y, 50);

        // Can also mutate:
        let x = 100;
        y.as_mut().assign(copy(&x));
        assert_eq!(x, 100);
        assert_eq!(*y, 100);
    }

    #[test]
    fn test_copy_smart_ptr() {
        let x = Box::new(42_u32);
        emplace! {
            let y = copy(x);
        }
        // x is no longer in scope, as it was moved into the Copy.
        assert_eq!(*y, 42);
    }

    /// Tests that the assigned variables have the correct type.
    #[test]
    fn test_emplace_type() {
        let x: u32 = 42;
        emplace! {
            let foo = copy(&x);
        }
        let _foo: Pin<&mut u32> = foo; // type checks OK
    }

    #[test]
    fn test_emplace() {
        let x: u32 = 42;
        emplace! {
            let foo = copy(&x);
        }
        assert_eq!(*foo, 42);
    }

    #[test]
    fn test_emplace_mut() {
        let x: u32 = 42;
        emplace! {
            let mut foo = copy(&x);
        }
        assert_eq!(*foo, 42);
        *foo = 0;
        assert_eq!(*foo, 0);
    }

    #[test]
    fn test_emplace_multi() {
        let x: u32 = 42;
        emplace! {
            let foo = copy(&x);
            let bar = copy(&*foo);
        }
        assert_eq!(*foo, 42);
        assert_eq!(*bar, 42);
    }

    #[test]
    fn test_emplace_type_syntax() {
        let x: u32 = 42;
        emplace! {
            let mut foo: Pin<&mut u32> = copy(&x);
            let bar: Pin<&mut u32> = copy(&x);
        }
        assert_eq!(*foo, 42);
        *foo = 0;
        assert_eq!(*foo, 0);
        assert_eq!(*bar, 42);
    }

    #[test]
    fn test_ctor_macro() {
        struct MyStruct {
            x: u32,
            y: u32,
        }
        unsafe impl RecursivelyPinned for MyStruct {
            type CtorInitializedFields = Self;
        }
        emplace! { let my_struct = ctor!(MyStruct {
            x: 4,
            y: copy(&2)
        });}
        assert_eq!(my_struct.x, 4);
        assert_eq!(my_struct.y, 2);

        // test that trailing commas compile:
        #[rustfmt::skip]
        let _ = ctor!(MyStruct {
            x: 0,
            y: 0,
        });
    }

    #[test]
    fn test_ctor_macro_unit_struct() {
        struct MyStruct;
        unsafe impl RecursivelyPinned for MyStruct {
            type CtorInitializedFields = Self;
        }
        emplace! { let _my_struct = ctor!(MyStruct);}
        emplace! { let _my_struct = ctor!(MyStruct {});}
    }

    #[test]
    fn test_ctor_macro_named_tuple_struct() {
        struct MyStruct(u32, u32);
        unsafe impl RecursivelyPinned for MyStruct {
            type CtorInitializedFields = Self;
        }
        emplace! { let my_struct = ctor!(MyStruct {
            0: 4,
            1: copy(&2)
        });}
        assert_eq!(my_struct.0, 4);
        assert_eq!(my_struct.1, 2);
    }

    #[test]
    fn test_ctor_macro_tuple_struct() {
        struct MyStruct(u32, u32);
        unsafe impl RecursivelyPinned for MyStruct {
            type CtorInitializedFields = Self;
        }
        emplace! { let my_struct = ctor!(MyStruct (4, copy(&2)));}
        assert_eq!(my_struct.0, 4);
        assert_eq!(my_struct.1, 2);
    }

    #[test]
    fn test_ctor_macro_manuallydrop_struct() {
        struct MyStruct {
            x: ManuallyDrop<Vec<u32>>,
            y: u64,
        }
        unsafe impl RecursivelyPinned for MyStruct {
            type CtorInitializedFields = Self;
        }
        emplace! {let my_struct = ctor!(MyStruct {x: unsafe {ManuallyDropCtor::new(vec![42])}, y: 0 }); }
        assert_eq!(&*my_struct.x, &vec![42]);
        assert_eq!(my_struct.y, 0);
    }

    #[test]
    fn test_ctor_macro_union() {
        union MyUnion {
            x: ManuallyDrop<Vec<u32>>,
            y: u64,
        }
        unsafe impl RecursivelyPinned for MyUnion {
            type CtorInitializedFields = Self;
        }
        emplace! {let mut my_union = ctor!(MyUnion {x: unsafe { ManuallyDropCtor::new(vec![42])} }); }
        assert_eq!(unsafe { &*my_union.x }, &vec![42]);

        // And now write to the union.

        // First, should drop myunion.x.
        unsafe { ManuallyDrop::drop(&mut Pin::into_inner_unchecked(my_union.as_mut()).x) }
        // Second, we can overwrite.
        my_union.as_mut().reconstruct(ctor!(MyUnion { y: 24 }));
        assert_eq!(unsafe { my_union.y }, 24);
    }

    #[test]
    fn test_ctor_macro_nested_struct() {
        mod nested {
            pub struct MyStruct {
                pub x: u32,
                pub y: u32,
            }
            unsafe impl crate::RecursivelyPinned for MyStruct {
                type CtorInitializedFields = Self;
            }
        }
        emplace! { let my_struct = ctor!(nested::MyStruct {
            x: 4,
            y: copy(&2)
        });}
        assert_eq!(my_struct.x, 4);
        assert_eq!(my_struct.y, 2);
    }

    #[test]
    fn test_ctor_macro_nested_tuple_struct() {
        mod nested {
            pub struct MyStruct(pub u32, pub u32);
            unsafe impl crate::RecursivelyPinned for MyStruct {
                type CtorInitializedFields = Self;
            }
        }
        emplace! { let my_struct = ctor!(nested::MyStruct (4, copy(&2)));}
        assert_eq!(my_struct.0, 4);
        assert_eq!(my_struct.1, 2);
    }

    /// Test that the ctor macro safety check doesn't rely on the struct not
    /// implementing Drop.
    #[test]
    fn test_ctor_macro_drop_struct() {
        struct MyStruct {
            x: String,
        }
        unsafe impl RecursivelyPinned for MyStruct {
            type CtorInitializedFields = Self;
        }
        impl Drop for MyStruct {
            fn drop(&mut self) {}
        }

        emplace! { let _my_struct = ctor!(MyStruct {
            x: "".to_string()
        });}
    }

    /// Struct which sets a bool to true when dropped.
    ///
    /// We use Mutex so as to allow for mutating state in a way Rust believes is
    /// unwind-safe.
    struct DropNotify<'a>(&'a Mutex<bool>);

    impl Drop for DropNotify<'_> {
        fn drop(&mut self) {
            *self.0.lock().unwrap() = true;
        }
    }

    /// Ctor which constructs a DropNotify but panics before completing
    /// construction.
    ///
    /// This can be used to test both that a drop occurs (for e.g. previously
    /// constructed DropNotify objects), as well as that one does not:
    /// because it in fact does fully initialize the thing it is meant to
    /// construct, it is not UB to then call drop on it -- even though it would
    /// be UB for almost any other Ctor.
    #[must_use = must_use_ctor!()]
    struct PanicCtor<'a>(DropNotify<'a>);

    impl<'a> Ctor for PanicCtor<'a> {
        type Output = DropNotify<'a>;
        unsafe fn ctor(self, dest: Pin<&mut MaybeUninit<Self::Output>>) {
            self.0.ctor(dest);
            panic!();
        }
    }

    impl !Unpin for PanicCtor<'_> {}

    /// Tests that drop() is called when the Ctor doesn't panic.
    #[test]
    fn test_emplace_drop() {
        let is_dropped = Mutex::new(false);
        {
            emplace! { let _my_drop_notify = DropNotify(&is_dropped); }
        }
        assert!(*is_dropped.lock().unwrap());
    }

    /// Tests that when a panic occurs during emplace!{}, the uninitialized
    /// value is not dropped.
    #[test]
    fn test_emplace_no_drop_on_panic() {
        let is_dropped = Mutex::new(false);
        let panic_result = std::panic::catch_unwind(|| {
            emplace! { let _my_drop_notify = PanicCtor(DropNotify(&is_dropped)); }
        });
        assert!(panic_result.is_err());
        assert!(!*is_dropped.lock().unwrap());
    }

    /// Tests that when a panic occurs during initialization of a struct with
    /// ctor!, the initialized fields are dropped, and the uninitialized
    /// fields are not.
    #[test]
    fn test_ctor_macro_drop() {
        struct MyStruct<'a> {
            x: DropNotify<'a>,
            y: DropNotify<'a>,
        }
        unsafe impl RecursivelyPinned for MyStruct<'_> {
            type CtorInitializedFields = Self;
        }

        let x_dropped = Mutex::new(false);
        let y_dropped = Mutex::new(false);
        let panic_result = std::panic::catch_unwind(|| {
            emplace! { let _my_struct = ctor!(MyStruct {
                x: DropNotify(&x_dropped),
                y: PanicCtor(DropNotify(&y_dropped))
            });}
        });
        assert!(panic_result.is_err());
        assert!(*x_dropped.lock().unwrap());
        assert!(!*y_dropped.lock().unwrap());
    }

    #[test]
    fn test_ctor_initialized_fields_struct() {
        pub struct CtorOnly {
            pub field: i32,
            _must_construct_using_ctor: [(); 0],
        }

        pub struct CtorOnlyPubFields {
            pub field: i32,
        }

        unsafe impl RecursivelyPinned for CtorOnly {
            type CtorInitializedFields = CtorOnlyPubFields;
        }

        // Fails to compile: did not specify _must_construct_using_ctor, and cannot
        // (outside this crate) because it is private
        // let x = CtorOnly {field: 3};

        emplace! {let x = ctor!(CtorOnly {field: 3});}
        assert_eq!(x.field, 3);
    }

    #[test]
    fn ctor_initialized_fields_tuple_struct() {
        pub struct CtorOnly(pub i32, [(); 0]);
        pub struct CtorOnlyPubFields(i32);

        unsafe impl RecursivelyPinned for CtorOnly {
            type CtorInitializedFields = CtorOnlyPubFields;
        }

        // Fails to compile: did not specify field 1, and cannot (outside this crate)
        // because it is private
        // let x = CtorOnly(3);

        emplace! {let x = ctor!(CtorOnly(3));}
        assert_eq!(x.0, 3);
    }

    /// logs calls to the constructors, drop.
    struct DropCtorLogger<'a> {
        log: &'a RefCell<Vec<&'static str>>,
    }

    impl Drop for DropCtorLogger<'_> {
        fn drop(&mut self) {
            self.log.borrow_mut().push("drop");
        }
    }

    struct LoggingCtor<'a> {
        log: &'a RefCell<Vec<&'static str>>,
        ctor_message: &'static str,
    }

    impl<'a> Ctor for LoggingCtor<'a> {
        type Output = DropCtorLogger<'a>;
        unsafe fn ctor(self, mut dest: Pin<&mut MaybeUninit<Self::Output>>) {
            self.log.borrow_mut().push(self.ctor_message);
            dest.as_mut_ptr().write(DropCtorLogger { log: self.log });
        }
    }
    impl !Unpin for LoggingCtor<'_> {}

    impl<'a> CtorNew<&DropCtorLogger<'a>> for DropCtorLogger<'a> {
        type CtorType = LoggingCtor<'a>;
        fn ctor_new(src: &DropCtorLogger<'a>) -> Self::CtorType {
            LoggingCtor { log: &src.log, ctor_message: "copy ctor" }
        }
    }

    impl<'a> CtorNew<RvalueReference<'_, DropCtorLogger<'a>>> for DropCtorLogger<'a> {
        type CtorType = LoggingCtor<'a>;
        fn ctor_new(src: RvalueReference<'_, DropCtorLogger<'a>>) -> Self::CtorType {
            LoggingCtor { log: &src.0.log, ctor_message: "move ctor" }
        }
    }

    /// Tests the ctor/drop order for copy-constructible Unpin types: ctor comes
    /// before drop.
    #[test]
    fn test_copy_ctor_drop_order() {
        let log = RefCell::new(vec![]);
        let log = &log;

        emplace! {
            let notify_tester = DropCtorLogger {log};
            let new_value = DropCtorLogger {log};
        }
        notify_tester.assign(&*new_value);
        assert_eq!(*log.borrow(), vec!["copy ctor", "drop"]);
    }

    /// Tests the ctor/drop order for move-constructible Unpin types: ctor comes
    /// before drop.
    #[test]
    fn test_move_ctor_drop_order() {
        let log = RefCell::new(vec![]);
        let log = &log;

        emplace! {
            let notify_tester = DropCtorLogger {log};
            let new_value = DropCtorLogger {log};
        }
        notify_tester.assign(mov!(new_value));
        assert_eq!(*log.borrow(), vec!["move ctor", "drop"]);
    }

    fn takes_rvalue_reference<T>(_: RvalueReference<T>) {}
    /// Non-obvious fact: you can mov() an owned reference type! Moving anything
    /// also performs a rust move, but the resulting rvalue reference is
    /// still valid for a temporary's lifetime.
    #[test]
    fn test_mov_box() {
        struct S;
        let x: Pin<Box<S>> = Box::pin(S);
        takes_rvalue_reference(mov!(x));
        // let _x = x; // fails to compile: x is moved!
    }

    #[test]
    fn test_mov_mut_ref_to_unpin() {
        takes_rvalue_reference(mov!(&mut 1));
    }

    #[test]
    fn test_mov_pinned_mut_ref() {
        let x = &mut 2;
        let pinned_mut_ref = Pin::new(x);
        takes_rvalue_reference(mov!(pinned_mut_ref));
    }

    #[test]
    fn test_ctor_then() {
        emplace! {
            let x = 40.ctor_then(|mut y| { *y += 2 });
        }
        assert_eq!(*x, 42);
    }

    /// Test that a slot can be created in a temporary.
    #[test]
    fn test_slot_temporary() {
        assert_eq!(*emplace!(Slot::new(42)).as_opt().unwrap(), 42);
    }

    /// Test that a slot can be created in a local.
    #[test]
    fn test_slot_local() {
        emplace! {let slot = Slot::new(42); }
        assert_eq!(*slot.as_opt().unwrap(), 42);
    }

    /// Shows the use of Slot to implement a "slotted return value", similar to
    /// moveit.
    #[test]
    fn test_slotted_return_value() {
        // TODO(jeanpierreda): delete this, use doctests when doctests work.
        fn foo(slot: Pin<&mut Slot<u32>>) -> Pin<&mut u32> {
            slot.replace(42)
        }

        emplace! {let slot = Slot::uninit(); }
        let rv = foo(slot);
        assert_eq!(*rv, 42);
    }

    /// Shows the use of Slot to implement output parameters.
    #[test]
    fn test_slotted_output_parameter() {
        // TODO(jeanpierreda): delete this, use doctests when doctests work.
        fn foo(slot: Pin<&mut Slot<u32>>) {
            slot.replace(42);
        }

        emplace! {let mut slot = Slot::uninit(); }
        foo(slot.as_mut());
        assert_eq!(*slot.as_opt().unwrap(), 42);
    }

    #[test]
    fn test_ctor_trait_captures() {
        fn adder<'a, 'b>(
            x: &'a i32,
            y: &'b i32,
        ) -> impl Ctor<Output = i32> + Captures<'a> + Captures<'b> {
            FnCtor::new(|mut dest: Pin<&mut core::mem::MaybeUninit<i32>>| {
                dest.write(*x + *y);
            })
        }

        emplace! {
            let sum = adder(&40, &2);
        }
        assert_eq!(*sum, 42);
    }

    // The following test is broken due to https://github.com/rust-lang/rust/issues/66551
    // If that bug is fixed, this test should be uncommented, and `Captures`
    // deprecated and removed.
    //
    // ```
    // #[test]
    // fn test_ctor_native_captures() {
    //     fn adder<'a, 'b>(
    //         x: &'a i32,
    //         y: &'b i32,
    //     ) -> impl Ctor<Output = i32> + 'a + 'b {
    //         FnCtor::new(|mut dest: Pin<&mut std::mem::MaybeUninit<i32>>| {
    //             dest.write(*x + *y);
    //         })
    //     }

    //     emplace! {
    //         let sum = adder(&40, &2);
    //     }
    //     assert_eq!(*sum, 42);
    // }
    // ```
}
