// 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, vec_into_raw_parts, extern_types)]
#![cfg_attr(feature = "unstable", allow(incomplete_features), feature(unsized_const_params))]

//! This crate provides facilities for safely casting across multiple Rust types
//! that represent the same C++ type.  This is needed because:
//!
//! - In C++ one can interchangably use references to a forward-declared
//!   `struct` and references to the complete definition of the `struct`, but
//!   Rust bindings represent them using separate types (see `Incomplete<Name,
//!   Declarer>`).
//!
//! - In C++ one can interchangably use multiple independent C++ class template
//!   instantiations, but Rust bindings may represent them using separate types.
//!   This happens when the same class template is instantiated with the same
//!   template arguments in 2 different Crubit-generated crates with C++
//!   bindings.
//!
//! ## Forward declarations
//!
//! Given this C++:
//!
//! ```c++
//! namespace foo {
//! class Foo;
//! }  // namespace foo
//!
//! void MyFunction(foo::Foo& foo) {
//!   // can pass Foo around, but cannot access members, copy it, delete it, etc.
//!   some_other_library::OtherFunction(foo);
//! }
//! ```
//!
//! We can translate it to this equivalent Rust:
//!
//! ```
//! use forward_declare::{forward_declare, CppCast};
//!
//! forward_declare!(pub Foo = symbol!("foo::Foo"));
//! fn MyFunction(foo: &mut Foo) {
//!   some_other_library::OtherFunction(foo.cpp_cast());
//! }
//! ```
//!
//! On the reverse end, to **define** a type which may be forward-declared in
//! other crates, use the `unsafe_define!` macro:
//!
//! ```
//! pub struct Foo { ... }
//! unsafe_define!(symbol!("foo::Foo"), Foo);
//! ```
//!
//! The C++ forward declaration of a type `class Foo;` declares the name `Foo`
//! to be a type, but does not provide details such size and contents; such type
//! declaration is said to be incomplete. This is used in C++ to speed up build
//! performance (by omitting the real definition from the dependencies) and to
//! break up dependency cycles (by having one or both sides of the cycle
//! forward-declare pieces from the other side).
//!
//! In the general case, forward declarations in existing C++ code cannot be
//! removed without substantial changes. For example, a library can
//! forward-declare a class that is only defined in the binary. So a forward
//! declaration might not even have a single defining type, but one for
//! every binary that uses the library!
//!
//! Rust has close-enough equivalents to forward-declaration for constants and
//! functions, but not for types. This crate can be used wherever forward
//! declarations are used in C++, for those cases where forward declarations
//! cannot be avoided.
//!
//! ## Forward Declaring
//!
//! To forward declare a type which supports forward declarations, use the
//! `forward_declare` macro.
//!
//! ```
//! forward_declare!(pub YourType = symbol!("foo::YourType"));
//! ```
//!
//! This creates a public alias `pub YourType =
//! Incomplete<symbol!("foo::YourType"), ???>;`, where `???` is some type unique
//! to this scope. In particular, this means that different calls
//! to `forward_declare` produce different (but otherwise interchangeable)
//! types.
//!
//! Most user code won't need to directly use the `forward_declare!` macro and
//! can instead rely on forward declarations provided in the `..._rs_api` crates
//! generated by `rs_bindings_from_cc`.
//!
//! ## Providing a full definition
//!
//! For each type you wish to allow to be forward declared by others, give it a
//! globally unique name such as `"foo::YourType"`, and call
//! `unsafe_define!(symbol!("foo::YourType"), YourType)`.
//!
//! Most user code won't need to directly use the `unsafe_define!` macro and can
//! instead rely on definitions provided in the `..._rs_api` crates generated by
//! `rs_bindings_from_cc`.
//!
//! ## Supported casts
//!
//! Casting is supported between
//!
//!   * Two forward-declarations of the same C++ type,
//!   * A forward-declaration and a complete definition of the same C++ type,
//!   * Two complete definitions of the same C++ type (e.g. two identical class
//!     template instantiations).
//!
//! ### Pointers and references
//!
//! Casting is also supported for all of the following common pointer types
//! (e.g. a references to a forward-declared type can be cast to a reference to
//! a fully-defined type):
//!
//!   * `& _`
//!   * `&mut _`
//!   * `Pin<& _>`
//!   * `Pin<&mut _>`
//!   * `* const _`
//!   * `* mut _`
//!
//! `Box`, `Rc`, and `Arc` are excluded, because they require knowledge of the
//! `Drop` impl, and incomplete (e.g. forward-declared) types do not know how to
//! drop.
//!
//! Additionally, references can be cast to/from a corresponding `Pin`:
//!
//!   * `& T` <-> `Pin<&T>`
//!   * `&mut T` <-> `Pin<&mut T>` (only if `T: Unpin`).
//!
//! ### Containers
//!
//! If container's element type supports casting, then casting is also supported
//! for the following container types (e.g. a slice of references to a
//! forward-declared type can be cast to a slice of references to a
//! fully-defined type):
//!
//!   * Slices - `&[T]`
//!   * Arrays - `[T; N]`
//!   * `Vec<T>`
//!   * TODO: Add support for more containers as needed (HashSet?  bindings for
//!     std::vector?)
//!
//! ## Passing around values
//!
//! Compound data types implement the `CppCast` trait, which allows for
//! converting between complete and incomplete types. To convert from complete
//! to incomplete, incomplete to complete, or incomplete to incomplete when
//! crossing crate boundaries, use `.cpp_cast()` to perform the conversion.
//!
//! ```
//! forward_declare!(pub Foo = symbol!("foo::Foo"));
//!
//! fn takes_incomplete(foo: &mut Foo) {
//!   some_other_library::other_function(foo.cpp_cast());
//! }
//!
//! fn takes_complete(foo: &mut RealFoo) {
//!   takes_incomplete(foo.cpp_cast());
//! }
//! ```
//!
//! ## Crossing Crate Boundaries
//!
//! **Warning:** Users of incomplete types from other crates should not assume
//! that currently-incomplete types stay incomplete forever; code owners should
//! feel free to replace an incomplete type with a complete type.
//!
//! In Rust, unlike C++, the incomplete type and complete type are different
//! types. It is in theory a backwards-incompatible change to change from
//! incomplete to complete. Callers must try as much as possible to ease that
//! transition, since forward declarations are expected to be removed over time.
//!
//! This is partially enforced by the type system: every forward declaration of
//! a type is unique, and every crate should have its own forward declaration,
//! not reusing the forward declaration of another crate. As a result, you must
//! call `cpp_cast()` when crossing crate boundaries, and failure to do
//! so is an error:
//!
//!
//! ```compile_fail
//! # mod other_crate {
//! #   forward_declare!(pub ForwardDeclared = symbol!("foo::Type"));
//! #   pub fn function(x: &ForwardDeclared) {panic!()}
//! # }
//!
//! forward_declare!(pub ForwardDeclared = symbol!("foo::Type"));
//! let x: &ForwardDeclared = unimplemented!();
//! other_crate::function(x);  // ERROR
//! ```
//!
//! If that example were valid, then removing a forward declaration and
//! replacing it with the real type would break the caller, requiring a change
//! to call `cpp_cast()`. But since we always require the caller to call`
//! cpp_cast()` *anyway*, even if it already has an incomplete
//! type, `other_crate::function` is free to remove the forward declaration
//! without breaking this caller.
//!
//! ```no_run
//! # mod other_crate {
//! #   forward_declare!(pub ForwardDeclared = symbol!("foo::Type"));
//! #   pub fn function(x: &ForwardDeclared) {panic!()}
//! # }
//! #
//! # forward_declare!(pub ForwardDeclared = symbol!("foo::Type"));
//! # let x: &ForwardDeclared = unimplemented!();
//! other_crate::function(x.cpp_cast());  // Works whether `function` takes incomplete or complete type.
//! ```

