//! Code for type-checking cast expressions.
//!
//! A cast `e as U` is valid if one of the following holds:
//! * `e` has type `T` and `T` coerces to `U`; *coercion-cast*
//! * `e` has type `*T`, `U` is `*U_0`, and either `U_0: Sized` or
//!    pointer_kind(`T`) = pointer_kind(`U_0`); *ptr-ptr-cast*
//! * `e` has type `*T` and `U` is a numeric type, while `T: Sized`; *ptr-addr-cast*
//! * `e` is an integer and `U` is `*U_0`, while `U_0: Sized`; *addr-ptr-cast*
//! * `e` has type `T` and `T` and `U` are any numeric types; *numeric-cast*
//! * `e` is a C-like enum and `U` is an integer type; *enum-cast*
//! * `e` has type `bool` or `char` and `U` is an integer; *prim-int-cast*
//! * `e` has type `u8` and `U` is `char`; *u8-char-cast*
//! * `e` has type `&[T; n]` and `U` is `*const T`; *array-ptr-cast*
//! * `e` is a function pointer type and `U` has type `*T`,
//!   while `T: Sized`; *fptr-ptr-cast*
//! * `e` is a function pointer type and `U` is an integer; *fptr-addr-cast*
//!
//! where `&.T` and `*T` are references of either mutability,
//! and where pointer_kind(`T`) is the kind of the unsize info
//! in `T` - the vtable for a trait definition (e.g., `fmt::Display` or
//! `Iterator`, not `Iterator<Item=u8>`) or a length (or `()` if `T: Sized`).
//!
//! Note that lengths are not adjusted when casting raw slices -
//! `T: *const [u16] as *const [u8]` creates a slice that only includes
//! half of the original memory.
//!
//! Casting is not transitive, that is, even if `e as U1 as U2` is a valid
//! expression, `e as U2` is not necessarily so (in fact it will only be valid if
//! `U1` coerces to `U2`).

use super::FnCtxt;

use crate::hir::def_id::DefId;
use crate::type_error_struct;
use rustc_ast::ast;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported};
use rustc_hir as hir;
use rustc_hir::lang_items;
use rustc_middle::ty::adjustment::AllowTwoPhase;
use rustc_middle::ty::cast::{CastKind, CastTy};
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, Ty, TypeAndMut, TypeFoldable};
use rustc_session::lint;
use rustc_session::Session;
use rustc_span::symbol::sym;
use rustc_span::Span;
use rustc_trait_selection::traits;
use rustc_trait_selection::traits::error_reporting::report_object_safety_error;

/// Reifies a cast check to be checked once we have full type information for
/// a function context.
pub struct CastCheck<'tcx> {
    expr: &'tcx hir::Expr<'tcx>,
    expr_ty: Ty<'tcx>,
    cast_ty: Ty<'tcx>,
    cast_span: Span,
    span: Span,
}

