#![allow(non_snake_case)]

use rustc::hir::{ExprKind, Node};
use crate::hir::def_id::DefId;
use rustc::hir::lowering::is_range_literal;
use rustc::ty::subst::SubstsRef;
use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
use rustc::ty::layout::{self, IntegerExt, LayoutOf, VariantIdx, SizeSkeleton};
use rustc::{lint, util};
use rustc_data_structures::indexed_vec::Idx;
use util::nodemap::FxHashSet;
use lint::{LateContext, LintContext, LintArray};
use lint::{LintPass, LateLintPass};

use std::cmp;
use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};

use syntax::{ast, attr, source_map};
use syntax::errors::Applicability;
use syntax::symbol::sym;
use rustc_target::spec::abi::Abi;
use syntax_pos::Span;

use rustc::hir;

use rustc::mir::interpret::{sign_extend, truncate};

use log::debug;

declare_lint! {
    UNUSED_COMPARISONS,
    Warn,
    "comparisons made useless by limits of the types involved"
}

declare_lint! {
    OVERFLOWING_LITERALS,
    Deny,
    "literal out of range for its type"
}

declare_lint! {
    VARIANT_SIZE_DIFFERENCES,
    Allow,
    "detects enums with widely varying variant sizes"
}

#[derive(Copy, Clone)]
pub struct TypeLimits {
    /// Id of the last visited negated expression
    negated_expr_id: hir::HirId,
}

impl_lint_pass!(TypeLimits => [UNUSED_COMPARISONS, OVERFLOWING_LITERALS]);

impl TypeLimits {
    pub fn new() -> TypeLimits {
        TypeLimits { negated_expr_id: hir::DUMMY_HIR_ID }
    }
}

/// Attempts to special-case the overflowing literal lint when it occurs as a range endpoint.
/// Returns `true` iff the lint was overridden.
fn lint_overflowing_range_endpoint<'a, 'tcx>(
    cx: &LateContext<'a, 'tcx>,
    lit: &hir::Lit,
    lit_val: u128,
    max: u128,
    expr: &'tcx hir::Expr,
    parent_expr: &'tcx hir::Expr,
    ty: impl std::fmt::Debug,
) -> bool {
    // We only want to handle exclusive (`..`) ranges,
    // which are represented as `ExprKind::Struct`.
    if let ExprKind::Struct(_, eps, _) = &parent_expr.node {
        if eps.len() != 2 {
            return false;
        }
        // We can suggest using an inclusive range
        // (`..=`) instead only if it is the `end` that is
        // overflowing and only by 1.
        if eps[1].expr.hir_id == expr.hir_id && lit_val - 1 == max {
            let mut err = cx.struct_span_lint(
                OVERFLOWING_LITERALS,
                parent_expr.span,
                &format!("range endpoint is out of range for `{:?}`", ty),
            );
            if let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) {
                use ast::{LitKind, LitIntType};
                // We need to preserve the literal's suffix,
                // as it may determine typing information.
                let suffix = match lit.node {
                    LitKind::Int(_, LitIntType::Signed(s)) => format!("{}", s),
                    LitKind::Int(_, LitIntType::Unsigned(s)) => format!("{}", s),
                    LitKind::Int(_, LitIntType::Unsuffixed) => "".to_owned(),
                    _ => bug!(),
                };
                let suggestion = format!("{}..={}{}", start, lit_val - 1, suffix);
                err.span_suggestion(
                    parent_expr.span,
                    &"use an inclusive range instead",
                    suggestion,
                    Applicability::MachineApplicable,
                );
                err.emit();
                return true;
            }
        }
    }

    false
}

// For `isize` & `usize`, be conservative with the warnings, so that the
// warnings are consistent between 32- and 64-bit platforms.
fn int_ty_range(int_ty: ast::IntTy) -> (i128, i128) {
    match int_ty {
        ast::IntTy::Isize => (i64::min_value() as i128, i64::max_value() as i128),
        ast::IntTy::I8 => (i8::min_value() as i64 as i128, i8::max_value() as i128),
        ast::IntTy::I16 => (i16::min_value() as i64 as i128, i16::max_value() as i128),
        ast::IntTy::I32 => (i32::min_value() as i64 as i128, i32::max_value() as i128),
        ast::IntTy::I64 => (i64::min_value() as i128, i64::max_value() as i128),
        ast::IntTy::I128 =>(i128::min_value() as i128, i128::max_value()),
    }
}