pub use forward_declare_proc_macros::forward_declare;
#[cfg(not(feature = "unstable"))]
pub use forward_declare_proc_macros::symbol;

#[cfg(feature = "unstable")]
#[macro_export]
macro_rules! symbol {
    ($name:literal) => {
        $crate::internal::Symbol::<$name>
    };
}

/// Public to be exposed to macros, but otherwise for internal use only.
pub mod internal {
    /// `Symbol` type, equivalent to const &'static str values, but usable in
    /// generics in stable Rust.
    ///
    /// Every symbol is a tuple of `C`: for example, `symbol!("xy")` is
    /// `Symbol((C<'x'>, C<'y'>))`
    #[cfg(not(feature = "unstable"))]
    #[repr(C)]
    pub struct Symbol<T>(std::marker::PhantomData<T>);

    /// A character in a symbol string.
    #[cfg(not(feature = "unstable"))]
    #[repr(C)]
    pub struct C<const CHAR: char>;

    #[cfg(feature = "unstable")]
    pub struct Symbol<const SYMBOL: &'static str>;

    /// Types that implement the `CppType` trait with the same `Name` can be
    /// safely transmuted between each other, because they either provide
    /// bindings for the same C++ type, or point/refer to the same C++ type,
    /// or contain the same C++ type.
    ///
    /// Even though this trait is public, implementations of this trait should
    /// only be provided by Crubit itself:
    ///
    /// - Via `forward_declare!` and `unsafe_define!` macros
    /// - Via blanket `impl`s provided for references, pointers (e.g. see `mod
    ///   ref_transmutability` below).
    ///
    /// # Safety
    ///
    /// Two types implement `CppType` with the same name if and only if they can
    /// be transmuted to one another.
    pub unsafe trait CppType {
        /// `Name` helps Rust type system to identify the given transmutability
        /// equivalence class.
        ///
        /// `forward_declare!` and `unsafe_define!` macros form the `Name` using
        /// the `symbol!` macro, based on the fully-qualified name of
        /// the imported C++ type.
        ///
        /// In other scenarios, the `Name` is formed using an arbitrary
        /// convention that is sufficient to guarantee non-overlapping
        /// names (e.g. see the private `ref_transmutability::RefName`
        /// type alias below).
        type Name;
    }
}

