// Copyright 2018 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.

use rustc::hir;
use rustc::hir::Node;
use rustc::mir::{self, BindingForm, Constant, ClearCrossCrate, Local, Location, Mir};
use rustc::mir::{Mutability, Operand, Place, Projection, ProjectionElem, Static, Terminator};
use rustc::mir::TerminatorKind;
use rustc::ty::{self, Const, DefIdTree, TyS, TyKind, TyCtxt};
use rustc_data_structures::indexed_vec::Idx;
use syntax_pos::Span;
use syntax_pos::symbol::keywords;

use dataflow::move_paths::InitLocation;
use borrow_check::MirBorrowckCtxt;
use util::borrowck_errors::{BorrowckErrors, Origin};
use util::collect_writes::FindAssignments;
use util::suggest_ref_mut;
use rustc_errors::Applicability;

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub(super) enum AccessKind {
    MutableBorrow,
    Mutate,
    Move,
}

impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
    pub(super) fn report_mutability_error(
        &mut self,
        access_place: &Place<'tcx>,
        span: Span,
        the_place_err: &Place<'tcx>,
        error_access: AccessKind,
        location: Location,
    ) {
        debug!(
            "report_mutability_error(\
                access_place={:?}, span={:?}, the_place_err={:?}, error_access={:?}, location={:?},\
            )",
            access_place, span, the_place_err, error_access, location,
        );

        let mut err;
        let item_msg;
        let reason;
        let access_place_desc = self.describe_place(access_place);
        debug!("report_mutability_error: access_place_desc={:?}", access_place_desc);

        match the_place_err {
            Place::Local(local) => {
                item_msg = format!("`{}`", access_place_desc.unwrap());
                if let Place::Local(_) = access_place {
                    reason = ", as it is not declared as mutable".to_string();
                } else {
                    let name = self.mir.local_decls[*local]
                        .name
                        .expect("immutable unnamed local");
                    reason = format!(", as `{}` is not declared as mutable", name);
                }
            }

            Place::Projection(box Projection {
                base,
                elem: ProjectionElem::Field(upvar_index, _),
            }) => {
                debug_assert!(is_closure_or_generator(
                    base.ty(self.mir, self.infcx.tcx).to_ty(self.infcx.tcx)
                ));

                item_msg = format!("`{}`", access_place_desc.unwrap());
                if access_place.is_upvar_field_projection(self.mir, &self.infcx.tcx).is_some() {
                    reason = ", as it is not declared as mutable".to_string();
                } else {
                    let name = self.mir.upvar_decls[upvar_index.index()].debug_name;
                    reason = format!(", as `{}` is not declared as mutable", name);
                }
            }

            Place::Projection(box Projection {
                base,
                elem: ProjectionElem::Deref,
            }) => {
                if *base == Place::Local(Local::new(1)) && !self.mir.upvar_decls.is_empty() {
                    item_msg = format!("`{}`", access_place_desc.unwrap());
                    debug_assert!(self.mir.local_decls[Local::new(1)].ty.is_region_ptr());
                    debug_assert!(is_closure_or_generator(
                        the_place_err.ty(self.mir, self.infcx.tcx).to_ty(self.infcx.tcx)
                    ));

                    reason = if access_place.is_upvar_field_projection(self.mir,
                                                                       &self.infcx.tcx).is_some() {
                        ", as it is a captured variable in a `Fn` closure".to_string()
                    } else {
                        ", as `Fn` closures cannot mutate their captured variables".to_string()
                    }
                } else if {
                    if let Place::Local(local) = *base {
                        if let Some(ClearCrossCrate::Set(BindingForm::RefForGuard))
                            = self.mir.local_decls[local].is_user_variable {
                                true
                        } else {
                            false
                        }
                    } else {
                        false
                    }
                } {
                    item_msg = format!("`{}`", access_place_desc.unwrap());
                    reason = ", as it is immutable for the pattern guard".to_string();
                } else {
                    let pointer_type =
                        if base.ty(self.mir, self.infcx.tcx).to_ty(self.infcx.tcx).is_region_ptr() {
                            "`&` reference"
                        } else {
                            "`*const` pointer"
                        };
                    if let Some(desc) = access_place_desc {
                        item_msg = format!("`{}`", desc);
                        reason = match error_access {
                            AccessKind::Move |
                            AccessKind::Mutate => format!(" which is behind a {}", pointer_type),
                            AccessKind::MutableBorrow => {
                                format!(", as it is behind a {}", pointer_type)
                            }
                        }
                    } else {
                        item_msg = format!("data in a {}", pointer_type);
                        reason = String::new();
                    }
                }
            }

            Place::Promoted(_) => unreachable!(),

            Place::Static(box Static { def_id, ty: _ }) => {
                if let Place::Static(_) = access_place {
                    item_msg = format!("immutable static item `{}`", access_place_desc.unwrap());
                    reason = String::new();
                } else {
                    item_msg = format!("`{}`", access_place_desc.unwrap());
                    let static_name = &self.infcx.tcx.item_name(*def_id);
                    reason = format!(", as `{}` is an immutable static item", static_name);
                }
            }

            Place::Projection(box Projection {
                base: _,
                elem: ProjectionElem::Index(_),
            })
            | Place::Projection(box Projection {
                base: _,
                elem: ProjectionElem::ConstantIndex { .. },
            })
            | Place::Projection(box Projection {
                base: _,
                elem: ProjectionElem::Subslice { .. },
            })
            | Place::Projection(box Projection {
                base: _,
                elem: ProjectionElem::Downcast(..),
            }) => bug!("Unexpected immutable place."),
        }

        debug!("report_mutability_error: item_msg={:?}, reason={:?}", item_msg, reason);

        // `act` and `acted_on` are strings that let us abstract over
        // the verbs used in some diagnostic messages.
        let act;
        let acted_on;

        let span = match error_access {
            AccessKind::Move => {
                err = self.infcx.tcx
                    .cannot_move_out_of(span, &(item_msg + &reason), Origin::Mir);
                err.span_label(span, "cannot move");
                err.buffer(&mut self.errors_buffer);
                return;
            }
            AccessKind::Mutate => {
                err = self.infcx.tcx
                    .cannot_assign(span, &(item_msg + &reason), Origin::Mir);
                act = "assign";
                acted_on = "written";
                span
            }
            AccessKind::MutableBorrow => {
                act = "borrow as mutable";
                acted_on = "borrowed as mutable";

                let borrow_spans = self.borrow_spans(span, location);
                let borrow_span = borrow_spans.args_or_use();
                err = self.infcx.tcx.cannot_borrow_path_as_mutable_because(
                    borrow_span,
                    &item_msg,
                    &reason,
                    Origin::Mir,
                );
                borrow_spans.var_span_label(
                    &mut err,
                    format!(
                        "mutable borrow occurs due to use of `{}` in closure",
                        // always Some() if the message is printed.
                        self.describe_place(access_place).unwrap_or_default(),
                    )
                );
                borrow_span
            }
        };

        debug!("report_mutability_error: act={:?}, acted_on={:?}", act, acted_on);

        match the_place_err {
            // Suggest making an existing shared borrow in a struct definition a mutable borrow.
            //
            // This is applicable when we have a deref of a field access to a deref of a local -
            // something like `*((*_1).0`. The local that we get will be a reference to the
            // struct we've got a field access of (it must be a reference since there's a deref
            // after the field access).
            Place::Projection(box Projection {
                base: Place::Projection(box Projection {
                    base: Place::Projection(box Projection {
                        base,
                        elem: ProjectionElem::Deref,
                    }),
                    elem: ProjectionElem::Field(field, _),
                }),
                elem: ProjectionElem::Deref,
            }) => {
                err.span_label(span, format!("cannot {ACT}", ACT = act));

                if let Some((span, message)) = annotate_struct_field(
                    self.infcx.tcx,
                    base.ty(self.mir, self.infcx.tcx).to_ty(self.infcx.tcx),
                    field,
                ) {
                    err.span_suggestion_with_applicability(
                        span,
                        "consider changing this to be mutable",
                        message,
                        Applicability::MaybeIncorrect,
                    );
                }
            },

            // Suggest removing a `&mut` from the use of a mutable reference.
            Place::Local(local)
                if {
                    self.mir.local_decls.get(*local).map(|local_decl| {
                        if let ClearCrossCrate::Set(
                            mir::BindingForm::ImplicitSelf(kind)
                        ) = local_decl.is_user_variable.as_ref().unwrap() {
                            // Check if the user variable is a `&mut self` and we can therefore
                            // suggest removing the `&mut`.
                            //
                            // Deliberately fall into this case for all implicit self types,
                            // so that we don't fall in to the next case with them.
                            *kind == mir::ImplicitSelfKind::MutRef
                        } else if Some(keywords::SelfValue.name()) == local_decl.name {
                            // Otherwise, check if the name is the self kewyord - in which case
                            // we have an explicit self. Do the same thing in this case and check
                            // for a `self: &mut Self` to suggest removing the `&mut`.
                            if let ty::TyKind::Ref(
                                _, _, hir::Mutability::MutMutable
                            ) = local_decl.ty.sty {
                                true
                            } else {
                                false
                            }
                        } else {
                            false
                        }
                    }).unwrap_or(false)
                } =>
            {
                err.span_label(span, format!("cannot {ACT}", ACT = act));
                err.span_label(span, "try removing `&mut` here");
            },

            // We want to suggest users use `let mut` for local (user
            // variable) mutations...
            Place::Local(local) if self.mir.local_decls[*local].can_be_made_mutable() => {
                // ... but it doesn't make sense to suggest it on
                // variables that are `ref x`, `ref mut x`, `&self`,
                // or `&mut self` (such variables are simply not
                // mutable).
                let local_decl = &self.mir.local_decls[*local];
                assert_eq!(local_decl.mutability, Mutability::Not);

                err.span_label(span, format!("cannot {ACT}", ACT = act));
                err.span_suggestion_with_applicability(
                    local_decl.source_info.span,
                    "consider changing this to be mutable",
                    format!("mut {}", local_decl.name.unwrap()),
                    Applicability::MachineApplicable,
                );
            }

            // Also suggest adding mut for upvars
            Place::Projection(box Projection {
                base,
                elem: ProjectionElem::Field(upvar_index, _),
            }) => {
                debug_assert!(is_closure_or_generator(
                    base.ty(self.mir, self.infcx.tcx).to_ty(self.infcx.tcx)
                ));

                err.span_label(span, format!("cannot {ACT}", ACT = act));

                let upvar_hir_id = self.mir.upvar_decls[upvar_index.index()]
                    .var_hir_id
                    .assert_crate_local();
                let upvar_node_id = self.infcx.tcx.hir.hir_to_node_id(upvar_hir_id);
                if let Some(Node::Binding(pat)) = self.infcx.tcx.hir.find(upvar_node_id) {
                    if let hir::PatKind::Binding(
                        hir::BindingAnnotation::Unannotated,
                        _,
                        upvar_ident,
                        _,
                    ) = pat.node
                    {
                        err.span_suggestion_with_applicability(
                            upvar_ident.span,
                            "consider changing this to be mutable",
                            format!("mut {}", upvar_ident.name),
                            Applicability::MachineApplicable,
                        );
                    }
                }
            }

            // complete hack to approximate old AST-borrowck
            // diagnostic: if the span starts with a mutable borrow of
            // a local variable, then just suggest the user remove it.
            Place::Local(_)
                if {
                    if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) {
                        snippet.starts_with("&mut ")
                    } else {
                        false
                    }
                } =>
            {
                err.span_label(span, format!("cannot {ACT}", ACT = act));
                err.span_label(span, "try removing `&mut` here");
            }

            Place::Projection(box Projection {
                base: Place::Local(local),
                elem: ProjectionElem::Deref,
            }) if {
                if let Some(ClearCrossCrate::Set(BindingForm::RefForGuard)) =
                    self.mir.local_decls[*local].is_user_variable
                {
                    true
                } else {
                    false
                }
            } =>
            {
                err.span_label(span, format!("cannot {ACT}", ACT = act));
                err.note(
                    "variables bound in patterns are immutable until the end of the pattern guard",
                );
            }

            // We want to point out when a `&` can be readily replaced
            // with an `&mut`.
            //
            // FIXME: can this case be generalized to work for an
            // arbitrary base for the projection?
            Place::Projection(box Projection {
                base: Place::Local(local),
                elem: ProjectionElem::Deref,
            }) if self.mir.local_decls[*local].is_user_variable.is_some() =>
            {
                let local_decl = &self.mir.local_decls[*local];
                let suggestion = match local_decl.is_user_variable.as_ref().unwrap() {
                    ClearCrossCrate::Set(mir::BindingForm::ImplicitSelf(_)) => {
                        Some(suggest_ampmut_self(self.infcx.tcx, local_decl))
                    }

                    ClearCrossCrate::Set(mir::BindingForm::Var(mir::VarBindingForm {
                        binding_mode: ty::BindingMode::BindByValue(_),
                        opt_ty_info,
                        ..
                    })) => Some(suggest_ampmut(
                        self.infcx.tcx,
                        self.mir,
                        *local,
                        local_decl,
                        *opt_ty_info,
                    )),

                    ClearCrossCrate::Set(mir::BindingForm::Var(mir::VarBindingForm {
                        binding_mode: ty::BindingMode::BindByReference(_),
                        ..
                    })) => {
                        let pattern_span = local_decl.source_info.span;
                        suggest_ref_mut(self.infcx.tcx, pattern_span)
                            .map(|replacement| (pattern_span, replacement))
                    }

                    ClearCrossCrate::Set(mir::BindingForm::RefForGuard) => unreachable!(),

                    ClearCrossCrate::Clear => bug!("saw cleared local state"),
                };

                let (pointer_sigil, pointer_desc) = if local_decl.ty.is_region_ptr() {
                    ("&", "reference")
                } else {
                    ("*const", "pointer")
                };

                if let Some((err_help_span, suggested_code)) = suggestion {
                    err.span_suggestion_with_applicability(
                        err_help_span,
                        &format!("consider changing this to be a mutable {}", pointer_desc),
                        suggested_code,
                        Applicability::MachineApplicable,
                    );
                }

                if let Some(name) = local_decl.name {
                    err.span_label(
                        span,
                        format!(
                            "`{NAME}` is a `{SIGIL}` {DESC}, \
                             so the data it refers to cannot be {ACTED_ON}",
                            NAME = name,
                            SIGIL = pointer_sigil,
                            DESC = pointer_desc,
                            ACTED_ON = acted_on
                        ),
                    );
                } else {
                    err.span_label(
                        span,
                        format!(
                            "cannot {ACT} through `{SIGIL}` {DESC}",
                            ACT = act,
                            SIGIL = pointer_sigil,
                            DESC = pointer_desc
                        ),
                    );
                }
            }

            Place::Projection(box Projection {
                base,
                elem: ProjectionElem::Deref,
            }) if *base == Place::Local(Local::new(1)) && !self.mir.upvar_decls.is_empty() =>
            {
                err.span_label(span, format!("cannot {ACT}", ACT = act));
                err.span_help(
                    self.mir.span,
                    "consider changing this to accept closures that implement `FnMut`"
                );
            }

            Place::Projection(box Projection {
                base: Place::Local(local),
                elem: ProjectionElem::Deref,
            })  if error_access == AccessKind::MutableBorrow => {
                err.span_label(span, format!("cannot {ACT}", ACT = act));

                let mpi = self.move_data.rev_lookup.find_local(*local);
                for i in self.move_data.init_path_map[mpi].iter() {
                    if let InitLocation::Statement(location) = self.move_data.inits[*i].location {
                        if let Some(
                            Terminator {
                                kind: TerminatorKind::Call {
                                    func: Operand::Constant(box Constant {
                                        literal: Const {
                                            ty: &TyS {
                                                sty: TyKind::FnDef(id, substs),
                                                ..
                                            },
                                            ..
                                        },
                                        ..
                                    }),
                                    ..
                                },
                                ..
                            }
                        ) = &self.mir.basic_blocks()[location.block].terminator {
                            let index_trait = self.infcx.tcx.lang_items().index_trait();
                            if self.infcx.tcx.parent(id) == index_trait {
                                let mut found = false;
                                self.infcx.tcx.for_each_relevant_impl(
                                    self.infcx.tcx.lang_items().index_mut_trait().unwrap(),
                                    substs.type_at(0),
                                    |_relevant_impl| {
                                        found = true;
                                    }
                                );

                                let extra = if found {
                                    String::new()
                                } else {
                                    format!(", but it is not implemented for `{}`",
                                            substs.type_at(0))
                                };

                                err.help(
                                    &format!(
                                        "trait `IndexMut` is required to modify indexed content{}",
                                         extra,
                                    ),
                                );
                            }
                        }
                    }
                }
            }

            _ => {
                err.span_label(span, format!("cannot {ACT}", ACT = act));
            }
        }

        err.buffer(&mut self.errors_buffer);
    }
}