fn uint_ty_range(uint_ty: ast::UintTy) -> (u128, u128) {
    match uint_ty {
        ast::UintTy::Usize => (u64::min_value() as u128, u64::max_value() as u128),
        ast::UintTy::U8 => (u8::min_value() as u128, u8::max_value() as u128),
        ast::UintTy::U16 => (u16::min_value() as u128, u16::max_value() as u128),
        ast::UintTy::U32 => (u32::min_value() as u128, u32::max_value() as u128),
        ast::UintTy::U64 => (u64::min_value() as u128, u64::max_value() as u128),
        ast::UintTy::U128 => (u128::min_value(), u128::max_value()),
    }
}

fn get_bin_hex_repr(cx: &LateContext<'_, '_>, lit: &hir::Lit) -> Option<String> {
    let src = cx.sess().source_map().span_to_snippet(lit.span).ok()?;
    let firstch = src.chars().next()?;

    if firstch == '0' {
        match src.chars().nth(1) {
            Some('x') | Some('b') => return Some(src),
            _ => return None,
        }
    }

    None
}

fn report_bin_hex_error(
    cx: &LateContext<'_, '_>,
    expr: &hir::Expr,
    ty: attr::IntType,
    repr_str: String,
    val: u128,
    negative: bool,
) {
    let size = layout::Integer::from_attr(&cx.tcx, ty).size();
    let (t, actually) = match ty {
        attr::IntType::SignedInt(t) => {
            let actually = sign_extend(val, size) as i128;
            (format!("{:?}", t), actually.to_string())
        }
        attr::IntType::UnsignedInt(t) => {
            let actually = truncate(val, size);
            (format!("{:?}", t), actually.to_string())
        }
    };
    let mut err = cx.struct_span_lint(
        OVERFLOWING_LITERALS,
        expr.span,
        &format!("literal out of range for {}", t),
    );
    err.note(&format!(
        "the literal `{}` (decimal `{}`) does not fit into \
            an `{}` and will become `{}{}`",
        repr_str, val, t, actually, t
    ));
    if let Some(sugg_ty) =
        get_type_suggestion(&cx.tables.node_type(expr.hir_id), val, negative)
    {
        if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') {
            let (sans_suffix, _) = repr_str.split_at(pos);
            err.span_suggestion(
                expr.span,
                &format!("consider using `{}` instead", sugg_ty),
                format!("{}{}", sans_suffix, sugg_ty),
                Applicability::MachineApplicable
            );
        } else {
            err.help(&format!("consider using `{}` instead", sugg_ty));
        }
    }

    err.emit();
}

// This function finds the next fitting type and generates a suggestion string.
// It searches for fitting types in the following way (`X < Y`):
//  - `iX`: if literal fits in `uX` => `uX`, else => `iY`
//  - `-iX` => `iY`
//  - `uX` => `uY`
//
// No suggestion for: `isize`, `usize`.
fn get_type_suggestion(t: Ty<'_>, val: u128, negative: bool) -> Option<String> {
    use syntax::ast::IntTy::*;
    use syntax::ast::UintTy::*;
    macro_rules! find_fit {
        ($ty:expr, $val:expr, $negative:expr,
         $($type:ident => [$($utypes:expr),*] => [$($itypes:expr),*]),+) => {
            {
                let _neg = if negative { 1 } else { 0 };
                match $ty {
                    $($type => {
                        $(if !negative && val <= uint_ty_range($utypes).1 {
                            return Some(format!("{:?}", $utypes))
                        })*
                        $(if val <= int_ty_range($itypes).1 as u128 + _neg {
                            return Some(format!("{:?}", $itypes))
                        })*
                        None
                    },)+
                    _ => None
                }
            }
        }
    }
    match t.sty {
        ty::Int(i) => find_fit!(i, val, negative,
                      I8 => [U8] => [I16, I32, I64, I128],
                      I16 => [U16] => [I32, I64, I128],
                      I32 => [U32] => [I64, I128],
                      I64 => [U64] => [I128],
                      I128 => [U128] => []),
        ty::Uint(u) => find_fit!(u, val, negative,
                      U8 => [U8, U16, U32, U64, U128] => [],
                      U16 => [U16, U32, U64, U128] => [],
                      U32 => [U32, U64, U128] => [],
                      U64 => [U64, U128] => [],
                      U128 => [U128] => []),
        _ => None,
    }
}