use internal::*;

// TODO: cramertj - Move this to `extern "C"` type when extern types and the Sized heirarchy have
// stabilized.
//
// extern "C" {
//     /// Adding an `Unsized` field to your type makes it completely unsized
//     /// (not just dynamically-sized).
//     type Unsized;
// }
type Unsized = ();

/// A struct representing an "Incomplete Type" for `Name`
///
/// For any given name, there may be multiple "incomplete types" for that name
/// -- for example, `Incomplete<symbol!("T"), crate_1::T1>` is a different type
/// from `Incomplete<symbol!("T"), T2>`. This is intentional: in public
/// interfaces, an incomplete type is allowed to be changed to the complete type
/// without breaking callers.
///
/// TODO(jeanpierreda): make rust think this is ffi-safe. (PhantomData...)
#[repr(C)]
pub struct Incomplete<Name, Declarer>(std::marker::PhantomData<(Name, Declarer)>, Unsized);

// Ensure this is not `Unpin`, `Send`, or `Sync`. This is discussed somewhat in:
// https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs

/// Incomplete types can't be copied by value, because we don't know their true
/// size.
impl<Name, Declarer> !Unpin for Incomplete<Name, Declarer> {}
/// Similarly, we don't know if they are Send or Sync.
impl<Name, Declarer> !Send for Incomplete<Name, Declarer> {}
impl<Name, Declarer> !Sync for Incomplete<Name, Declarer> {}

/// Marker trait for complete types.
///
/// This is automatically implemented for anything `!Unpin`, but all other types
/// need to implement it by hand. Sorry, Rust just doesn't allow the kind of
/// negative reasoning we'd need to make this better.
///
/// In particular, this is *not* implemented for `Incomplete<...>`.
pub trait Complete {}

