// 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>>| {
                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 {
                        // SAFETY: the place is in bounds, just uninitialized. See e.g. second
                        // example: https://doc.rust-lang.org/nightly/std/ptr/macro.addr_of_mut.html
                        $crate::macro_internal::init_field(
                            &raw 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> {}

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

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

    #[gtest]
    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);
    }

    #[gtest]
    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.
    #[gtest]
    fn test_emplace_type() {
        let x: u32 = 42;
        emplace! {
            let foo = copy(&x);
        }
        let _foo: Pin<&mut u32> = foo; // type checks OK
    }

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

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

    #[gtest]
    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);
    }

    #[gtest]
    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);
    }

    #[gtest]
    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,
        });
    }

    #[gtest]
    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 {});}
    }

    #[gtest]
    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);
    }

    #[gtest]
    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);
    }

    #[gtest]
    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);
    }

    #[gtest]
    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);
    }

    #[gtest]
    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);
    }

    #[gtest]
    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.
    #[gtest]
    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.
    #[gtest]
    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.
    #[gtest]
    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.
    #[gtest]
    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());
    }

    #[gtest]
    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);
    }

    #[gtest]
    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.
    #[gtest]
    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.
    #[gtest]
    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.
    #[gtest]
    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!
    }

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

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

    #[gtest]
    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.
    #[gtest]
    fn test_slot_temporary() {
        assert_eq!(*emplace!(Slot::new(42)).as_opt().unwrap(), 42);
    }

    /// Test that a slot can be created in a local.
    #[gtest]
    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.
    #[gtest]
    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.
    #[gtest]
    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);
    }

    #[gtest]
    fn test_ctor_trait_captures() {
        fn adder<'a, 'b>(x: &'a i32, y: &'b i32) -> impl Ctor<Output = i32> + use<'a, '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);
    }
}