fn lint_int_literal<'a, 'tcx>(
    cx: &LateContext<'a, 'tcx>,
    type_limits: &TypeLimits,
    e: &'tcx hir::Expr,
    lit: &hir::Lit,
    t: ast::IntTy,
    v: u128,
) {
    let int_type = if let ast::IntTy::Isize = t {
        cx.sess().target.isize_ty
    } else {
        t
    };

    let (_, max) = int_ty_range(int_type);
    let max = max as u128;
    let negative = type_limits.negated_expr_id == e.hir_id;

    // Detect literal value out of range [min, max] inclusive
    // avoiding use of -min to prevent overflow/panic
    if (negative && v > max + 1) || (!negative && v > max) {
        if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
            report_bin_hex_error(
                cx,
                e,
                attr::IntType::SignedInt(t),
                repr_str,
                v,
                negative,
            );
            return;
        }

        let par_id = cx.tcx.hir().get_parent_node(e.hir_id);
        if let Node::Expr(par_e) = cx.tcx.hir().get(par_id) {
            if let hir::ExprKind::Struct(..) = par_e.node {
                if is_range_literal(cx.sess(), par_e)
                    && lint_overflowing_range_endpoint(cx, lit, v, max, e, par_e, t)
                {
                    // The overflowing literal lint was overridden.
                    return;
                }
            }
        }

        cx.span_lint(
            OVERFLOWING_LITERALS,
            e.span,
            &format!("literal out of range for `{:?}`", t),
        );
    }
}

fn lint_uint_literal<'a, 'tcx>(
    cx: &LateContext<'a, 'tcx>,
    e: &'tcx hir::Expr,
    lit: &hir::Lit,
    t: ast::UintTy,
) {
    let uint_type = if let ast::UintTy::Usize = t {
        cx.sess().target.usize_ty
    } else {
        t
    };
    let (min, max) = uint_ty_range(uint_type);
    let lit_val: u128 = match lit.node {
        // _v is u8, within range by definition
        ast::LitKind::Byte(_v) => return,
        ast::LitKind::Int(v, _) => v,
        _ => bug!(),
    };
    if lit_val < min || lit_val > max {
        let parent_id = cx.tcx.hir().get_parent_node(e.hir_id);
        if let Node::Expr(par_e) = cx.tcx.hir().get(parent_id) {
            match par_e.node {
                hir::ExprKind::Cast(..) => {
                    if let ty::Char = cx.tables.expr_ty(par_e).sty {
                        let mut err = cx.struct_span_lint(
                            OVERFLOWING_LITERALS,
                            par_e.span,
                            "only `u8` can be cast into `char`",
                        );
                        err.span_suggestion(
                            par_e.span,
                            &"use a `char` literal instead",
                            format!("'\\u{{{:X}}}'", lit_val),
                            Applicability::MachineApplicable,
                        );
                        err.emit();
                        return;
                    }
                }
                hir::ExprKind::Struct(..)
                    if is_range_literal(cx.sess(), par_e) => {
                        if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, par_e, t) {
                            // The overflowing literal lint was overridden.
                            return;
                        }
                    }
                _ => {}
            }
        }
        if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
            report_bin_hex_error(cx, e, attr::IntType::UnsignedInt(t), repr_str, lit_val, false);
            return;
        }
        cx.span_lint(
            OVERFLOWING_LITERALS,
            e.span,
            &format!("literal out of range for `{:?}`", t),
        );
    }
}