/// We know this to be true because `Incomplete<...>` is `!Unpin`.
///
/// Ideally we'd get a better blanket impl, but this very nearly covers
/// everything. Most `Unpin` types are going to be wrappers around C++ types,
/// which can auto-generate a `Complete` impl, and the rest are unlikely to
/// matter.
impl<T: Unpin> Complete for T {}

/// All forward declarations represented by `Incomplete<Name, ...>` form a
/// transmutability equivalence class (together with the complete definition(s)
/// - see the `unsafe_define!` macro below).
///
/// # Safety notes
///
/// We alias references to arbitrary `T` using references to `Incomplete`. This
/// is OK, because of the design of `Incomplete`:
///
/// - layout: `Incomplete` has no fields of size > 0, so it does not alias `T`
///   incompatibly.
///
/// - provenance: while in general it is not valid to access memory
///   **neighboring** that of a type    (e.g. one can't use &vec[0] to access
///   vec[1]), in this case, we are using    `feature(extern_types)`, which is a
///   DST which must grant access to the following memory or    else it would be
///   useless. (This type of access is the reason the feature exists).
unsafe impl<Name, Declarer> CppType for Incomplete<Name, Declarer> {
    type Name = Name;
}

/// `unsafe_define!(symbol!("..."), T)` claims that `T` is the unique definition
/// of the type identified by that symbol, and implements the conversions for
/// pointers to and from the corresponding `Incomplete` pointers.
///
/// Safety: if more than one type claim to be the definition, then they may be
/// transmuted into each other in safe code. The safety requirements for
/// `std::mem::transmute` apply.
#[macro_export]
macro_rules! unsafe_define {
    // TODO(jeanpierreda): support generic complete type (e.g. `symbol!("xyz") <-> Foo<T> where T : Bar`)
    ($Name:ty, $Complete:ty) => {
        unsafe impl $crate::internal::CppType for $Complete {
            type Name = $Name;
        }
    };
}

/// If `T` can be transmuted into `U`, then one can also transmute between
/// `*const T`, and `* const U`.  (This are always "thin" pointers - with the
/// same size as `usize`.)
unsafe impl<T: ?Sized> CppType for *const T
where
    T: CppType,
{
    type Name = (*const (), T::Name);
}

/// If `T` can be transmuted into `U`, then one can also transmute between `*mut
/// T`, and `*mut U`. These are always "thin" pointers - with the same size as
/// `usize`.
unsafe impl<T: ?Sized> CppType for *mut T
where
    T: CppType,
{
    type Name = (*mut (), T::Name);
}

/// If `T` can be transmuted into `U`, then one can also transmute between
/// arrays `[T; N]` and `[U; N]`.
///
/// # Safety notes
///
/// If `T` and `U` are transmutable then they should have the same alignment,
/// size, and stride.  Based on "Unsafe Code Guidelines Reference" [1], this
/// means that the arrays `[T; N]` and `[U, N]` have the same memory layout.
///
/// Note that `T` below has an implicit `T: Sized` constraint.  This means that
/// it is *not* possible to transmute into or out-of an array of
/// forward-declared types.  OTOH, it *is* possible to transmute between arrays
/// of transmutable, completely-defined/sized types (e.g. between arrays of
/// template instantiations).
///
/// [1]
/// https://rust-lang.github.io/unsafe-code-guidelines/layout/arrays-and-slices.html#layout-of-rust-array-types
unsafe impl<T, const N: usize> CppType for [T; N]
where
    T: CppType,
{
    type Name = ([(); N], T::Name);
}

