// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! 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
//!    unsize_kind(`T`) = unsize_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 unsize_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 lint;
use hir::def_id::DefId;
use rustc::hir;
use rustc::traits;
use rustc::ty::{self, Ty, TypeFoldable};
use rustc::ty::cast::{CastKind, CastTy};
use syntax::ast;
use syntax_pos::Span;
use util::common::ErrorReported;

/// 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,
    expr_ty: Ty<'tcx>,
    cast_ty: Ty<'tcx>,
    cast_span: Span,
    span: Span,
}

/// The kind of the unsize info (length or vtable) - we only allow casts between
/// fat pointers if their unsize-infos have the same kind.
#[derive(Copy, Clone, PartialEq, Eq)]
enum UnsizeKind<'tcx> {
    Vtable(DefId),
    Length,
    /// The unsize info of this projection
    OfProjection(&'tcx ty::ProjectionTy<'tcx>),
    /// The unsize info of this parameter
    OfParam(&'tcx ty::ParamTy)
}

impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
    /// Returns the kind of unsize information of t, or None
    /// if t is sized or it is unknown.
    fn unsize_kind(&self, t: Ty<'tcx>) -> Option<UnsizeKind<'tcx>> {
        match t.sty {
            ty::TySlice(_) | ty::TyStr => Some(UnsizeKind::Length),
            ty::TyTrait(ref tty) => Some(UnsizeKind::Vtable(tty.principal_def_id())),
            ty::TyStruct(def, substs) => {
                // FIXME(arielb1): do some kind of normalization
                match def.struct_variant().fields.last() {
                    None => None,
                    Some(f) => self.unsize_kind(f.ty(self.tcx, substs))
                }
            }
            // We should really try to normalize here.
            ty::TyProjection(ref pi) => Some(UnsizeKind::OfProjection(pi)),
            ty::TyParam(ref p) => Some(UnsizeKind::OfParam(p)),
            _ => None
        }
    }
}

#[derive(Copy, Clone)]
enum CastError {
    CastToBool,
    CastToChar,
    DifferingKinds,
    /// Cast of thin to fat raw ptr (eg. `*const () as *const [u8]`)
    SizedUnsizedCast,
    IllegalCast,
    NeedViaPtr,
    NeedViaThinPtr,
    NeedViaInt,
    NeedViaUsize,
    NonScalar,
}

impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
    pub fn new(fcx: &FnCtxt<'a, 'gcx, 'tcx>,
               expr: &'tcx hir::Expr,
               expr_ty: Ty<'tcx>,
               cast_ty: Ty<'tcx>,
               cast_span: Span,
               span: Span)
               -> Result<CastCheck<'tcx>, ErrorReported> {
        let check = CastCheck {
            expr: expr,
            expr_ty: expr_ty,
            cast_ty: cast_ty,
            cast_span: cast_span,
            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.sty {
            ty::TyTrait(..) | ty::TySlice(..) => {
                check.report_cast_to_unsized_type(fcx);
                Err(ErrorReported)
            }
            _ => {
                Ok(check)
            }
        }
    }

    fn report_cast_error(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, e: CastError) {
        match e {
            CastError::NeedViaPtr |
            CastError::NeedViaThinPtr |
            CastError::NeedViaInt |
            CastError::NeedViaUsize => {
                fcx.type_error_struct(self.span, |actual| {
                    format!("casting `{}` as `{}` is invalid",
                            actual,
                            fcx.ty_to_string(self.cast_ty))
                }, self.expr_ty)
                    .help(&format!("cast through {} first", match e {
                            CastError::NeedViaPtr => "a raw pointer",
                            CastError::NeedViaThinPtr => "a thin pointer",
                            CastError::NeedViaInt => "an integer",
                            CastError::NeedViaUsize => "a usize",
                            _ => bug!()
                        }))
                    .emit();
            }
            CastError::CastToBool => {
                struct_span_err!(fcx.tcx.sess, self.span, E0054, "cannot cast as `bool`")
                    .help("compare with zero instead")
                    .emit();
            }
            CastError::CastToChar => {
                fcx.type_error_message(self.span, |actual| {
                    format!("only `u8` can be cast as `char`, not `{}`", actual)
                }, self.expr_ty);
            }
            CastError::NonScalar => {
                fcx.type_error_message(self.span, |actual| {
                    format!("non-scalar cast: `{}` as `{}`",
                            actual,
                            fcx.ty_to_string(self.cast_ty))
                }, self.expr_ty);
            }
            CastError::IllegalCast => {
                fcx.type_error_message(self.span, |actual| {
                    format!("casting `{}` as `{}` is invalid",
                            actual,
                            fcx.ty_to_string(self.cast_ty))
                }, self.expr_ty);
            }
            CastError::SizedUnsizedCast => {
                fcx.type_error_message(self.span, |actual| {
                    format!("cannot cast thin pointer `{}` to fat pointer `{}`",
                            actual,
                            fcx.ty_to_string(self.cast_ty))
                }, self.expr_ty)
            }
            CastError::DifferingKinds => {
                fcx.type_error_struct(self.span, |actual| {
                    format!("casting `{}` as `{}` is invalid",
                            actual,
                            fcx.ty_to_string(self.cast_ty))
                }, self.expr_ty)
                    .note("vtable kinds may not match")
                    .emit();
            }
        }
    }

    fn report_cast_to_unsized_type(&self, fcx: &FnCtxt<'a, 'gcx, '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 = fcx.type_error_struct(self.span, |actual| {
            format!("cast to unsized type: `{}` as `{}`", actual, tstr)
        }, self.expr_ty);
        match self.expr_ty.sty {
            ty::TyRef(_, ty::TypeAndMut { mutbl: mt, .. }) => {
                let mtstr = match mt {
                    hir::MutMutable => "mut ",
                    hir::MutImmutable => ""
                };
                if self.cast_ty.is_trait() {
                    match fcx.tcx.sess.codemap().span_to_snippet(self.cast_span) {
                        Ok(s) => {
                            err.span_suggestion(self.cast_span,
                                                "try casting to a reference instead:",
                                                format!("&{}{}", mtstr, s));
                        },
                        Err(_) =>
                            span_help!(err, self.cast_span,
                                       "did you mean `&{}{}`?", mtstr, tstr),
                    }
                } else {
                    span_help!(err, self.span,
                               "consider using an implicit coercion to `&{}{}` instead",
                               mtstr, tstr);
                }
            }
            ty::TyBox(..) => {
                match fcx.tcx.sess.codemap().span_to_snippet(self.cast_span) {
                    Ok(s) => {
                        err.span_suggestion(self.cast_span,
                                            "try casting to a `Box` instead:",
                                            format!("Box<{}>", s));
                    },
                    Err(_) =>
                        span_help!(err, self.cast_span, "did you mean `Box<{}>`?", tstr),
                }
            }
            _ => {
                span_help!(err, self.expr.span,
                           "consider using a box or reference as appropriate");
            }
        }
        err.emit();
    }

    fn trivial_cast_lint(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) {
        let t_cast = self.cast_ty;
        let t_expr = self.expr_ty;
        if t_cast.is_numeric() && t_expr.is_numeric() {
            fcx.tcx.sess.add_lint(lint::builtin::TRIVIAL_NUMERIC_CASTS,
                                  self.expr.id,
                                  self.span,
                                  format!("trivial numeric cast: `{}` as `{}`. Cast can be \
                                           replaced by coercion, this might require type \
                                           ascription or a temporary variable",
                                          fcx.ty_to_string(t_expr),
                                          fcx.ty_to_string(t_cast)));
        } else {
            fcx.tcx.sess.add_lint(lint::builtin::TRIVIAL_CASTS,
                                  self.expr.id,
                                  self.span,
                                  format!("trivial cast: `{}` as `{}`. Cast can be \
                                           replaced by coercion, this might require type \
                                           ascription or a temporary variable",
                                          fcx.ty_to_string(t_expr),
                                          fcx.ty_to_string(t_cast)));
        }

    }

    pub fn check(mut self, fcx: &FnCtxt<'a, 'gcx, '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.id, self.expr_ty,
               self.cast_ty);

        if !fcx.type_is_known_to_be_sized(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 if self.try_coercion_cast(fcx) {
            self.trivial_cast_lint(fcx);
            debug!(" -> CoercionCast");
            fcx.tcx.cast_kinds.borrow_mut().insert(self.expr.id,
                                                   CastKind::CoercionCast);
        } else { match self.do_check(fcx) {
            Ok(k) => {
                debug!(" -> {:?}", k);
                fcx.tcx.cast_kinds.borrow_mut().insert(self.expr.id, k);
            }
            Err(e) => self.report_cast_error(fcx, e)
        };}
    }

    /// Check 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, 'gcx, 'tcx>) -> Result<CastKind, CastError> {
        use rustc::ty::cast::IntTy::*;
        use rustc::ty::cast::CastTy::*;

        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)) => {
                if let ty::TyFnDef(_, _, f) = self.expr_ty.sty {
                    // Attempt a coercion to a fn pointer type.
                    let res = fcx.try_coerce(self.expr, fcx.tcx.mk_fn_ptr(f));
                    if !res.is_ok() {
                        return Err(CastError::NonScalar);
                    }
                    (FnPtr, t_cast)
                } else {
                    return Err(CastError::NonScalar);
                }
            }
            _ => {
                return Err(CastError::NonScalar)
            }
        };

        match (t_from, t_cast) {
            // These types have invariants! can't cast into them.
            (_, RPtr(_)) | (_, 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), Float) | (Int(CEnum), Float) | (Int(Char), Float)
                => Err(CastError::NeedViaInt),
            (Int(Bool), Ptr(_)) | (Int(CEnum), Ptr(_)) | (Int(Char), Ptr(_))
                => Err(CastError::NeedViaUsize),

            // 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
            (Ptr(_), Float) | (FnPtr, Float) => Err(CastError::NeedViaUsize),
            (FnPtr, Int(_)) => Ok(CastKind::FnPtrAddrCast),
            (RPtr(_), Int(_)) | (RPtr(_), Float) => Err(CastError::NeedViaPtr),
            // * -> ptr
            (Int(_), Ptr(mt)) => self.check_addr_ptr_cast(fcx, mt), // addr-ptr-cast
            (FnPtr, Ptr(mt)) => self.check_fptr_ptr_cast(fcx, mt),
            (Float, Ptr(_)) => Err(CastError::NeedViaUsize),
            (RPtr(rmt), Ptr(mt)) => self.check_ref_cast(fcx, rmt, mt), // array-ptr-cast

            // prim -> prim
            (Int(CEnum), Int(_)) => Ok(CastKind::EnumCast),
            (Int(Char), Int(_)) | (Int(Bool), Int(_)) => Ok(CastKind::PrimIntCast),

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

        }
    }

    fn check_ptr_ptr_cast(&self,
                          fcx: &FnCtxt<'a, 'gcx, 'tcx>,
                          m_expr: &'tcx ty::TypeAndMut<'tcx>,
                          m_cast: &'tcx 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.

        // Cast to sized is OK
        if fcx.type_is_known_to_be_sized(m_cast.ty, self.span) {
            return Ok(CastKind::PtrPtrCast);
        }

        // sized -> unsized? report invalid cast (don't complain about vtable kinds)
        if fcx.type_is_known_to_be_sized(m_expr.ty, self.span) {
            return Err(CastError::SizedUnsizedCast);
        }

        // vtable kinds must match
        match (fcx.unsize_kind(m_cast.ty), fcx.unsize_kind(m_expr.ty)) {
            (Some(a), Some(b)) if a == b => Ok(CastKind::PtrPtrCast),
            _ => Err(CastError::DifferingKinds)
        }
    }

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

        if fcx.type_is_known_to_be_sized(m_cast.ty, self.span) {
            Ok(CastKind::FnPtrPtrCast)
        } else {
            Err(CastError::IllegalCast)
        }
    }

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

        if fcx.type_is_known_to_be_sized(m_expr.ty, self.span) {
            Ok(CastKind::PtrAddrCast)
        } else {
            Err(CastError::NeedViaThinPtr)
        }
    }

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

        if m_expr.mutbl == hir::MutImmutable && m_cast.mutbl == hir::MutImmutable {
            if let ty::TyArray(ety, _) = m_expr.ty.sty {
                // 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.

                // 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, 'gcx, 'tcx>,
                           m_cast: &'tcx ty::TypeAndMut<'tcx>)
                           -> Result<CastKind, CastError>
    {
        // ptr-addr cast. pointer must be thin.
        if fcx.type_is_known_to_be_sized(m_cast.ty, self.span) {
           Ok(CastKind::AddrPtrCast)
        } else {
           Err(CastError::IllegalCast)
        }
    }

    fn try_coercion_cast(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> bool {
        fcx.try_coerce(self.expr, self.cast_ty).is_ok()
    }

}

impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
    fn type_is_known_to_be_sized(&self,
                                 ty: Ty<'tcx>,
                                 span: Span)
                                 -> bool
    {
        traits::type_known_to_meet_builtin_bound(self, ty, ty::BoundSized, span)
    }
}