fn lint_literal<'a, 'tcx>(
    cx: &LateContext<'a, 'tcx>,
    type_limits: &TypeLimits,
    e: &'tcx hir::Expr,
    lit: &hir::Lit,
) {
    match cx.tables.node_type(e.hir_id).sty {
        ty::Int(t) => {
            match lit.node {
                ast::LitKind::Int(v, ast::LitIntType::Signed(_)) |
                ast::LitKind::Int(v, ast::LitIntType::Unsuffixed) => {
                    lint_int_literal(cx, type_limits, e, lit, t, v)
                }
                _ => bug!(),
            };
        }
        ty::Uint(t) => {
            lint_uint_literal(cx, e, lit, t)
        }
        ty::Float(t) => {
            let is_infinite = match lit.node {
                ast::LitKind::Float(v, _) |
                ast::LitKind::FloatUnsuffixed(v) => {
                    match t {
                        ast::FloatTy::F32 => v.as_str().parse().map(f32::is_infinite),
                        ast::FloatTy::F64 => v.as_str().parse().map(f64::is_infinite),
                    }
                }
                _ => bug!(),
            };
            if is_infinite == Ok(true) {
                cx.span_lint(OVERFLOWING_LITERALS,
                             e.span,
                             &format!("literal out of range for `{:?}`", t));
            }
        }
        _ => {}
    }
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx hir::Expr) {
        match e.node {
            hir::ExprKind::Unary(hir::UnNeg, ref expr) => {
                // propagate negation, if the negation itself isn't negated
                if self.negated_expr_id != e.hir_id {
                    self.negated_expr_id = expr.hir_id;
                }
            }
            hir::ExprKind::Binary(binop, ref l, ref r) => {
                if is_comparison(binop) && !check_limits(cx, binop, &l, &r) {
                    cx.span_lint(UNUSED_COMPARISONS,
                                 e.span,
                                 "comparison is useless due to type limits");
                }
            }
            hir::ExprKind::Lit(ref lit) => lint_literal(cx, self, e, lit),
            _ => {}
        };

        fn is_valid<T: cmp::PartialOrd>(binop: hir::BinOp, v: T, min: T, max: T) -> bool {
            match binop.node {
                hir::BinOpKind::Lt => v > min && v <= max,
                hir::BinOpKind::Le => v >= min && v < max,
                hir::BinOpKind::Gt => v >= min && v < max,
                hir::BinOpKind::Ge => v > min && v <= max,
                hir::BinOpKind::Eq | hir::BinOpKind::Ne => v >= min && v <= max,
                _ => bug!(),
            }
        }

        fn rev_binop(binop: hir::BinOp) -> hir::BinOp {
            source_map::respan(binop.span,
                            match binop.node {
                                hir::BinOpKind::Lt => hir::BinOpKind::Gt,
                                hir::BinOpKind::Le => hir::BinOpKind::Ge,
                                hir::BinOpKind::Gt => hir::BinOpKind::Lt,
                                hir::BinOpKind::Ge => hir::BinOpKind::Le,
                                _ => return binop,
                            })
        }

        fn check_limits(cx: &LateContext<'_, '_>,
                        binop: hir::BinOp,
                        l: &hir::Expr,
                        r: &hir::Expr)
                        -> bool {
            let (lit, expr, swap) = match (&l.node, &r.node) {
                (&hir::ExprKind::Lit(_), _) => (l, r, true),
                (_, &hir::ExprKind::Lit(_)) => (r, l, false),
                _ => return true,
            };
            // Normalize the binop so that the literal is always on the RHS in
            // the comparison
            let norm_binop = if swap { rev_binop(binop) } else { binop };
            match cx.tables.node_type(expr.hir_id).sty {
                ty::Int(int_ty) => {
                    let (min, max) = int_ty_range(int_ty);
                    let lit_val: i128 = match lit.node {
                        hir::ExprKind::Lit(ref li) => {
                            match li.node {
                                ast::LitKind::Int(v, ast::LitIntType::Signed(_)) |
                                ast::LitKind::Int(v, ast::LitIntType::Unsuffixed) => v as i128,
                                _ => return true
                            }
                        },
                        _ => bug!()
                    };
                    is_valid(norm_binop, lit_val, min, max)
                }
                ty::Uint(uint_ty) => {
                    let (min, max) :(u128, u128) = uint_ty_range(uint_ty);
                    let lit_val: u128 = match lit.node {
                        hir::ExprKind::Lit(ref li) => {
                            match li.node {
                                ast::LitKind::Int(v, _) => v,
                                _ => return true
                            }
                        },
                        _ => bug!()
                    };
                    is_valid(norm_binop, lit_val, min, max)
                }
                _ => true,
            }
        }

        fn is_comparison(binop: hir::BinOp) -> bool {
            match binop.node {
                hir::BinOpKind::Eq |
                hir::BinOpKind::Lt |
                hir::BinOpKind::Le |
                hir::BinOpKind::Ne |
                hir::BinOpKind::Ge |
                hir::BinOpKind::Gt => true,
                _ => false,
            }
        }
    }
}

declare_lint! {
    IMPROPER_CTYPES,
    Warn,
    "proper use of libc types in foreign modules"
}

declare_lint_pass!(ImproperCTypes => [IMPROPER_CTYPES]);

struct ImproperCTypesVisitor<'a, 'tcx> {
    cx: &'a LateContext<'a, 'tcx>,
}