/// If `T` can be transmuted into `U`, then one can also transmute between
/// slices `[T]` and `[U]`.
///
/// # Safety notes
///
/// ## Slices
///
/// "Unsafe Code Guidelines Reference" [1] points out that "the layout of a
/// slice [T] of length N is the same as that of a [T; N] array".  Therefore the
/// safety of slice tranmutability can just depend on the safety of array
/// transmutability and we can just refer to the safety notes for the
/// `impl ... for [T; N]`.
///
/// [1]
/// https://rust-lang.github.io/unsafe-code-guidelines/layout/arrays-and-slices.html#layout-of-rust-array-types
///
/// ## References to slices
///
/// The `impl` below only covers slices `[T]`, but it seems useful to talk here
/// about the safety of transmuting *references* to slices: `&[T]` (covered by
/// the `impl`s in the `ref_transmutability` module below).  Transmuting of such
/// "fat" pointers is safe based on "Unsafe Code Guidelines Reference" [2]
/// pointing out that the layout of `&[T]` is independent of T - it is expected
/// to have the same layout as:
///
/// ```rs
/// #[repr(C)]
/// struct Slice<T> {
///   ptr: *const T,
///   len: usize,
/// }
/// ```
///
/// [2] https://rust-lang.github.io/unsafe-code-guidelines/layout/pointers.html#notes
unsafe impl<T> CppType for [T]
where
    T: CppType,
{
    // Using somewhat icky `usize::MAX` to work around the fact that [()] is
    // unsized.
    type Name = ([(); usize::MAX], T::Name);
}

/// If `T` can be transmuted into `U`, then one can also transmute between `&'a
/// T`, `&'a U`, `Pin<&'a T>`, and `Pin<&'a U>`.  The corresponding CppType uses
/// `RefName` as the `Name` of the transmutability equivalence class.
///
/// # Safety
///
/// 1. `&T` => `&U`: Pointers to transmutable things are themselves
/// transmutable.  This is safe for    "thin" pointers (e.g. `&i32`) as well as
/// for "fat" pointers (e.g. `&[i32]` also stores the    size of the slice).
///
/// 2. `&T` => `Pin<&T>`: `Pin` is `repr(transparent)` and `Pin::new` is
/// safe.
///
/// 3. `Pin<&T>` => `&T`: `Pin` is `repr(transparent)` and `Pin::get_ref` is
/// safe.
///
/// 4. `Pin<&T>` => `Pin<&U>`: This combines transmutes 3, 1, and 2.
///
/// 5. `&T` => `Pin<&U>`: This combines transmutes 1 and 2.
///
/// 6. `Pin<&T>` => `&U`: This combines transmutes 4 and 3.
///
/// # Transmuting to the unpinned variant
///
/// We allow transmuting to the unpinned variant, when known to be safe.
///
/// ## Motivation
///
/// Consider what happens if a forward declaration in C++ is removed in favor of
/// the complete type, where the library containing that declaration was wrapped
/// in Rust. If the type is trivially relocatable, and we automatically generate
/// C++ bindings which do not use `Pin` except for non-trivially-relocatable
/// types, this would be a backwards incompatible change. So, we should
/// also support unpinning during the cast.
///
/// ## Limited scope of impls
///
/// Note: ideally we'd blanket impl the conversion to allow unpinning any smart
/// pointer type, and not only mut references, but this causes coherence issues,
/// because `Pin` itself is a smart pointer. I could not think of a workaround
/// that did not require specialization, other than to hardcode the set of
/// pointer types supported.
///
/// Since we're hardcoding a set of pointer types above *anyway*, we just need
/// to keep the list of unpinnable types in sync with the list of "pointers to
/// transmutable things" above.
mod ref_transmutability {
    use super::CppType;
    use std::pin::Pin;

    type RefName<'a, Name> = (&'a (), Name);

    /// Safety: See the doc comment for the `ref_transmutability` module.
    unsafe impl<'a, T: ?Sized> CppType for &'a T
    where
        T: CppType,
    {
        type Name = RefName<'a, T::Name>;
    }

    /// Safety: See the doc comment for the `ref_transmutability` module.
    unsafe impl<'a, T: ?Sized> CppType for Pin<&'a T>
    where
        T: CppType,
    {
        type Name = RefName<'a, T::Name>;
    }
}

