// tidy-alphabetical-start
#![cfg_attr(test, feature(test))]
#![feature(never_type)]
// tidy-alphabetical-end

pub(crate) use rustc_data_structures::fx::{FxIndexMap as Map, FxIndexSet as Set};

pub mod layout;
mod maybe_transmutable;

#[derive(Copy, Clone, Debug, Default)]
pub struct Assume {
    pub alignment: bool,
    pub lifetimes: bool,
    pub safety: bool,
    pub validity: bool,
}

/// Either transmutation is allowed, we have an error, or we have an optional
/// Condition that must hold.
#[derive(Debug, Hash, Eq, PartialEq, Clone)]
pub enum Answer<R, T> {
    Yes,
    No(Reason<T>),
    If(Condition<R, T>),
}

/// A condition which must hold for safe transmutation to be possible.
#[derive(Debug, Hash, Eq, PartialEq, Clone)]
pub enum Condition<R, T> {
    /// `Src` is transmutable into `Dst`, if `src` is transmutable into `dst`.
    Transmutable { src: T, dst: T },

    /// The region `long` must outlive `short`.
    Outlives { long: R, short: R },

    /// The `ty` is immutable.
    Immutable { ty: T },

    /// `Src` is transmutable into `Dst`, if all of the enclosed requirements are met.
    IfAll(Vec<Condition<R, T>>),

    /// `Src` is transmutable into `Dst` if any of the enclosed requirements are met.
    IfAny(Vec<Condition<R, T>>),
}

/// Answers "why wasn't the source type transmutable into the destination type?"
#[derive(Debug, Hash, Eq, PartialEq, PartialOrd, Ord, Clone)]
pub enum Reason<T> {
    /// The layout of the source type is not yet supported.
    SrcIsNotYetSupported,
    /// The layout of the destination type is not yet supported.
    DstIsNotYetSupported,
    /// The layout of the destination type is bit-incompatible with the source type.
    DstIsBitIncompatible,
    /// The destination type is uninhabited.
    DstUninhabited,
    /// The destination type may carry safety invariants.
    DstMayHaveSafetyInvariants,
    /// `Dst` is larger than `Src`, and the excess bytes were not exclusively uninitialized.
    DstIsTooBig,
    /// `Dst` is larger `Src`.
    DstRefIsTooBig {
        /// The referent of the source type.
        src: T,
        /// The size of the source type's referent.
        src_size: usize,
        /// The too-large referent of the destination type.
        dst: T,
        /// The size of the destination type's referent.
        dst_size: usize,
    },
    /// Src should have a stricter alignment than Dst, but it does not.
    DstHasStricterAlignment { src_min_align: usize, dst_min_align: usize },
    /// Can't go from shared pointer to unique pointer
    DstIsMoreUnique,
    /// Encountered a type error
    TypeError,
    /// The layout of src is unknown
    SrcLayoutUnknown,
    /// The layout of dst is unknown
    DstLayoutUnknown,
    /// The size of src is overflow
    SrcSizeOverflow,
    /// The size of dst is overflow
    DstSizeOverflow,
}

#[cfg(feature = "rustc")]
mod rustc {
    use rustc_hir::lang_items::LangItem;
    use rustc_middle::ty::{Const, Region, Ty, TyCtxt};

    use super::*;

    pub struct TransmuteTypeEnv<'tcx> {
        tcx: TyCtxt<'tcx>,
    }

    impl<'tcx> TransmuteTypeEnv<'tcx> {
        pub fn new(tcx: TyCtxt<'tcx>) -> Self {
            Self { tcx }
        }

        pub fn is_transmutable(
            &mut self,
            src: Ty<'tcx>,
            dst: Ty<'tcx>,
            assume: crate::Assume,
        ) -> crate::Answer<Region<'tcx>, Ty<'tcx>> {
            crate::maybe_transmutable::MaybeTransmutableQuery::new(src, dst, assume, self.tcx)
                .answer()
        }
    }

    impl Assume {
        /// Constructs an `Assume` from a given const-`Assume`.
        pub fn from_const<'tcx>(tcx: TyCtxt<'tcx>, ct: Const<'tcx>) -> Option<Self> {
            use rustc_middle::ty::ScalarInt;
            use rustc_span::sym;

            let cv = ct.try_to_value()?;
            let adt_def = cv.ty.ty_adt_def()?;

            if !tcx.is_lang_item(adt_def.did(), LangItem::TransmuteOpts) {
                tcx.dcx().delayed_bug(format!(
                    "The given `const` was not marked with the `{}` lang item.",
                    LangItem::TransmuteOpts.name()
                ));
                return Some(Self {
                    alignment: true,
                    lifetimes: true,
                    safety: true,
                    validity: true,
                });
            }

            let variant = adt_def.non_enum_variant();
            let fields = cv.to_branch();

            let get_field = |name| {
                let (field_idx, _) = variant
                    .fields
                    .iter()
                    .enumerate()
                    .find(|(_, field_def)| name == field_def.name)
                    .unwrap_or_else(|| panic!("There were no fields named `{name}`."));
                fields[field_idx].try_to_leaf().map(|leaf| leaf == ScalarInt::TRUE)
            };

            Some(Self {
                alignment: get_field(sym::alignment)?,
                lifetimes: get_field(sym::lifetimes)?,
                safety: get_field(sym::safety)?,
                validity: get_field(sym::validity)?,
            })
        }
    }
}

#[cfg(feature = "rustc")]
pub use rustc::*;