enum FfiResult<'tcx> {
    FfiSafe,
    FfiPhantom(Ty<'tcx>),
    FfiUnsafe {
        ty: Ty<'tcx>,
        reason: &'static str,
        help: Option<&'static str>,
    },
}

fn is_zst<'tcx>(tcx: TyCtxt<'tcx>, did: DefId, ty: Ty<'tcx>) -> bool {
    tcx.layout_of(tcx.param_env(did).and(ty)).map(|layout| layout.is_zst()).unwrap_or(false)
}

fn ty_is_known_nonnull<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
    match ty.sty {
        ty::FnPtr(_) => true,
        ty::Ref(..) => true,
        ty::Adt(field_def, substs) if field_def.repr.transparent() && !field_def.is_union() => {
            for field in field_def.all_fields() {
                let field_ty = tcx.normalize_erasing_regions(
                    ParamEnv::reveal_all(),
                    field.ty(tcx, substs),
                );
                if is_zst(tcx, field.did, field_ty) {
                    continue;
                }

                let attrs = tcx.get_attrs(field_def.did);
                if attrs.iter().any(|a| a.check_name(sym::rustc_nonnull_optimization_guaranteed)) ||
                    ty_is_known_nonnull(tcx, field_ty) {
                    return true;
                }
            }

            false
        }
        _ => false,
    }
}

/// Check if this enum can be safely exported based on the
/// "nullable pointer optimization". Currently restricted
/// to function pointers, references, core::num::NonZero*,
/// core::ptr::NonNull, and #[repr(transparent)] newtypes.
/// FIXME: This duplicates code in codegen.
fn is_repr_nullable_ptr<'tcx>(
    tcx: TyCtxt<'tcx>,
    ty: Ty<'tcx>,
    ty_def: &'tcx ty::AdtDef,
    substs: SubstsRef<'tcx>,
) -> bool {
    if ty_def.variants.len() != 2 {
        return false;
    }

    let get_variant_fields = |index| &ty_def.variants[VariantIdx::new(index)].fields;
    let variant_fields = [get_variant_fields(0), get_variant_fields(1)];
    let fields = if variant_fields[0].is_empty() {
        &variant_fields[1]
    } else if variant_fields[1].is_empty() {
        &variant_fields[0]
    } else {
        return false;
    };

    if fields.len() != 1 {
        return false;
    }

    let field_ty = fields[0].ty(tcx, substs);
    if !ty_is_known_nonnull(tcx, field_ty) {
        return false;
    }

    // At this point, the field's type is known to be nonnull and the parent enum is Option-like.
    // If the computed size for the field and the enum are different, the nonnull optimization isn't
    // being applied (and we've got a problem somewhere).
    let compute_size_skeleton = |t| SizeSkeleton::compute(t, tcx, ParamEnv::reveal_all()).unwrap();
    if !compute_size_skeleton(ty).same_size(compute_size_skeleton(field_ty)) {
        bug!("improper_ctypes: Option nonnull optimization not applied?");
    }

    true
}

impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
    /// Checks if the given type is "ffi-safe" (has a stable, well-defined
    /// representation which can be exported to C code).
    fn check_type_for_ffi(&self,
                          cache: &mut FxHashSet<Ty<'tcx>>,
                          ty: Ty<'tcx>) -> FfiResult<'tcx> {
        use FfiResult::*;

        let cx = self.cx.tcx;

        // Protect against infinite recursion, for example
        // `struct S(*mut S);`.
        // FIXME: A recursion limit is necessary as well, for irregular
        // recursive types.
        if !cache.insert(ty) {
            return FfiSafe;
        }

        match ty.sty {
            ty::Adt(def, substs) => {
                if def.is_phantom_data() {
                    return FfiPhantom(ty);
                }
                match def.adt_kind() {
                    AdtKind::Struct => {
                        if !def.repr.c() && !def.repr.transparent() {
                            return FfiUnsafe {
                                ty,
                                reason: "this struct has unspecified layout",
                                help: Some("consider adding a `#[repr(C)]` or \
                                            `#[repr(transparent)]` attribute to this struct"),
                            };
                        }

                        if def.non_enum_variant().fields.is_empty() {
                            return FfiUnsafe {
                                ty,
                                reason: "this struct has no fields",
                                help: Some("consider adding a member to this struct"),
                            };
                        }

                        // We can't completely trust repr(C) and repr(transparent) markings;
                        // make sure the fields are actually safe.
                        let mut all_phantom = true;
                        for field in &def.non_enum_variant().fields {
                            let field_ty = cx.normalize_erasing_regions(
                                ParamEnv::reveal_all(),
                                field.ty(cx, substs),
                            );
                            // repr(transparent) types are allowed to have arbitrary ZSTs, not just
                            // PhantomData -- skip checking all ZST fields
                            if def.repr.transparent() && is_zst(cx, field.did, field_ty) {
                                continue;
                            }
                            let r = self.check_type_for_ffi(cache, field_ty);
                            match r {
                                FfiSafe => {
                                    all_phantom = false;
                                }
                                FfiPhantom(..) => {}
                                FfiUnsafe { .. } => {
                                    return r;
                                }
                            }
                        }

                        if all_phantom { FfiPhantom(ty) } else { FfiSafe }
                    }
                    AdtKind::Union => {
                        if !def.repr.c() && !def.repr.transparent() {
                            return FfiUnsafe {
                                ty,
                                reason: "this union has unspecified layout",
                                help: Some("consider adding a `#[repr(C)]` or \
                                            `#[repr(transparent)]` attribute to this union"),
                            };
                        }

                        if def.non_enum_variant().fields.is_empty() {
                            return FfiUnsafe {
                                ty,
                                reason: "this union has no fields",
                                help: Some("consider adding a field to this union"),
                            };
                        }

                        let mut all_phantom = true;
                        for field in &def.non_enum_variant().fields {
                            let field_ty = cx.normalize_erasing_regions(
                                ParamEnv::reveal_all(),
                                field.ty(cx, substs),
                            );
                            // repr(transparent) types are allowed to have arbitrary ZSTs, not just
                            // PhantomData -- skip checking all ZST fields.
                            if def.repr.transparent() && is_zst(cx, field.did, field_ty) {
                                continue;
                            }
                            let r = self.check_type_for_ffi(cache, field_ty);
                            match r {
                                FfiSafe => {
                                    all_phantom = false;
                                }
                                FfiPhantom(..) => {}
                                FfiUnsafe { .. } => {
                                    return r;
                                }
                            }
                        }

                        if all_phantom { FfiPhantom(ty) } else { FfiSafe }
                    }
                    AdtKind::Enum => {
                        if def.variants.is_empty() {
                            // Empty enums are okay... although sort of useless.
                            return FfiSafe;
                        }

                        // Check for a repr() attribute to specify the size of the
                        // discriminant.
                        if !def.repr.c() && !def.repr.transparent() && def.repr.int.is_none() {
                            // Special-case types like `Option<extern fn()>`.
                            if !is_repr_nullable_ptr(cx, ty, def, substs) {
                                return FfiUnsafe {
                                    ty,
                                    reason: "enum has no representation hint",
                                    help: Some("consider adding a `#[repr(C)]`, \
                                                `#[repr(transparent)]`, or integer `#[repr(...)]` \
                                                attribute to this enum"),
                                };
                            }
                        }

                        // Check the contained variants.
                        for variant in &def.variants {
                            for field in &variant.fields {
                                let field_ty = cx.normalize_erasing_regions(
                                    ParamEnv::reveal_all(),
                                    field.ty(cx, substs),
                                );
                                // repr(transparent) types are allowed to have arbitrary ZSTs, not
                                // just PhantomData -- skip checking all ZST fields.
                                if def.repr.transparent() && is_zst(cx, field.did, field_ty) {
                                    continue;
                                }
                                let r = self.check_type_for_ffi(cache, field_ty);
                                match r {
                                    FfiSafe => {}
                                    FfiUnsafe { .. } => {
                                        return r;
                                    }
                                    FfiPhantom(..) => {
                                        return FfiUnsafe {
                                            ty,
                                            reason: "this enum contains a PhantomData field",
                                            help: None,
                                        };
                                    }
                                }
                            }
                        }
                        FfiSafe
                    }
                }
            }

            ty::Char => FfiUnsafe {
                ty,
                reason: "the `char` type has no C equivalent",
                help: Some("consider using `u32` or `libc::wchar_t` instead"),
            },

            ty::Int(ast::IntTy::I128) | ty::Uint(ast::UintTy::U128) => FfiUnsafe {
                ty,
                reason: "128-bit integers don't currently have a known stable ABI",
                help: None,
            },

            // Primitive types with a stable representation.
            ty::Bool | ty::Int(..) | ty::Uint(..) | ty::Float(..) | ty::Never => FfiSafe,

            ty::Slice(_) => FfiUnsafe {
                ty,
                reason: "slices have no C equivalent",
                help: Some("consider using a raw pointer instead"),
            },

            ty::Dynamic(..) => FfiUnsafe {
                ty,
                reason: "trait objects have no C equivalent",
                help: None,
            },

            ty::Str => FfiUnsafe {
                ty,
                reason: "string slices have no C equivalent",
                help: Some("consider using `*const u8` and a length instead"),
            },

            ty::Tuple(..) => FfiUnsafe {
                ty,
                reason: "tuples have unspecified layout",
                help: Some("consider using a struct instead"),
            },

            ty::RawPtr(ty::TypeAndMut { ty, .. }) |
            ty::Ref(_, ty, _) => self.check_type_for_ffi(cache, ty),

            ty::Array(ty, _) => self.check_type_for_ffi(cache, ty),

            ty::FnPtr(sig) => {
                match sig.abi() {
                    Abi::Rust | Abi::RustIntrinsic | Abi::PlatformIntrinsic | Abi::RustCall => {
                        return FfiUnsafe {
                            ty,
                            reason: "this function pointer has Rust-specific calling convention",
                            help: Some("consider using an `extern fn(...) -> ...` \
                                        function pointer instead"),
                        }
                    }
                    _ => {}
                }

                let sig = cx.erase_late_bound_regions(&sig);
                if !sig.output().is_unit() {
                    let r = self.check_type_for_ffi(cache, sig.output());
                    match r {
                        FfiSafe => {}
                        _ => {
                            return r;
                        }
                    }
                }
                for arg in sig.inputs() {
                    let r = self.check_type_for_ffi(cache, arg);
                    match r {
                        FfiSafe => {}
                        _ => {
                            return r;
                        }
                    }
                }
                FfiSafe
            }

            ty::Foreign(..) => FfiSafe,

            ty::Param(..) |
            ty::Infer(..) |
            ty::Bound(..) |
            ty::Error |
            ty::Closure(..) |
            ty::Generator(..) |
            ty::GeneratorWitness(..) |
            ty::Placeholder(..) |
            ty::UnnormalizedProjection(..) |
            ty::Projection(..) |
            ty::Opaque(..) |
            ty::FnDef(..) => bug!("unexpected type in foreign function: {:?}", ty),
        }
    }

    fn emit_ffi_unsafe_type_lint(
        &mut self,
        ty: Ty<'tcx>,
        sp: Span,
        note: &str,
        help: Option<&str>,
    ) {
        let mut diag = self.cx.struct_span_lint(
            IMPROPER_CTYPES,
            sp,
            &format!("`extern` block uses type `{}`, which is not FFI-safe", ty),
        );
        diag.span_label(sp, "not FFI-safe");
        if let Some(help) = help {
            diag.help(help);
        }
        diag.note(note);
        if let ty::Adt(def, _) = ty.sty {
            if let Some(sp) = self.cx.tcx.hir().span_if_local(def.did) {
                diag.span_note(sp, "type defined here");
            }
        }
        diag.emit();
    }

    fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool {
        use crate::rustc::ty::TypeFoldable;

        struct ProhibitOpaqueTypes<'tcx> {
            ty: Option<Ty<'tcx>>,
        };

        impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueTypes<'tcx> {
            fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
                if let ty::Opaque(..) = ty.sty {
                    self.ty = Some(ty);
                    true
                } else {
                    ty.super_visit_with(self)
                }
            }
        }

        let mut visitor = ProhibitOpaqueTypes { ty: None };
        ty.visit_with(&mut visitor);
        if let Some(ty) = visitor.ty {
            self.emit_ffi_unsafe_type_lint(
                ty,
                sp,
                "opaque types have no C equivalent",
                None,
            );
            true
        } else {
            false
        }
    }

    fn check_type_for_ffi_and_report_errors(&mut self, sp: Span, ty: Ty<'tcx>) {
        // We have to check for opaque types before `normalize_erasing_regions`,
        // which will replace opaque types with their underlying concrete type.
        if self.check_for_opaque_ty(sp, ty) {
            // We've already emitted an error due to an opaque type.
            return;
        }

        // it is only OK to use this function because extern fns cannot have
        // any generic types right now:
        let ty = self.cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);

        match self.check_type_for_ffi(&mut FxHashSet::default(), ty) {
            FfiResult::FfiSafe => {}
            FfiResult::FfiPhantom(ty) => {
                self.emit_ffi_unsafe_type_lint(ty, sp, "composed only of `PhantomData`", None);
            }
            FfiResult::FfiUnsafe { ty, reason, help } => {
                self.emit_ffi_unsafe_type_lint(ty, sp, reason, help);
            }
        }
    }

    fn check_foreign_fn(&mut self, id: hir::HirId, decl: &hir::FnDecl) {
        let def_id = self.cx.tcx.hir().local_def_id(id);
        let sig = self.cx.tcx.fn_sig(def_id);
        let sig = self.cx.tcx.erase_late_bound_regions(&sig);
        let inputs = if sig.c_variadic {
            // Don't include the spoofed `VaListImpl` in the functions list
            // of inputs.
            &sig.inputs()[..sig.inputs().len() - 1]
        } else {
            &sig.inputs()[..]
        };

        for (input_ty, input_hir) in inputs.iter().zip(&decl.inputs) {
            self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty);
        }

        if let hir::Return(ref ret_hir) = decl.output {
            let ret_ty = sig.output();
            if !ret_ty.is_unit() {
                self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty);
            }
        }
    }

    fn check_foreign_static(&mut self, id: hir::HirId, span: Span) {
        let def_id = self.cx.tcx.hir().local_def_id(id);
        let ty = self.cx.tcx.type_of(def_id);
        self.check_type_for_ffi_and_report_errors(span, ty);
    }
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
    fn check_foreign_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::ForeignItem) {
        let mut vis = ImproperCTypesVisitor { cx };
        let abi = cx.tcx.hir().get_foreign_abi(it.hir_id);
        if abi != Abi::RustIntrinsic && abi != Abi::PlatformIntrinsic {
            match it.node {
                hir::ForeignItemKind::Fn(ref decl, _, _) => {
                    vis.check_foreign_fn(it.hir_id, decl);
                }
                hir::ForeignItemKind::Static(ref ty, _) => {
                    vis.check_foreign_static(it.hir_id, ty.span);
                }
                hir::ForeignItemKind::Type => ()
            }
        }
    }
}