/// If `T` can be transmuted into `U`, then one can also transmute
/// 1) between `&'a mut T` and `&'a mut U`
/// 2) between `Pin<&'a mut T>` and `Pin<&'a mut U>`
/// 3) from `&'a mut T` into `Pin<&'a mut T>` or into `Pin<&'a mut U>`
///
/// Additionally, if `T` and `U` are `Unpin`, then one can also transmute
/// 4) from `Pin<&'a mut T>` into `&'a mut T` or into `&'a mut U`
///
/// The corresponding CppType uses `MutRefName` as the `Name` of the
/// transmutability equivalence class.
///
/// # Safety
///
/// The list below is very similar to the safety notes for `RefName`, except
/// that the 3rd item below also needs to talk about the `T: Unpin` constraint.
///
/// 1. `&mut T` => `&mut U`: Pointers to transmutable things are themselves
/// transmutable.  This is    safe for "thin" pointers (e.g. `&i32`) as well as
/// for "fat" pointers (e.g. `&[i32]` also    stores the size of the slice).
///
/// 2. `&mut T` => `Pin<&mut T>`: `Pin` is `repr(transparent)` and `Pin::new`
///    is safe.
///
/// 3. `Pin<&mut T>` => `&mut T`: `Pin` is `repr(transparent)` and
/// `Pin::into_inner` is safe    and allowed for `T: Unpin`.
///
/// 4. `Pin<&mut T>` => `Pin<&mut U>`: This combines transmutes 3, 1, and 2.
///
/// 5. `&mut T` => `Pin<&mut U>`: This combines transmutes 1 and 2.
///
/// 6. `Pin<&mut T>` => `&mut U`: This combines transmutes 4 and 3.
///
/// # Transmuting to the unpinned variant
///
/// Transmuting to the unpinned variant is described in more details in the doc
/// comment of `RefName`.
mod mut_ref_transmutability {
    use super::CppType;
    use std::pin::Pin;

    type MutRefName<'a, Name> = (&'a mut (), Name);

    /// Safety: See the doc comment for the `mut_ref_transmutability` module.
    unsafe impl<'a, T: ?Sized> CppType for &'a mut T
    where
        T: CppType,
        T: Unpin, // See safety notes for MutRefName, item 3
    {
        type Name = MutRefName<'a, T::Name>;
    }

    /// Safety: See the doc comment for the `mut_ref_transmutability` module.
    unsafe impl<'a, T: ?Sized> CppType for Pin<&'a mut T>
    where
        T: CppType,
    {
        type Name = MutRefName<'a, T::Name>;
    }
}

/// Like `Into<T>`, but for completeness conversions.
pub trait CppCast<T> {
    fn cpp_cast(self) -> T;
}

impl<T, U> CppCast<U> for T
where
    T: CppType,
    U: CppType<Name = T::Name>,
{
    fn cpp_cast(self) -> U {
        assert_eq!(std::mem::size_of::<T>(), std::mem::size_of::<U>());
        let x = std::mem::ManuallyDrop::new(self);
        unsafe { std::mem::transmute_copy(&*x) }
    }
}

impl<'a, T: ?Sized, U: ?Sized> CppCast<Vec<&'a U>> for Vec<&'a T>
where
    T: CppType,
    U: CppType<Name = T::Name>,
{
    fn cpp_cast(self) -> Vec<&'a U> {
        let (p, len, capacity) = self.into_raw_parts();
        unsafe { Vec::from_raw_parts(p as *mut &'a U, len, capacity) }
    }
}

/// Like `CppCast<T>`, but allows for lifetime transmutes.
///
/// `UnsafeCppCast` can be used to cast from, for example, a C++ type that has no lifetime
/// information, to an idiomatic Rust type that does contain lifetime information.
///
/// # Safety
///
/// `UnsafeCppCast` is unsafe, because it allows to cast from a C++
/// type with unclear lifetime provenance into a Rust type.
/// TODO(jeanpierreda): create more & blanket impls for this.
pub unsafe trait UnsafeCppCast<'a, T>
where
    Self: 'a,
    T: 'a + Sized,
{
    /// Cast between types.
    ///
    /// # Safety
    ///
    /// `self` must be alive for at least 'a.
    unsafe fn unsafe_cpp_cast(self) -> T;
}