/// The kind of pointer and associated metadata (thin, length or vtable) - we
/// only allow casts between fat pointers if their metadata have the same
/// kind.
#[derive(Copy, Clone, PartialEq, Eq)]
enum PointerKind<'tcx> {
    /// No metadata attached, ie pointer to sized type or foreign type
    Thin,
    /// A trait object
    Vtable(Option<DefId>),
    /// Slice
    Length,
    /// The unsize info of this projection
    OfProjection(&'tcx ty::ProjectionTy<'tcx>),
    /// The unsize info of this opaque ty
    OfOpaque(DefId, SubstsRef<'tcx>),
    /// The unsize info of this parameter
    OfParam(&'tcx ty::ParamTy),
}

impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
    /// Returns the kind of unsize information of t, or None
    /// if t is unknown.
    fn pointer_kind(
        &self,
        t: Ty<'tcx>,
        span: Span,
    ) -> Result<Option<PointerKind<'tcx>>, ErrorReported> {
        debug!("pointer_kind({:?}, {:?})", t, span);

        let t = self.resolve_vars_if_possible(&t);

        if t.references_error() {
            return Err(ErrorReported);
        }

        if self.type_is_known_to_be_sized_modulo_regions(t, span) {
            return Ok(Some(PointerKind::Thin));
        }

        Ok(match t.kind {
            ty::Slice(_) | ty::Str => Some(PointerKind::Length),
            ty::Dynamic(ref tty, ..) => Some(PointerKind::Vtable(tty.principal_def_id())),
            ty::Adt(def, substs) if def.is_struct() => match def.non_enum_variant().fields.last() {
                None => Some(PointerKind::Thin),
                Some(f) => {
                    let field_ty = self.field_ty(span, f, substs);
                    self.pointer_kind(field_ty, span)?
                }
            },
            ty::Tuple(fields) => match fields.last() {
                None => Some(PointerKind::Thin),
                Some(f) => self.pointer_kind(f.expect_ty(), span)?,
            },

            // Pointers to foreign types are thin, despite being unsized
            ty::Foreign(..) => Some(PointerKind::Thin),
            // We should really try to normalize here.
            ty::Projection(ref pi) => Some(PointerKind::OfProjection(pi)),
            ty::Opaque(def_id, substs) => Some(PointerKind::OfOpaque(def_id, substs)),
            ty::Param(ref p) => Some(PointerKind::OfParam(p)),
            // Insufficient type information.
            ty::Placeholder(..) | ty::Bound(..) | ty::Infer(_) => None,

            ty::Bool
            | ty::Char
            | ty::Int(..)
            | ty::Uint(..)
            | ty::Float(_)
            | ty::Array(..)
            | ty::GeneratorWitness(..)
            | ty::RawPtr(_)
            | ty::Ref(..)
            | ty::FnDef(..)
            | ty::FnPtr(..)
            | ty::Closure(..)
            | ty::Generator(..)
            | ty::Adt(..)
            | ty::Never
            | ty::Error(_) => {
                self.tcx
                    .sess
                    .delay_span_bug(span, &format!("`{:?}` should be sized but is not?", t));
                return Err(ErrorReported);
            }
        })
    }
}

#[derive(Copy, Clone)]
enum CastError {
    ErrorReported,

    CastToBool,
    CastToChar,
    DifferingKinds,
    /// Cast of thin to fat raw ptr (e.g., `*const () as *const [u8]`).
    SizedUnsizedCast,
    IllegalCast,
    NeedDeref,
    NeedViaPtr,
    NeedViaThinPtr,
    NeedViaInt,
    NonScalar,
    UnknownExprPtrKind,
    UnknownCastPtrKind,
}

impl From<ErrorReported> for CastError {
    fn from(ErrorReported: ErrorReported) -> Self {
        CastError::ErrorReported
    }
}

fn make_invalid_casting_error<'a, 'tcx>(
    sess: &'a Session,
    span: Span,
    expr_ty: Ty<'tcx>,
    cast_ty: Ty<'tcx>,
    fcx: &FnCtxt<'a, 'tcx>,
) -> DiagnosticBuilder<'a> {
    type_error_struct!(
        sess,
        span,
        expr_ty,
        E0606,
        "casting `{}` as `{}` is invalid",
        fcx.ty_to_string(expr_ty),
        fcx.ty_to_string(cast_ty)
    )
}