declare_lint_pass!(VariantSizeDifferences => [VARIANT_SIZE_DIFFERENCES]);

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences {
    fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
        if let hir::ItemKind::Enum(ref enum_definition, _) = it.node {
            let item_def_id = cx.tcx.hir().local_def_id(it.hir_id);
            let t = cx.tcx.type_of(item_def_id);
            let ty = cx.tcx.erase_regions(&t);
            let layout = match cx.layout_of(ty) {
                Ok(layout) => layout,
                Err(ty::layout::LayoutError::Unknown(_)) => return,
                Err(err @ ty::layout::LayoutError::SizeOverflow(_)) => {
                    bug!("failed to get layout for `{}`: {}", t, err);
                }
            };
            let (variants, tag) = match layout.variants {
                layout::Variants::Multiple {
                    discr_kind: layout::DiscriminantKind::Tag,
                    ref discr,
                    ref variants,
                    ..
                } => (variants, discr),
                _ => return,
            };

            let discr_size = tag.value.size(&cx.tcx).bytes();

            debug!("enum `{}` is {} bytes large with layout:\n{:#?}",
                   t, layout.size.bytes(), layout);

            let (largest, slargest, largest_index) = enum_definition.variants
                .iter()
                .zip(variants)
                .map(|(variant, variant_layout)| {
                    // Subtract the size of the enum discriminant.
                    let bytes = variant_layout.size.bytes().saturating_sub(discr_size);

                    debug!("- variant `{}` is {} bytes large",
                           variant.ident,
                           bytes);
                    bytes
                })
                .enumerate()
                .fold((0, 0, 0), |(l, s, li), (idx, size)| if size > l {
                    (size, l, idx)
                } else if size > s {
                    (l, size, li)
                } else {
                    (l, s, li)
                });

            // We only warn if the largest variant is at least thrice as large as
            // the second-largest.
            if largest > slargest * 3 && slargest > 0 {
                cx.span_lint(VARIANT_SIZE_DIFFERENCES,
                                enum_definition.variants[largest_index].span,
                                &format!("enum variant is more than three times \
                                          larger ({} bytes) than the next largest",
                                         largest));
            }
        }
    }
}
