// Copyright 2014 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 related to processing overloaded binary and unary operators.

use super::{FnCtxt, Needs};
use super::method::MethodCallee;
use rustc::ty::{self, Ty, TypeFoldable};
use rustc::ty::TypeVariants::{TyRef, TyAdt, TyStr, TyUint, TyNever, TyTuple, TyChar, TyArray};
use rustc::ty::adjustment::{Adjustment, Adjust, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
use rustc::infer::type_variable::TypeVariableOrigin;
use errors;
use syntax_pos::Span;
use syntax::ast::Ident;
use rustc::hir;

impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
    /// Check a `a <op>= b`
    pub fn check_binop_assign(&self,
                              expr: &'gcx hir::Expr,
                              op: hir::BinOp,
                              lhs_expr: &'gcx hir::Expr,
                              rhs_expr: &'gcx hir::Expr) -> Ty<'tcx>
    {
        let (lhs_ty, rhs_ty, return_ty) =
            self.check_overloaded_binop(expr, lhs_expr, rhs_expr, op, IsAssign::Yes);

        let ty = if !lhs_ty.is_ty_var() && !rhs_ty.is_ty_var()
                    && is_builtin_binop(lhs_ty, rhs_ty, op) {
            self.enforce_builtin_binop_types(lhs_expr, lhs_ty, rhs_expr, rhs_ty, op);
            self.tcx.mk_nil()
        } else {
            return_ty
        };

        if !self.is_place_expr(lhs_expr) {
            struct_span_err!(
                self.tcx.sess, lhs_expr.span,
                E0067, "invalid left-hand side expression")
            .span_label(
                lhs_expr.span,
                "invalid expression for left-hand side")
            .emit();
        }
        ty
    }

    /// Check a potentially overloaded binary operator.
    pub fn check_binop(&self,
                       expr: &'gcx hir::Expr,
                       op: hir::BinOp,
                       lhs_expr: &'gcx hir::Expr,
                       rhs_expr: &'gcx hir::Expr) -> Ty<'tcx>
    {
        let tcx = self.tcx;

        debug!("check_binop(expr.id={}, expr={:?}, op={:?}, lhs_expr={:?}, rhs_expr={:?})",
               expr.id,
               expr,
               op,
               lhs_expr,
               rhs_expr);

        match BinOpCategory::from(op) {
            BinOpCategory::Shortcircuit => {
                // && and || are a simple case.
                self.check_expr_coercable_to_type(lhs_expr, tcx.types.bool);
                let lhs_diverges = self.diverges.get();
                self.check_expr_coercable_to_type(rhs_expr, tcx.types.bool);

                // Depending on the LHS' value, the RHS can never execute.
                self.diverges.set(lhs_diverges);

                tcx.types.bool
            }
            _ => {
                // Otherwise, we always treat operators as if they are
                // overloaded. This is the way to be most flexible w/r/t
                // types that get inferred.
                let (lhs_ty, rhs_ty, return_ty) =
                    self.check_overloaded_binop(expr, lhs_expr,
                                                rhs_expr, op, IsAssign::No);

                // Supply type inference hints if relevant. Probably these
                // hints should be enforced during select as part of the
                // `consider_unification_despite_ambiguity` routine, but this
                // more convenient for now.
                //
                // The basic idea is to help type inference by taking
                // advantage of things we know about how the impls for
                // scalar types are arranged. This is important in a
                // scenario like `1_u32 << 2`, because it lets us quickly
                // deduce that the result type should be `u32`, even
                // though we don't know yet what type 2 has and hence
                // can't pin this down to a specific impl.
                if
                    !lhs_ty.is_ty_var() && !rhs_ty.is_ty_var() &&
                    is_builtin_binop(lhs_ty, rhs_ty, op)
                {
                    let builtin_return_ty =
                        self.enforce_builtin_binop_types(lhs_expr, lhs_ty, rhs_expr, rhs_ty, op);
                    self.demand_suptype(expr.span, builtin_return_ty, return_ty);
                }

                return_ty
            }
        }
    }

    fn enforce_builtin_binop_types(&self,
                                   lhs_expr: &'gcx hir::Expr,
                                   lhs_ty: Ty<'tcx>,
                                   rhs_expr: &'gcx hir::Expr,
                                   rhs_ty: Ty<'tcx>,
                                   op: hir::BinOp)
                                   -> Ty<'tcx>
    {
        debug_assert!(is_builtin_binop(lhs_ty, rhs_ty, op));

        let tcx = self.tcx;
        match BinOpCategory::from(op) {
            BinOpCategory::Shortcircuit => {
                self.demand_suptype(lhs_expr.span, tcx.mk_bool(), lhs_ty);
                self.demand_suptype(rhs_expr.span, tcx.mk_bool(), rhs_ty);
                tcx.mk_bool()
            }

            BinOpCategory::Shift => {
                // result type is same as LHS always
                lhs_ty
            }

            BinOpCategory::Math |
            BinOpCategory::Bitwise => {
                // both LHS and RHS and result will have the same type
                self.demand_suptype(rhs_expr.span, lhs_ty, rhs_ty);
                lhs_ty
            }

            BinOpCategory::Comparison => {
                // both LHS and RHS and result will have the same type
                self.demand_suptype(rhs_expr.span, lhs_ty, rhs_ty);
                tcx.mk_bool()
            }
        }
    }

    fn check_overloaded_binop(&self,
                              expr: &'gcx hir::Expr,
                              lhs_expr: &'gcx hir::Expr,
                              rhs_expr: &'gcx hir::Expr,
                              op: hir::BinOp,
                              is_assign: IsAssign)
                              -> (Ty<'tcx>, Ty<'tcx>, Ty<'tcx>)
    {
        debug!("check_overloaded_binop(expr.id={}, op={:?}, is_assign={:?})",
               expr.id,
               op,
               is_assign);

        let lhs_ty = match is_assign {
            IsAssign::No => {
                // Find a suitable supertype of the LHS expression's type, by coercing to
                // a type variable, to pass as the `Self` to the trait, avoiding invariant
                // trait matching creating lifetime constraints that are too strict.
                // E.g. adding `&'a T` and `&'b T`, given `&'x T: Add<&'x T>`, will result
                // in `&'a T <: &'x T` and `&'b T <: &'x T`, instead of `'a = 'b = 'x`.
                let lhs_ty = self.check_expr_with_needs(lhs_expr, Needs::None);
                let fresh_var = self.next_ty_var(TypeVariableOrigin::MiscVariable(lhs_expr.span));
                self.demand_coerce(lhs_expr, lhs_ty, fresh_var,  AllowTwoPhase::No)
            }
            IsAssign::Yes => {
                // rust-lang/rust#52126: We have to use strict
                // equivalence on the LHS of an assign-op like `+=`;
                // overwritten or mutably-borrowed places cannot be
                // coerced to a supertype.
                self.check_expr_with_needs(lhs_expr, Needs::MutPlace)
            }
        };
        let lhs_ty = self.resolve_type_vars_with_obligations(lhs_ty);

        // NB: As we have not yet type-checked the RHS, we don't have the
        // type at hand. Make a variable to represent it. The whole reason
        // for this indirection is so that, below, we can check the expr
        // using this variable as the expected type, which sometimes lets
        // us do better coercions than we would be able to do otherwise,
        // particularly for things like `String + &String`.
        let rhs_ty_var = self.next_ty_var(TypeVariableOrigin::MiscVariable(rhs_expr.span));

        let result = self.lookup_op_method(lhs_ty, &[rhs_ty_var], Op::Binary(op, is_assign));

        // see `NB` above
        let rhs_ty = self.check_expr_coercable_to_type(rhs_expr, rhs_ty_var);
        let rhs_ty = self.resolve_type_vars_with_obligations(rhs_ty);

        let return_ty = match result {
            Ok(method) => {
                let by_ref_binop = !op.node.is_by_value();
                if is_assign == IsAssign::Yes || by_ref_binop {
                    if let ty::TyRef(region, _, mutbl) = method.sig.inputs()[0].sty {
                        let mutbl = match mutbl {
                            hir::MutImmutable => AutoBorrowMutability::Immutable,
                            hir::MutMutable => AutoBorrowMutability::Mutable {
                                // Allow two-phase borrows for binops in initial deployment
                                // since they desugar to methods
                                allow_two_phase_borrow: AllowTwoPhase::Yes,
                            }
                        };
                        let autoref = Adjustment {
                            kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
                            target: method.sig.inputs()[0]
                        };
                        self.apply_adjustments(lhs_expr, vec![autoref]);
                    }
                }
                if by_ref_binop {
                    if let ty::TyRef(region, _, mutbl) = method.sig.inputs()[1].sty {
                        let mutbl = match mutbl {
                            hir::MutImmutable => AutoBorrowMutability::Immutable,
                            hir::MutMutable => AutoBorrowMutability::Mutable {
                                // Allow two-phase borrows for binops in initial deployment
                                // since they desugar to methods
                                allow_two_phase_borrow: AllowTwoPhase::Yes,
                            }
                        };
                        let autoref = Adjustment {
                            kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
                            target: method.sig.inputs()[1]
                        };
                        // HACK(eddyb) Bypass checks due to reborrows being in
                        // some cases applied on the RHS, on top of which we need
                        // to autoref, which is not allowed by apply_adjustments.
                        // self.apply_adjustments(rhs_expr, vec![autoref]);
                        self.tables
                            .borrow_mut()
                            .adjustments_mut()
                            .entry(rhs_expr.hir_id)
                            .or_default()
                            .push(autoref);
                    }
                }
                self.write_method_call(expr.hir_id, method);

                method.sig.output()
            }
            Err(()) => {
                // error types are considered "builtin"
                if !lhs_ty.references_error() {
                    let source_map = self.tcx.sess.source_map();
                    match is_assign {
                        IsAssign::Yes => {
                            let mut err = struct_span_err!(self.tcx.sess, expr.span, E0368,
                                                "binary assignment operation `{}=` \
                                                cannot be applied to type `{}`",
                                                op.node.as_str(),
                                                lhs_ty);
                            err.span_label(lhs_expr.span,
                                    format!("cannot use `{}=` on type `{}`",
                                    op.node.as_str(), lhs_ty));
                            let mut suggested_deref = false;
                            if let TyRef(_, mut rty, _) = lhs_ty.sty {
                                if {
                                    !self.infcx.type_moves_by_default(self.param_env,
                                                                        rty,
                                                                        lhs_expr.span) &&
                                        self.lookup_op_method(rty,
                                                              &[rhs_ty],
                                                              Op::Binary(op, is_assign))
                                            .is_ok()
                                } {
                                    if let Ok(lstring) = source_map.span_to_snippet(lhs_expr.span) {
                                        while let TyRef(_, rty_inner, _) = rty.sty {
                                            rty = rty_inner;
                                        }
                                        let msg = &format!(
                                                "`{}=` can be used on '{}', you can \
                                                dereference `{2}`: `*{2}`",
                                                op.node.as_str(),
                                                rty,
                                                lstring
                                        );
                                        err.help(msg);
                                        suggested_deref = true;
                                    }
                                }
                            }
                            let missing_trait = match op.node {
                                hir::BinOpKind::Add    => Some("std::ops::AddAssign"),
                                hir::BinOpKind::Sub    => Some("std::ops::SubAssign"),
                                hir::BinOpKind::Mul    => Some("std::ops::MulAssign"),
                                hir::BinOpKind::Div    => Some("std::ops::DivAssign"),
                                hir::BinOpKind::Rem    => Some("std::ops::RemAssign"),
                                hir::BinOpKind::BitAnd => Some("std::ops::BitAndAssign"),
                                hir::BinOpKind::BitXor => Some("std::ops::BitXorAssign"),
                                hir::BinOpKind::BitOr  => Some("std::ops::BitOrAssign"),
                                hir::BinOpKind::Shl    => Some("std::ops::ShlAssign"),
                                hir::BinOpKind::Shr    => Some("std::ops::ShrAssign"),
                                _             => None
                            };
                            if let Some(missing_trait) = missing_trait {
                                if op.node == hir::BinOpKind::Add &&
                                    self.check_str_addition(expr, lhs_expr, rhs_expr, lhs_ty,
                                                            rhs_ty, &mut err, true) {
                                    // This has nothing here because it means we did string
                                    // concatenation (e.g. "Hello " += "World!"). This means
                                    // we don't want the note in the else clause to be emitted
                                } else if let ty::TyParam(_) = lhs_ty.sty {
                                    // FIXME: point to span of param
                                    err.note(&format!(
                                        "`{}` might need a bound for `{}`",
                                        lhs_ty, missing_trait
                                    ));
                                } else if !suggested_deref {
                                    err.note(&format!(
                                        "an implementation of `{}` might \
                                         be missing for `{}`",
                                        missing_trait, lhs_ty
                                    ));
                                }
                            }
                            err.emit();
                        }
                        IsAssign::No => {
                            let mut err = struct_span_err!(self.tcx.sess, expr.span, E0369,
                                            "binary operation `{}` cannot be applied to type `{}`",
                                            op.node.as_str(),
                                            lhs_ty);
                            let mut suggested_deref = false;
                            if let TyRef(_, mut rty, _) = lhs_ty.sty {
                                if {
                                    !self.infcx.type_moves_by_default(self.param_env,
                                                                        rty,
                                                                        lhs_expr.span) &&
                                        self.lookup_op_method(rty,
                                                              &[rhs_ty],
                                                              Op::Binary(op, is_assign))
                                            .is_ok()
                                } {
                                    if let Ok(lstring) = source_map.span_to_snippet(lhs_expr.span) {
                                        while let TyRef(_, rty_inner, _) = rty.sty {
                                            rty = rty_inner;
                                        }
                                        let msg = &format!(
                                                "`{}` can be used on '{}', you can \
                                                dereference `{2}`: `*{2}`",
                                                op.node.as_str(),
                                                rty,
                                                lstring
                                        );
                                        err.help(msg);
                                        suggested_deref = true;
                                    }
                                }
                            }
                            let missing_trait = match op.node {
                                hir::BinOpKind::Add    => Some("std::ops::Add"),
                                hir::BinOpKind::Sub    => Some("std::ops::Sub"),
                                hir::BinOpKind::Mul    => Some("std::ops::Mul"),
                                hir::BinOpKind::Div    => Some("std::ops::Div"),
                                hir::BinOpKind::Rem    => Some("std::ops::Rem"),
                                hir::BinOpKind::BitAnd => Some("std::ops::BitAnd"),
                                hir::BinOpKind::BitXor => Some("std::ops::BitXor"),
                                hir::BinOpKind::BitOr  => Some("std::ops::BitOr"),
                                hir::BinOpKind::Shl    => Some("std::ops::Shl"),
                                hir::BinOpKind::Shr    => Some("std::ops::Shr"),
                                hir::BinOpKind::Eq |
                                hir::BinOpKind::Ne => Some("std::cmp::PartialEq"),
                                hir::BinOpKind::Lt |
                                hir::BinOpKind::Le |
                                hir::BinOpKind::Gt |
                                hir::BinOpKind::Ge => Some("std::cmp::PartialOrd"),
                                _ => None
                            };
                            if let Some(missing_trait) = missing_trait {
                                if op.node == hir::BinOpKind::Add &&
                                    self.check_str_addition(expr, lhs_expr, rhs_expr, lhs_ty,
                                                            rhs_ty, &mut err, false) {
                                    // This has nothing here because it means we did string
                                    // concatenation (e.g. "Hello " + "World!"). This means
                                    // we don't want the note in the else clause to be emitted
                                } else if let ty::TyParam(_) = lhs_ty.sty {
                                    // FIXME: point to span of param
                                    err.note(&format!(
                                        "`{}` might need a bound for `{}`",
                                        lhs_ty, missing_trait
                                    ));
                                } else if !suggested_deref {
                                    err.note(&format!(
                                        "an implementation of `{}` might \
                                         be missing for `{}`",
                                        missing_trait, lhs_ty
                                    ));
                                }
                            }
                            err.emit();
                        }
                    }
                }
                self.tcx.types.err
            }
        };

        (lhs_ty, rhs_ty, return_ty)
    }

    fn check_str_addition(
        &self,
        expr: &'gcx hir::Expr,
        lhs_expr: &'gcx hir::Expr,
        rhs_expr: &'gcx hir::Expr,
        lhs_ty: Ty<'tcx>,
        rhs_ty: Ty<'tcx>,
        err: &mut errors::DiagnosticBuilder,
        is_assign: bool,
    ) -> bool {
        let source_map = self.tcx.sess.source_map();
        let msg = "`to_owned()` can be used to create an owned `String` \
                   from a string reference. String concatenation \
                   appends the string on the right to the string \
                   on the left and may require reallocation. This \
                   requires ownership of the string on the left";
        // If this function returns true it means a note was printed, so we don't need
        // to print the normal "implementation of `std::ops::Add` might be missing" note
        match (&lhs_ty.sty, &rhs_ty.sty) {
            (&TyRef(_, l_ty, _), &TyRef(_, r_ty, _))
            if l_ty.sty == TyStr && r_ty.sty == TyStr => {
                if !is_assign {
                    err.span_label(expr.span,
                                   "`+` can't be used to concatenate two `&str` strings");
                    match source_map.span_to_snippet(lhs_expr.span) {
                        Ok(lstring) => err.span_suggestion(lhs_expr.span,
                                                           msg,
                                                           format!("{}.to_owned()", lstring)),
                        _ => err.help(msg),
                    };
                }
                true
            }
            (&TyRef(_, l_ty, _), &TyAdt(..))
            if l_ty.sty == TyStr && &format!("{:?}", rhs_ty) == "std::string::String" => {
                err.span_label(expr.span,
                    "`+` can't be used to concatenate a `&str` with a `String`");
                match (
                    source_map.span_to_snippet(lhs_expr.span),
                    source_map.span_to_snippet(rhs_expr.span),
                    is_assign,
                ) {
                    (Ok(l), Ok(r), false) => {
                        err.multipart_suggestion(msg, vec![
                            (lhs_expr.span, format!("{}.to_owned()", l)),
                            (rhs_expr.span, format!("&{}", r)),
                        ]);
                    }
                    _ => {
                        err.help(msg);
                    }
                };
                true
            }
            _ => false,
        }
    }

    pub fn check_user_unop(&self,
                           ex: &'gcx hir::Expr,
                           operand_ty: Ty<'tcx>,
                           op: hir::UnOp)
                           -> Ty<'tcx>
    {
        assert!(op.is_by_value());
        match self.lookup_op_method(operand_ty, &[], Op::Unary(op, ex.span)) {
            Ok(method) => {
                self.write_method_call(ex.hir_id, method);
                method.sig.output()
            }
            Err(()) => {
                let actual = self.resolve_type_vars_if_possible(&operand_ty);
                if !actual.references_error() {
                    let mut err = struct_span_err!(self.tcx.sess, ex.span, E0600,
                                     "cannot apply unary operator `{}` to type `{}`",
                                     op.as_str(), actual);
                    err.span_label(ex.span, format!("cannot apply unary \
                                                    operator `{}`", op.as_str()));
                    match actual.sty {
                        TyUint(_) if op == hir::UnNeg => {
                            err.note("unsigned values cannot be negated");
                        },
                        TyStr | TyNever | TyChar | TyTuple(_) | TyArray(_,_) => {},
                        TyRef(_, ref lty, _) if lty.sty == TyStr => {},
                        _ => {
                            let missing_trait = match op {
                                hir::UnNeg => "std::ops::Neg",
                                hir::UnNot => "std::ops::Not",
                                hir::UnDeref => "std::ops::UnDerf"
                            };
                            err.note(&format!("an implementation of `{}` might \
                                                be missing for `{}`",
                                             missing_trait, operand_ty));
                        }
                    }
                    err.emit();
                }
                self.tcx.types.err
            }
        }
    }

    fn lookup_op_method(&self, lhs_ty: Ty<'tcx>, other_tys: &[Ty<'tcx>], op: Op)
                        -> Result<MethodCallee<'tcx>, ()>
    {
        let lang = self.tcx.lang_items();

        let span = match op {
            Op::Binary(op, _) => op.span,
            Op::Unary(_, span) => span
        };
        let (opname, trait_did) = if let Op::Binary(op, IsAssign::Yes) = op {
            match op.node {
                hir::BinOpKind::Add => ("add_assign", lang.add_assign_trait()),
                hir::BinOpKind::Sub => ("sub_assign", lang.sub_assign_trait()),
                hir::BinOpKind::Mul => ("mul_assign", lang.mul_assign_trait()),
                hir::BinOpKind::Div => ("div_assign", lang.div_assign_trait()),
                hir::BinOpKind::Rem => ("rem_assign", lang.rem_assign_trait()),
                hir::BinOpKind::BitXor => ("bitxor_assign", lang.bitxor_assign_trait()),
                hir::BinOpKind::BitAnd => ("bitand_assign", lang.bitand_assign_trait()),
                hir::BinOpKind::BitOr => ("bitor_assign", lang.bitor_assign_trait()),
                hir::BinOpKind::Shl => ("shl_assign", lang.shl_assign_trait()),
                hir::BinOpKind::Shr => ("shr_assign", lang.shr_assign_trait()),
                hir::BinOpKind::Lt | hir::BinOpKind::Le |
                hir::BinOpKind::Ge | hir::BinOpKind::Gt |
                hir::BinOpKind::Eq | hir::BinOpKind::Ne |
                hir::BinOpKind::And | hir::BinOpKind::Or => {
                    span_bug!(span,
                              "impossible assignment operation: {}=",
                              op.node.as_str())
                }
            }
        } else if let Op::Binary(op, IsAssign::No) = op {
            match op.node {
                hir::BinOpKind::Add => ("add", lang.add_trait()),
                hir::BinOpKind::Sub => ("sub", lang.sub_trait()),
                hir::BinOpKind::Mul => ("mul", lang.mul_trait()),
                hir::BinOpKind::Div => ("div", lang.div_trait()),
                hir::BinOpKind::Rem => ("rem", lang.rem_trait()),
                hir::BinOpKind::BitXor => ("bitxor", lang.bitxor_trait()),
                hir::BinOpKind::BitAnd => ("bitand", lang.bitand_trait()),
                hir::BinOpKind::BitOr => ("bitor", lang.bitor_trait()),
                hir::BinOpKind::Shl => ("shl", lang.shl_trait()),
                hir::BinOpKind::Shr => ("shr", lang.shr_trait()),
                hir::BinOpKind::Lt => ("lt", lang.partial_ord_trait()),
                hir::BinOpKind::Le => ("le", lang.partial_ord_trait()),
                hir::BinOpKind::Ge => ("ge", lang.partial_ord_trait()),
                hir::BinOpKind::Gt => ("gt", lang.partial_ord_trait()),
                hir::BinOpKind::Eq => ("eq", lang.eq_trait()),
                hir::BinOpKind::Ne => ("ne", lang.eq_trait()),
                hir::BinOpKind::And | hir::BinOpKind::Or => {
                    span_bug!(span, "&& and || are not overloadable")
                }
            }
        } else if let Op::Unary(hir::UnNot, _) = op {
            ("not", lang.not_trait())
        } else if let Op::Unary(hir::UnNeg, _) = op {
            ("neg", lang.neg_trait())
        } else {
            bug!("lookup_op_method: op not supported: {:?}", op)
        };

        debug!("lookup_op_method(lhs_ty={:?}, op={:?}, opname={:?}, trait_did={:?})",
               lhs_ty,
               op,
               opname,
               trait_did);

        let method = trait_did.and_then(|trait_did| {
            let opname = Ident::from_str(opname);
            self.lookup_method_in_trait(span, opname, trait_did, lhs_ty, Some(other_tys))
        });

        match method {
            Some(ok) => {
                let method = self.register_infer_ok_obligations(ok);
                self.select_obligations_where_possible(false);

                Ok(method)
            }
            None => {
                Err(())
            }
        }
    }
}

// Binary operator categories. These categories summarize the behavior
// with respect to the builtin operationrs supported.
enum BinOpCategory {
    /// &&, || -- cannot be overridden
    Shortcircuit,

    /// <<, >> -- when shifting a single integer, rhs can be any
    /// integer type. For simd, types must match.
    Shift,

    /// +, -, etc -- takes equal types, produces same type as input,
    /// applicable to ints/floats/simd
    Math,

    /// &, |, ^ -- takes equal types, produces same type as input,
    /// applicable to ints/floats/simd/bool
    Bitwise,

    /// ==, !=, etc -- takes equal types, produces bools, except for simd,
    /// which produce the input type
    Comparison,
}

impl BinOpCategory {
    fn from(op: hir::BinOp) -> BinOpCategory {
        match op.node {
            hir::BinOpKind::Shl | hir::BinOpKind::Shr =>
                BinOpCategory::Shift,

            hir::BinOpKind::Add |
            hir::BinOpKind::Sub |
            hir::BinOpKind::Mul |
            hir::BinOpKind::Div |
            hir::BinOpKind::Rem =>
                BinOpCategory::Math,

            hir::BinOpKind::BitXor |
            hir::BinOpKind::BitAnd |
            hir::BinOpKind::BitOr =>
                BinOpCategory::Bitwise,

            hir::BinOpKind::Eq |
            hir::BinOpKind::Ne |
            hir::BinOpKind::Lt |
            hir::BinOpKind::Le |
            hir::BinOpKind::Ge |
            hir::BinOpKind::Gt =>
                BinOpCategory::Comparison,

            hir::BinOpKind::And |
            hir::BinOpKind::Or =>
                BinOpCategory::Shortcircuit,
        }
    }
}

/// Whether the binary operation is an assignment (`a += b`), or not (`a + b`)
#[derive(Clone, Copy, Debug, PartialEq)]
enum IsAssign {
    No,
    Yes,
}

#[derive(Clone, Copy, Debug)]
enum Op {
    Binary(hir::BinOp, IsAssign),
    Unary(hir::UnOp, Span),
}

/// Returns true if this is a built-in arithmetic operation (e.g. u32
/// + u32, i16x4 == i16x4) and false if these types would have to be
/// overloaded to be legal. There are two reasons that we distinguish
/// builtin operations from overloaded ones (vs trying to drive
/// everything uniformly through the trait system and intrinsics or
/// something like that):
///
/// 1. Builtin operations can trivially be evaluated in constants.
/// 2. For comparison operators applied to SIMD types the result is
///    not of type `bool`. For example, `i16x4==i16x4` yields a
///    type like `i16x4`. This means that the overloaded trait
///    `PartialEq` is not applicable.
///
/// Reason #2 is the killer. I tried for a while to always use
/// overloaded logic and just check the types in constants/codegen after
/// the fact, and it worked fine, except for SIMD types. -nmatsakis
fn is_builtin_binop(lhs: Ty, rhs: Ty, op: hir::BinOp) -> bool {
    match BinOpCategory::from(op) {
        BinOpCategory::Shortcircuit => {
            true
        }

        BinOpCategory::Shift => {
            lhs.references_error() || rhs.references_error() ||
                lhs.is_integral() && rhs.is_integral()
        }

        BinOpCategory::Math => {
            lhs.references_error() || rhs.references_error() ||
                lhs.is_integral() && rhs.is_integral() ||
                lhs.is_floating_point() && rhs.is_floating_point()
        }

        BinOpCategory::Bitwise => {
            lhs.references_error() || rhs.references_error() ||
                lhs.is_integral() && rhs.is_integral() ||
                lhs.is_floating_point() && rhs.is_floating_point() ||
                lhs.is_bool() && rhs.is_bool()
        }

        BinOpCategory::Comparison => {
            lhs.references_error() || rhs.references_error() ||
                lhs.is_scalar() && rhs.is_scalar()
        }
    }
}