impl<'a, 'tcx> CastCheck<'tcx> {
    pub fn new(
        fcx: &FnCtxt<'a, 'tcx>,
        expr: &'tcx hir::Expr<'tcx>,
        expr_ty: Ty<'tcx>,
        cast_ty: Ty<'tcx>,
        cast_span: Span,
        span: Span,
    ) -> Result<CastCheck<'tcx>, ErrorReported> {
        let check = CastCheck { expr, expr_ty, cast_ty, cast_span, span };

        // For better error messages, check for some obviously unsized
        // cases now. We do a more thorough check at the end, once
        // inference is more completely known.
        match cast_ty.kind {
            ty::Dynamic(..) | ty::Slice(..) => {
                check.report_cast_to_unsized_type(fcx);
                Err(ErrorReported)
            }
            _ => Ok(check),
        }
    }

    fn report_cast_error(&self, fcx: &FnCtxt<'a, 'tcx>, e: CastError) {
        match e {
            CastError::ErrorReported => {
                // an error has already been reported
            }
            CastError::NeedDeref => {
                let error_span = self.span;
                let mut err = make_invalid_casting_error(
                    fcx.tcx.sess,
                    self.span,
                    self.expr_ty,
                    self.cast_ty,
                    fcx,
                );
                let cast_ty = fcx.ty_to_string(self.cast_ty);
                err.span_label(
                    error_span,
                    format!("cannot cast `{}` as `{}`", fcx.ty_to_string(self.expr_ty), cast_ty),
                );
                if let Ok(snippet) = fcx.sess().source_map().span_to_snippet(self.expr.span) {
                    err.span_suggestion(
                        self.expr.span,
                        "dereference the expression",
                        format!("*{}", snippet),
                        Applicability::MaybeIncorrect,
                    );
                } else {
                    err.span_help(self.expr.span, "dereference the expression with `*`");
                }
                err.emit();
            }
            CastError::NeedViaThinPtr | CastError::NeedViaPtr => {
                let mut err = make_invalid_casting_error(
                    fcx.tcx.sess,
                    self.span,
                    self.expr_ty,
                    self.cast_ty,
                    fcx,
                );
                if self.cast_ty.is_integral() {
                    err.help(&format!(
                        "cast through {} first",
                        match e {
                            CastError::NeedViaPtr => "a raw pointer",
                            CastError::NeedViaThinPtr => "a thin pointer",
                            _ => bug!(),
                        }
                    ));
                }
                err.emit();
            }
            CastError::NeedViaInt => {
                make_invalid_casting_error(
                    fcx.tcx.sess,
                    self.span,
                    self.expr_ty,
                    self.cast_ty,
                    fcx,
                )
                .help(&format!(
                    "cast through {} first",
                    match e {
                        CastError::NeedViaInt => "an integer",
                        _ => bug!(),
                    }
                ))
                .emit();
            }
            CastError::IllegalCast => {
                make_invalid_casting_error(
                    fcx.tcx.sess,
                    self.span,
                    self.expr_ty,
                    self.cast_ty,
                    fcx,
                )
                .emit();
            }
            CastError::DifferingKinds => {
                make_invalid_casting_error(
                    fcx.tcx.sess,
                    self.span,
                    self.expr_ty,
                    self.cast_ty,
                    fcx,
                )
                .note("vtable kinds may not match")
                .emit();
            }
            CastError::CastToBool => {
                let mut err =
                    struct_span_err!(fcx.tcx.sess, self.span, E0054, "cannot cast as `bool`");

                if self.expr_ty.is_numeric() {
                    match fcx.tcx.sess.source_map().span_to_snippet(self.expr.span) {
                        Ok(snippet) => {
                            err.span_suggestion(
                                self.span,
                                "compare with zero instead",
                                format!("{} != 0", snippet),
                                Applicability::MachineApplicable,
                            );
                        }
                        Err(_) => {
                            err.span_help(self.span, "compare with zero instead");
                        }
                    }
                } else {
                    err.span_label(self.span, "unsupported cast");
                }

                err.emit();
            }
            CastError::CastToChar => {
                type_error_struct!(
                    fcx.tcx.sess,
                    self.span,
                    self.expr_ty,
                    E0604,
                    "only `u8` can be cast as `char`, not `{}`",
                    self.expr_ty
                )
                .span_label(self.span, "invalid cast")
                .emit();
            }
            CastError::NonScalar => {
                let mut err = type_error_struct!(
                    fcx.tcx.sess,
                    self.span,
                    self.expr_ty,
                    E0605,
                    "non-primitive cast: `{}` as `{}`",
                    self.expr_ty,
                    fcx.ty_to_string(self.cast_ty)
                );
                let mut sugg = None;
                if let ty::Ref(reg, _, mutbl) = self.cast_ty.kind {
                    if fcx
                        .try_coerce(
                            self.expr,
                            fcx.tcx.mk_ref(reg, TypeAndMut { ty: self.expr_ty, mutbl }),
                            self.cast_ty,
                            AllowTwoPhase::No,
                        )
                        .is_ok()
                    {
                        sugg = Some(format!("&{}", mutbl.prefix_str()));
                    }
                }
                if let Some(sugg) = sugg {
                    err.span_label(self.span, "invalid cast");
                    err.span_suggestion_verbose(
                        self.expr.span.shrink_to_lo(),
                        "borrow the value for the cast to be valid",
                        sugg,
                        Applicability::MachineApplicable,
                    );
                } else if !matches!(
                    self.cast_ty.kind,
                    ty::FnDef(..) | ty::FnPtr(..) | ty::Closure(..)
                ) {
                    let mut label = true;
                    // Check `impl From<self.expr_ty> for self.cast_ty {}` for accurate suggestion:
                    if let Ok(snippet) = fcx.tcx.sess.source_map().span_to_snippet(self.expr.span) {
                        if let Some(from_trait) = fcx.tcx.get_diagnostic_item(sym::from_trait) {
                            let ty = fcx.resolve_vars_if_possible(&self.cast_ty);
                            // Erase regions to avoid panic in `prove_value` when calling
                            // `type_implements_trait`.
                            let ty = fcx.tcx.erase_regions(&ty);
                            let expr_ty = fcx.resolve_vars_if_possible(&self.expr_ty);
                            let expr_ty = fcx.tcx.erase_regions(&expr_ty);
                            let ty_params = fcx.tcx.mk_substs_trait(expr_ty, &[]);
                            // Check for infer types because cases like `Option<{integer}>` would
                            // panic otherwise.
                            if !expr_ty.has_infer_types()
                                && fcx.tcx.type_implements_trait((
                                    from_trait,
                                    ty,
                                    ty_params,
                                    fcx.param_env,
                                ))
                            {
                                label = false;
                                err.span_suggestion(
                                    self.span,
                                    "consider using the `From` trait instead",
                                    format!("{}::from({})", self.cast_ty, snippet),
                                    Applicability::MaybeIncorrect,
                                );
                            }
                        }
                    }
                    let msg = "an `as` expression can only be used to convert between primitive \
                               types or to coerce to a specific trait object";
                    if label {
                        err.span_label(self.span, msg);
                    } else {
                        err.note(msg);
                    }
                } else {
                    err.span_label(self.span, "invalid cast");
                }
                err.emit();
            }
            CastError::SizedUnsizedCast => {
                use crate::structured_errors::{SizedUnsizedCastError, StructuredDiagnostic};
                SizedUnsizedCastError::new(
                    &fcx.tcx.sess,
                    self.span,
                    self.expr_ty,
                    fcx.ty_to_string(self.cast_ty),
                )
                .diagnostic()
                .emit();
            }
            CastError::UnknownCastPtrKind | CastError::UnknownExprPtrKind => {
                let unknown_cast_to = match e {
                    CastError::UnknownCastPtrKind => true,
                    CastError::UnknownExprPtrKind => false,
                    _ => bug!(),
                };
                let mut err = struct_span_err!(
                    fcx.tcx.sess,
                    if unknown_cast_to { self.cast_span } else { self.span },
                    E0641,
                    "cannot cast {} a pointer of an unknown kind",
                    if unknown_cast_to { "to" } else { "from" }
                );
                if unknown_cast_to {
                    err.span_label(self.cast_span, "needs more type information");
                    err.note(
                        "the type information given here is insufficient to check whether \
                        the pointer cast is valid",
                    );
                } else {
                    err.span_label(
                        self.span,
                        "the type information given here is insufficient to check whether \
                        the pointer cast is valid",
                    );
                }
                err.emit();
            }
        }
    }

    fn report_cast_to_unsized_type(&self, fcx: &FnCtxt<'a, 'tcx>) {
        if self.cast_ty.references_error() || self.expr_ty.references_error() {
            return;
        }

        let tstr = fcx.ty_to_string(self.cast_ty);
        let mut err = type_error_struct!(
            fcx.tcx.sess,
            self.span,
            self.expr_ty,
            E0620,
            "cast to unsized type: `{}` as `{}`",
            fcx.resolve_vars_if_possible(&self.expr_ty),
            tstr
        );
        match self.expr_ty.kind {
            ty::Ref(_, _, mt) => {
                let mtstr = mt.prefix_str();
                if self.cast_ty.is_trait() {
                    match fcx.tcx.sess.source_map().span_to_snippet(self.cast_span) {
                        Ok(s) => {
                            err.span_suggestion(
                                self.cast_span,
                                "try casting to a reference instead",
                                format!("&{}{}", mtstr, s),
                                Applicability::MachineApplicable,
                            );
                        }
                        Err(_) => {
                            let msg = &format!("did you mean `&{}{}`?", mtstr, tstr);
                            err.span_help(self.cast_span, msg);
                        }
                    }
                } else {
                    let msg = &format!(
                        "consider using an implicit coercion to `&{}{}` instead",
                        mtstr, tstr
                    );
                    err.span_help(self.span, msg);
                }
            }
            ty::Adt(def, ..) if def.is_box() => {
                match fcx.tcx.sess.source_map().span_to_snippet(self.cast_span) {
                    Ok(s) => {
                        err.span_suggestion(
                            self.cast_span,
                            "you can cast to a `Box` instead",
                            format!("Box<{}>", s),
                            Applicability::MachineApplicable,
                        );
                    }
                    Err(_) => {
                        err.span_help(
                            self.cast_span,
                            &format!("you might have meant `Box<{}>`", tstr),
                        );
                    }
                }
            }
            _ => {
                err.span_help(self.expr.span, "consider using a box or reference as appropriate");
            }
        }
        err.emit();
    }

    fn trivial_cast_lint(&self, fcx: &FnCtxt<'a, 'tcx>) {
        let t_cast = self.cast_ty;
        let t_expr = self.expr_ty;
        let type_asc_or =
            if fcx.tcx.features().type_ascription { "type ascription or " } else { "" };
        let (adjective, lint) = if t_cast.is_numeric() && t_expr.is_numeric() {
            ("numeric ", lint::builtin::TRIVIAL_NUMERIC_CASTS)
        } else {
            ("", lint::builtin::TRIVIAL_CASTS)
        };
        fcx.tcx.struct_span_lint_hir(lint, self.expr.hir_id, self.span, |err| {
            err.build(&format!(
                "trivial {}cast: `{}` as `{}`",
                adjective,
                fcx.ty_to_string(t_expr),
                fcx.ty_to_string(t_cast)
            ))
            .help(&format!(
                "cast can be replaced by coercion; this might \
                                   require {}a temporary variable",
                type_asc_or
            ))
            .emit();
        });
    }

    pub fn check(mut self, fcx: &FnCtxt<'a, 'tcx>) {
        self.expr_ty = fcx.structurally_resolved_type(self.span, self.expr_ty);
        self.cast_ty = fcx.structurally_resolved_type(self.span, self.cast_ty);

        debug!("check_cast({}, {:?} as {:?})", self.expr.hir_id, self.expr_ty, self.cast_ty);

        if !fcx.type_is_known_to_be_sized_modulo_regions(self.cast_ty, self.span) {
            self.report_cast_to_unsized_type(fcx);
        } else if self.expr_ty.references_error() || self.cast_ty.references_error() {
            // No sense in giving duplicate error messages
        } else {
            match self.try_coercion_cast(fcx) {
                Ok(()) => {
                    self.trivial_cast_lint(fcx);
                    debug!(" -> CoercionCast");
                    fcx.tables.borrow_mut().set_coercion_cast(self.expr.hir_id.local_id);
                }
                Err(ty::error::TypeError::ObjectUnsafeCoercion(did)) => {
                    self.report_object_unsafe_cast(&fcx, did);
                }
                Err(_) => {
                    match self.do_check(fcx) {
                        Ok(k) => {
                            debug!(" -> {:?}", k);
                        }
                        Err(e) => self.report_cast_error(fcx, e),
                    };
                }
            };
        }
    }

    fn report_object_unsafe_cast(&self, fcx: &FnCtxt<'a, 'tcx>, did: DefId) {
        let violations = fcx.tcx.object_safety_violations(did);
        let mut err = report_object_safety_error(fcx.tcx, self.cast_span, did, violations);
        err.note(&format!("required by cast to type '{}'", fcx.ty_to_string(self.cast_ty)));
        err.emit();
    }

    /// Checks a cast, and report an error if one exists. In some cases, this
    /// can return Ok and create type errors in the fcx rather than returning
    /// directly. coercion-cast is handled in check instead of here.
    fn do_check(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result<CastKind, CastError> {
        use rustc_middle::ty::cast::CastTy::*;
        use rustc_middle::ty::cast::IntTy::*;

        let (t_from, t_cast) = match (CastTy::from_ty(self.expr_ty), CastTy::from_ty(self.cast_ty))
        {
            (Some(t_from), Some(t_cast)) => (t_from, t_cast),
            // Function item types may need to be reified before casts.
            (None, Some(t_cast)) => {
                match self.expr_ty.kind {
                    ty::FnDef(..) => {
                        // Attempt a coercion to a fn pointer type.
                        let f = fcx.normalize_associated_types_in(
                            self.expr.span,
                            &self.expr_ty.fn_sig(fcx.tcx),
                        );
                        let res = fcx.try_coerce(
                            self.expr,
                            self.expr_ty,
                            fcx.tcx.mk_fn_ptr(f),
                            AllowTwoPhase::No,
                        );
                        if let Err(TypeError::IntrinsicCast) = res {
                            return Err(CastError::IllegalCast);
                        }
                        if res.is_err() {
                            return Err(CastError::NonScalar);
                        }
                        (FnPtr, t_cast)
                    }
                    // Special case some errors for references, and check for
                    // array-ptr-casts. `Ref` is not a CastTy because the cast
                    // is split into a coercion to a pointer type, followed by
                    // a cast.
                    ty::Ref(_, inner_ty, mutbl) => {
                        return match t_cast {
                            Int(_) | Float => match inner_ty.kind {
                                ty::Int(_)
                                | ty::Uint(_)
                                | ty::Float(_)
                                | ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(_)) => {
                                    Err(CastError::NeedDeref)
                                }
                                _ => Err(CastError::NeedViaPtr),
                            },
                            // array-ptr-cast
                            Ptr(mt) => {
                                self.check_ref_cast(fcx, TypeAndMut { mutbl, ty: inner_ty }, mt)
                            }
                            _ => Err(CastError::NonScalar),
                        };
                    }
                    _ => return Err(CastError::NonScalar),
                }
            }
            _ => return Err(CastError::NonScalar),
        };

        match (t_from, t_cast) {
            // These types have invariants! can't cast into them.
            (_, Int(CEnum) | FnPtr) => Err(CastError::NonScalar),

            // * -> Bool
            (_, Int(Bool)) => Err(CastError::CastToBool),

            // * -> Char
            (Int(U(ast::UintTy::U8)), Int(Char)) => Ok(CastKind::U8CharCast), // u8-char-cast
            (_, Int(Char)) => Err(CastError::CastToChar),

            // prim -> float,ptr
            (Int(Bool) | Int(CEnum) | Int(Char), Float) => Err(CastError::NeedViaInt),

            (Int(Bool) | Int(CEnum) | Int(Char) | Float, Ptr(_)) | (Ptr(_) | FnPtr, Float) => {
                Err(CastError::IllegalCast)
            }

            // ptr -> *
            (Ptr(m_e), Ptr(m_c)) => self.check_ptr_ptr_cast(fcx, m_e, m_c), // ptr-ptr-cast
            (Ptr(m_expr), Int(_)) => self.check_ptr_addr_cast(fcx, m_expr), // ptr-addr-cast
            (FnPtr, Int(_)) => Ok(CastKind::FnPtrAddrCast),

            // * -> ptr
            (Int(_), Ptr(mt)) => self.check_addr_ptr_cast(fcx, mt), // addr-ptr-cast
            (FnPtr, Ptr(mt)) => self.check_fptr_ptr_cast(fcx, mt),

            // prim -> prim
            (Int(CEnum), Int(_)) => {
                self.cenum_impl_drop_lint(fcx);
                Ok(CastKind::EnumCast)
            }
            (Int(Char) | Int(Bool), Int(_)) => Ok(CastKind::PrimIntCast),

            (Int(_) | Float, Int(_) | Float) => Ok(CastKind::NumericCast),
        }
    }

    fn check_ptr_ptr_cast(
        &self,
        fcx: &FnCtxt<'a, 'tcx>,
        m_expr: ty::TypeAndMut<'tcx>,
        m_cast: ty::TypeAndMut<'tcx>,
    ) -> Result<CastKind, CastError> {
        debug!("check_ptr_ptr_cast m_expr={:?} m_cast={:?}", m_expr, m_cast);
        // ptr-ptr cast. vtables must match.

        let expr_kind = fcx.pointer_kind(m_expr.ty, self.span)?;
        let cast_kind = fcx.pointer_kind(m_cast.ty, self.span)?;

        let cast_kind = match cast_kind {
            // We can't cast if target pointer kind is unknown
            None => return Err(CastError::UnknownCastPtrKind),
            Some(cast_kind) => cast_kind,
        };

        // Cast to thin pointer is OK
        if cast_kind == PointerKind::Thin {
            return Ok(CastKind::PtrPtrCast);
        }

        let expr_kind = match expr_kind {
            // We can't cast to fat pointer if source pointer kind is unknown
            None => return Err(CastError::UnknownExprPtrKind),
            Some(expr_kind) => expr_kind,
        };

        // thin -> fat? report invalid cast (don't complain about vtable kinds)
        if expr_kind == PointerKind::Thin {
            return Err(CastError::SizedUnsizedCast);
        }

        // vtable kinds must match
        if cast_kind == expr_kind {
            Ok(CastKind::PtrPtrCast)
        } else {
            Err(CastError::DifferingKinds)
        }
    }

    fn check_fptr_ptr_cast(
        &self,
        fcx: &FnCtxt<'a, 'tcx>,
        m_cast: ty::TypeAndMut<'tcx>,
    ) -> Result<CastKind, CastError> {
        // fptr-ptr cast. must be to thin ptr

        match fcx.pointer_kind(m_cast.ty, self.span)? {
            None => Err(CastError::UnknownCastPtrKind),
            Some(PointerKind::Thin) => Ok(CastKind::FnPtrPtrCast),
            _ => Err(CastError::IllegalCast),
        }
    }

    fn check_ptr_addr_cast(
        &self,
        fcx: &FnCtxt<'a, 'tcx>,
        m_expr: ty::TypeAndMut<'tcx>,
    ) -> Result<CastKind, CastError> {
        // ptr-addr cast. must be from thin ptr

        match fcx.pointer_kind(m_expr.ty, self.span)? {
            None => Err(CastError::UnknownExprPtrKind),
            Some(PointerKind::Thin) => Ok(CastKind::PtrAddrCast),
            _ => Err(CastError::NeedViaThinPtr),
        }
    }

    fn check_ref_cast(
        &self,
        fcx: &FnCtxt<'a, 'tcx>,
        m_expr: ty::TypeAndMut<'tcx>,
        m_cast: ty::TypeAndMut<'tcx>,
    ) -> Result<CastKind, CastError> {
        // array-ptr-cast.

        if m_expr.mutbl == hir::Mutability::Not && m_cast.mutbl == hir::Mutability::Not {
            if let ty::Array(ety, _) = m_expr.ty.kind {
                // Due to the limitations of LLVM global constants,
                // region pointers end up pointing at copies of
                // vector elements instead of the original values.
                // To allow raw pointers to work correctly, we
                // need to special-case obtaining a raw pointer
                // from a region pointer to a vector.

                // Coerce to a raw pointer so that we generate AddressOf in MIR.
                let array_ptr_type = fcx.tcx.mk_ptr(m_expr);
                fcx.try_coerce(self.expr, self.expr_ty, array_ptr_type, AllowTwoPhase::No)
                    .unwrap_or_else(|_| {
                        bug!(
                        "could not cast from reference to array to pointer to array ({:?} to {:?})",
                        self.expr_ty,
                        array_ptr_type,
                    )
                    });

                // this will report a type mismatch if needed
                fcx.demand_eqtype(self.span, ety, m_cast.ty);
                return Ok(CastKind::ArrayPtrCast);
            }
        }

        Err(CastError::IllegalCast)
    }

    fn check_addr_ptr_cast(
        &self,
        fcx: &FnCtxt<'a, 'tcx>,
        m_cast: TypeAndMut<'tcx>,
    ) -> Result<CastKind, CastError> {
        // ptr-addr cast. pointer must be thin.
        match fcx.pointer_kind(m_cast.ty, self.span)? {
            None => Err(CastError::UnknownCastPtrKind),
            Some(PointerKind::Thin) => Ok(CastKind::AddrPtrCast),
            _ => Err(CastError::IllegalCast),
        }
    }

    fn try_coercion_cast(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result<(), ty::error::TypeError<'_>> {
        match fcx.try_coerce(self.expr, self.expr_ty, self.cast_ty, AllowTwoPhase::No) {
            Ok(_) => Ok(()),
            Err(err) => Err(err),
        }
    }

    fn cenum_impl_drop_lint(&self, fcx: &FnCtxt<'a, 'tcx>) {
        if let ty::Adt(d, _) = self.expr_ty.kind {
            if d.has_dtor(fcx.tcx) {
                fcx.tcx.struct_span_lint_hir(
                    lint::builtin::CENUM_IMPL_DROP_CAST,
                    self.expr.hir_id,
                    self.span,
                    |err| {
                        err.build(&format!(
                            "cannot cast enum `{}` into integer `{}` because it implements `Drop`",
                            self.expr_ty, self.cast_ty
                        ))
                        .emit();
                    },
                );
            }
        }
    }
}

impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
    fn type_is_known_to_be_sized_modulo_regions(&self, ty: Ty<'tcx>, span: Span) -> bool {
        let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
        traits::type_known_to_meet_bound_modulo_regions(self, self.param_env, ty, lang_item, span)
    }
}