fn suggest_ampmut_self<'cx, 'gcx, 'tcx>(
    tcx: TyCtxt<'cx, 'gcx, 'tcx>,
    local_decl: &mir::LocalDecl<'tcx>,
) -> (Span, String) {
    let sp = local_decl.source_info.span;
    (sp, match tcx.sess.source_map().span_to_snippet(sp) {
        Ok(snippet) => {
            let lt_pos = snippet.find('\'');
            if let Some(lt_pos) = lt_pos {
                format!("&{}mut self", &snippet[lt_pos..snippet.len() - 4])
            } else {
                "&mut self".to_string()
            }
        }
        _ => "&mut self".to_string()
    })
}

// When we want to suggest a user change a local variable to be a `&mut`, there
// are three potential "obvious" things to highlight:
//
// let ident [: Type] [= RightHandSideExpression];
//     ^^^^^    ^^^^     ^^^^^^^^^^^^^^^^^^^^^^^
//     (1.)     (2.)              (3.)
//
// We can always fallback on highlighting the first. But chances are good that
// the user experience will be better if we highlight one of the others if possible;
// for example, if the RHS is present and the Type is not, then the type is going to
// be inferred *from* the RHS, which means we should highlight that (and suggest
// that they borrow the RHS mutably).
//
// This implementation attempts to emulate AST-borrowck prioritization
// by trying (3.), then (2.) and finally falling back on (1.).
fn suggest_ampmut<'cx, 'gcx, 'tcx>(
    tcx: TyCtxt<'cx, 'gcx, 'tcx>,
    mir: &Mir<'tcx>,
    local: Local,
    local_decl: &mir::LocalDecl<'tcx>,
    opt_ty_info: Option<Span>,
) -> (Span, String) {
    let locations = mir.find_assignments(local);
    if !locations.is_empty() {
        let assignment_rhs_span = mir.source_info(locations[0]).span;
        if let Ok(src) = tcx.sess.source_map().span_to_snippet(assignment_rhs_span) {
            if let (true, Some(ws_pos)) = (
                src.starts_with("&'"),
                src.find(|c: char| -> bool { c.is_whitespace() }),
            ) {
                let lt_name = &src[1..ws_pos];
                let ty = &src[ws_pos..];
                return (assignment_rhs_span, format!("&{} mut {}", lt_name, ty));
            } else if src.starts_with('&') {
                let borrowed_expr = &src[1..];
                return (assignment_rhs_span, format!("&mut {}", borrowed_expr));
            }
        }
    }

    let highlight_span = match opt_ty_info {
        // if this is a variable binding with an explicit type,
        // try to highlight that for the suggestion.
        Some(ty_span) => ty_span,

        // otherwise, just highlight the span associated with
        // the (MIR) LocalDecl.
        None => local_decl.source_info.span,
    };

    if let Ok(src) = tcx.sess.source_map().span_to_snippet(highlight_span) {
        if let (true, Some(ws_pos)) = (
            src.starts_with("&'"),
            src.find(|c: char| -> bool { c.is_whitespace() }),
        ) {
            let lt_name = &src[1..ws_pos];
            let ty = &src[ws_pos..];
            return (highlight_span, format!("&{} mut{}", lt_name, ty));
        }
    }

    let ty_mut = local_decl.ty.builtin_deref(true).unwrap();
    assert_eq!(ty_mut.mutbl, hir::MutImmutable);
    (highlight_span,
     if local_decl.ty.is_region_ptr() {
         format!("&mut {}", ty_mut.ty)
     } else {
         format!("*mut {}", ty_mut.ty)
     })
}

