// 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
#![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`.

use std::marker::PhantomData;
use std::mem::{ManuallyDrop, MaybeUninit};
use std::ops::Deref;
use std::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<'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);
    }
}

/// !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<'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::RvalueReference(::std::pin::Pin::as_mut(&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 {
                std::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 std::mem::MaybeUninit;
    pub use std::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 { std::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 ::std::ptr::addr_of_mut;
                let drop_guard = ();
                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);
                )*
                ::std::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 _;
        std::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();
    std::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 std::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 std::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 std::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 = std::marker::PhantomPinned;
    unsafe fn ctor(self, dest: Pin<&mut MaybeUninit<Self::Output>>) {
        RustMoveCtor(std::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::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"]);
    }

    /// 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);
        fn takes_rvalue_reference(_: RvalueReference<S>) {}
        takes_rvalue_reference(mov!(x));
        // let _x = x; // fails to compile: x is moved!
    }

    #[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 std::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);
    // }
    // ```
}