fn is_closure_or_generator(ty: ty::Ty) -> bool {
    ty.is_closure() || ty.is_generator()
}

/// Add a suggestion to a struct definition given a field access to a local.
/// This function expects the local to be a reference to a struct in order to produce a suggestion.
///
/// ```text
/// LL |     s: &'a String
///    |        ---------- use `&'a mut String` here to make mutable
/// ```
fn annotate_struct_field(
    tcx: TyCtxt<'cx, 'gcx, 'tcx>,
    ty: ty::Ty<'tcx>,
    field: &mir::Field,
) -> Option<(Span, String)> {
    // Expect our local to be a reference to a struct of some kind.
    if let ty::TyKind::Ref(_, ty, _) = ty.sty {
        if let ty::TyKind::Adt(def, _) = ty.sty {
            let field = def.all_fields().nth(field.index())?;
            // Use the HIR types to construct the diagnostic message.
            let node_id = tcx.hir.as_local_node_id(field.did)?;
            let node = tcx.hir.find(node_id)?;
            // Now we're dealing with the actual struct that we're going to suggest a change to,
            // we can expect a field that is an immutable reference to a type.
            if let hir::Node::Field(field) = node {
                if let hir::TyKind::Rptr(lifetime, hir::MutTy {
                    mutbl: hir::Mutability::MutImmutable,
                    ref ty
                }) = field.ty.node {
                    // Get the snippets in two parts - the named lifetime (if there is one) and
                    // type being referenced, that way we can reconstruct the snippet without loss
                    // of detail.
                    let type_snippet = tcx.sess.source_map().span_to_snippet(ty.span).ok()?;
                    let lifetime_snippet = if !lifetime.is_elided() {
                        format!("{} ", tcx.sess.source_map().span_to_snippet(lifetime.span).ok()?)
                    } else {
                        String::new()
                    };

                    return Some((
                        field.ty.span,
                        format!(
                            "&{}mut {}",
                            lifetime_snippet, &*type_snippet,
                        ),
                    ));
                }
            }
        }
    }

    None
}
