use rustc::hir;
use rustc::hir::def_id::DefId;
use rustc::mir::{
    self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory, Local,
    LocalDecl, LocalKind, Location, Operand, Place, PlaceBase, Projection,
    ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind, VarBindingForm,
};
use rustc::ty::{self, Ty};
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::indexed_vec::Idx;
use rustc_errors::{Applicability, DiagnosticBuilder};
use syntax_pos::Span;
use syntax::source_map::CompilerDesugaringKind;

use super::nll::explain_borrow::BorrowExplanation;
use super::nll::region_infer::{RegionName, RegionNameSource};
use super::prefixes::IsPrefixOf;
use super::WriteKind;
use super::borrow_set::BorrowData;
use super::MirBorrowckCtxt;
use super::{InitializationRequiringAction, PrefixSet};
use super::error_reporting::{IncludingDowncast, UseSpans};
use crate::dataflow::drop_flag_effects;
use crate::dataflow::indexes::{MovePathIndex, MoveOutIndex};
use crate::util::borrowck_errors::{BorrowckErrors, Origin};

#[derive(Debug)]
struct MoveSite {
    /// Index of the "move out" that we found. The `MoveData` can
    /// then tell us where the move occurred.
    moi: MoveOutIndex,

    /// `true` if we traversed a back edge while walking from the point
    /// of error to the move site.
    traversed_back_edge: bool
}

/// Which case a StorageDeadOrDrop is for.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
enum StorageDeadOrDrop<'tcx> {
    LocalStorageDead,
    BoxedStorageDead,
    Destructor(Ty<'tcx>),
}

impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
    pub(super) fn report_use_of_moved_or_uninitialized(
        &mut self,
        location: Location,
        desired_action: InitializationRequiringAction,
        (moved_place, used_place, span): (&Place<'tcx>, &Place<'tcx>, Span),
        mpi: MovePathIndex,
    ) {
        debug!(
            "report_use_of_moved_or_uninitialized: location={:?} desired_action={:?} \
             moved_place={:?} used_place={:?} span={:?} mpi={:?}",
            location, desired_action, moved_place, used_place, span, mpi
        );

        let use_spans = self.move_spans(moved_place, location)
            .or_else(|| self.borrow_spans(span, location));
        let span = use_spans.args_or_use();

        let move_site_vec = self.get_moved_indexes(location, mpi);
        debug!(
            "report_use_of_moved_or_uninitialized: move_site_vec={:?}",
            move_site_vec
        );
        let move_out_indices: Vec<_> = move_site_vec
            .iter()
            .map(|move_site| move_site.moi)
            .collect();

        if move_out_indices.is_empty() {
            let root_place = self.prefixes(&used_place, PrefixSet::All).last().unwrap();

            if self.uninitialized_error_reported.contains(root_place) {
                debug!(
                    "report_use_of_moved_or_uninitialized place: error about {:?} suppressed",
                    root_place
                );
                return;
            }

            self.uninitialized_error_reported.insert(root_place.clone());

            let item_msg = match self.describe_place_with_options(used_place,
                                                                  IncludingDowncast(true)) {
                Some(name) => format!("`{}`", name),
                None => "value".to_owned(),
            };
            let mut err = self.infcx.tcx.cannot_act_on_uninitialized_variable(
                span,
                desired_action.as_noun(),
                &self.describe_place_with_options(moved_place, IncludingDowncast(true))
                    .unwrap_or_else(|| "_".to_owned()),
                Origin::Mir,
            );
            err.span_label(span, format!("use of possibly uninitialized {}", item_msg));

            use_spans.var_span_label(
                &mut err,
                format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()),
            );

            err.buffer(&mut self.errors_buffer);
        } else {
            if let Some((reported_place, _)) = self.move_error_reported.get(&move_out_indices) {
                if self.prefixes(&reported_place, PrefixSet::All)
                    .any(|p| p == used_place)
                {
                    debug!(
                        "report_use_of_moved_or_uninitialized place: error suppressed \
                         mois={:?}",
                        move_out_indices
                    );
                    return;
                }
            }

            let msg = ""; //FIXME: add "partially " or "collaterally "

            let mut err = self.infcx.tcx.cannot_act_on_moved_value(
                span,
                desired_action.as_noun(),
                msg,
                self.describe_place_with_options(&moved_place, IncludingDowncast(true)),
                Origin::Mir,
            );

            self.add_moved_or_invoked_closure_note(
                location,
                used_place,
                &mut err,
            );

            let mut is_loop_move = false;
            let is_partial_move = move_site_vec.iter().any(|move_site| {
                let move_out = self.move_data.moves[(*move_site).moi];
                let moved_place = &self.move_data.move_paths[move_out.path].place;
                used_place != moved_place && used_place.is_prefix_of(moved_place)
            });
            for move_site in &move_site_vec {
                let move_out = self.move_data.moves[(*move_site).moi];
                let moved_place = &self.move_data.move_paths[move_out.path].place;

                let move_spans = self.move_spans(moved_place, move_out.source);
                let move_span = move_spans.args_or_use();

                let move_msg = if move_spans.for_closure() {
                    " into closure"
                } else {
                    ""
                };

                if span == move_span {
                    err.span_label(
                        span,
                        format!("value moved{} here, in previous iteration of loop", move_msg),
                    );
                    is_loop_move = true;
                } else if move_site.traversed_back_edge {
                    err.span_label(
                        move_span,
                        format!(
                            "value moved{} here, in previous iteration of loop",
                            move_msg
                        ),
                    );
                } else {
                    err.span_label(move_span, format!("value moved{} here", move_msg));
                    move_spans.var_span_label(
                        &mut err,
                        format!("variable moved due to use{}", move_spans.describe()),
                    );
                }
                if Some(CompilerDesugaringKind::ForLoop) == move_span.compiler_desugaring_kind() {
                    if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) {
                        err.span_suggestion(
                            move_span,
                            "consider borrowing to avoid moving into the for loop",
                            format!("&{}", snippet),
                            Applicability::MaybeIncorrect,
                        );
                    }
                }
            }

            use_spans.var_span_label(
                &mut err,
                format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()),
            );

            if !is_loop_move {
                err.span_label(
                    span,
                    format!(
                        "value {} here {}",
                        desired_action.as_verb_in_past_tense(),
                        if is_partial_move { "after partial move" } else { "after move" },
                    ),
                );
            }

            let ty = used_place.ty(self.body, self.infcx.tcx).ty;
            let needs_note = match ty.sty {
                ty::Closure(id, _) => {
                    let tables = self.infcx.tcx.typeck_tables_of(id);
                    let hir_id = self.infcx.tcx.hir().as_local_hir_id(id).unwrap();

                    tables.closure_kind_origins().get(hir_id).is_none()
                }
                _ => true,
            };

            if needs_note {
                let mpi = self.move_data.moves[move_out_indices[0]].path;
                let place = &self.move_data.move_paths[mpi].place;

                let ty = place.ty(self.body, self.infcx.tcx).ty;
                let opt_name = self.describe_place_with_options(place, IncludingDowncast(true));
                let note_msg = match opt_name {
                    Some(ref name) => format!("`{}`", name),
                    None => "value".to_owned(),
                };
                if let ty::Param(param_ty) = ty.sty {
                    let tcx = self.infcx.tcx;
                    let generics = tcx.generics_of(self.mir_def_id);
                    let def_id = generics.type_param(&param_ty, tcx).def_id;
                    if let Some(sp) = tcx.hir().span_if_local(def_id) {
                        err.span_label(
                            sp,
                            "consider adding a `Copy` constraint to this type argument",
                        );
                    }
                }
                let span = if let Place::Base(PlaceBase::Local(local)) = place {
                    let decl = &self.body.local_decls[*local];
                    Some(decl.source_info.span)
                } else {
                    None
                };
                self.note_type_does_not_implement_copy(
                    &mut err,
                    &note_msg,
                    ty,
                    span,
                );
            }

            if let Some((_, mut old_err)) = self.move_error_reported
                .insert(move_out_indices, (used_place.clone(), err))
            {
                // Cancel the old error so it doesn't ICE.
                old_err.cancel();
            }
        }
    }

    pub(super) fn report_move_out_while_borrowed(
        &mut self,
        location: Location,
        (place, span): (&Place<'tcx>, Span),
        borrow: &BorrowData<'tcx>,
    ) {
        debug!(
            "report_move_out_while_borrowed: location={:?} place={:?} span={:?} borrow={:?}",
            location, place, span, borrow
        );
        let tcx = self.infcx.tcx;
        let value_msg = match self.describe_place(place) {
            Some(name) => format!("`{}`", name),
            None => "value".to_owned(),
        };
        let borrow_msg = match self.describe_place(&borrow.borrowed_place) {
            Some(name) => format!("`{}`", name),
            None => "value".to_owned(),
        };

        let borrow_spans = self.retrieve_borrow_spans(borrow);
        let borrow_span = borrow_spans.args_or_use();

        let move_spans = self.move_spans(place, location);
        let span = move_spans.args_or_use();

        let mut err = tcx.cannot_move_when_borrowed(
            span,
            &self.describe_place(place).unwrap_or_else(|| "_".to_owned()),
            Origin::Mir,
        );
        err.span_label(borrow_span, format!("borrow of {} occurs here", borrow_msg));
        err.span_label(span, format!("move out of {} occurs here", value_msg));

        borrow_spans.var_span_label(
            &mut err,
            format!("borrow occurs due to use{}", borrow_spans.describe())
        );

        move_spans.var_span_label(
            &mut err,
            format!("move occurs due to use{}", move_spans.describe())
        );

        self.explain_why_borrow_contains_point(
            location,
            borrow,
            None,
        ).add_explanation_to_diagnostic(self.infcx.tcx, self.body, &mut err, "", Some(borrow_span));
        err.buffer(&mut self.errors_buffer);
    }

    pub(super) fn report_use_while_mutably_borrowed(
        &mut self,
        location: Location,
        (place, _span): (&Place<'tcx>, Span),
        borrow: &BorrowData<'tcx>,
    ) -> DiagnosticBuilder<'cx> {
        let tcx = self.infcx.tcx;

        let borrow_spans = self.retrieve_borrow_spans(borrow);
        let borrow_span = borrow_spans.args_or_use();

        // Conflicting borrows are reported separately, so only check for move
        // captures.
        let use_spans = self.move_spans(place, location);
        let span = use_spans.var_or_use();

        let mut err = tcx.cannot_use_when_mutably_borrowed(
            span,
            &self.describe_place(place).unwrap_or_else(|| "_".to_owned()),
            borrow_span,
            &self.describe_place(&borrow.borrowed_place)
                .unwrap_or_else(|| "_".to_owned()),
            Origin::Mir,
        );

        borrow_spans.var_span_label(&mut err, {
            let place = &borrow.borrowed_place;
            let desc_place = self.describe_place(place).unwrap_or_else(|| "_".to_owned());

            format!("borrow occurs due to use of `{}`{}", desc_place, borrow_spans.describe())
        });

        self.explain_why_borrow_contains_point(location, borrow, None)
            .add_explanation_to_diagnostic(self.infcx.tcx, self.body, &mut err, "", None);
        err
    }

    pub(super) fn report_conflicting_borrow(
        &mut self,
        location: Location,
        (place, span): (&Place<'tcx>, Span),
        gen_borrow_kind: BorrowKind,
        issued_borrow: &BorrowData<'tcx>,
    ) -> DiagnosticBuilder<'cx> {
        let issued_spans = self.retrieve_borrow_spans(issued_borrow);
        let issued_span = issued_spans.args_or_use();

        let borrow_spans = self.borrow_spans(span, location);
        let span = borrow_spans.args_or_use();

        let container_name = if issued_spans.for_generator() || borrow_spans.for_generator() {
            "generator"
        } else {
            "closure"
        };

        let (desc_place, msg_place, msg_borrow, union_type_name) =
            self.describe_place_for_conflicting_borrow(place, &issued_borrow.borrowed_place);

        let explanation = self.explain_why_borrow_contains_point(location, issued_borrow, None);
        let second_borrow_desc = if explanation.is_explained() {
            "second "
        } else {
            ""
        };

        // FIXME: supply non-"" `opt_via` when appropriate
        let tcx = self.infcx.tcx;
        let first_borrow_desc;
        let mut err = match (
            gen_borrow_kind,
            "immutable",
            "mutable",
            issued_borrow.kind,
            "immutable",
            "mutable",
        ) {
            (BorrowKind::Shared, lft, _, BorrowKind::Mut { .. }, _, rgt) => {
                first_borrow_desc = "mutable ";
                tcx.cannot_reborrow_already_borrowed(
                    span,
                    &desc_place,
                    &msg_place,
                    lft,
                    issued_span,
                    "it",
                    rgt,
                    &msg_borrow,
                    None,
                    Origin::Mir,
                )
            }
            (BorrowKind::Mut { .. }, _, lft, BorrowKind::Shared, rgt, _) => {
                first_borrow_desc = "immutable ";
                tcx.cannot_reborrow_already_borrowed(
                    span,
                    &desc_place,
                    &msg_place,
                    lft,
                    issued_span,
                    "it",
                    rgt,
                    &msg_borrow,
                    None,
                    Origin::Mir,
                )
            }

            (BorrowKind::Mut { .. }, _, _, BorrowKind::Mut { .. }, _, _) => {
                first_borrow_desc = "first ";
                tcx.cannot_mutably_borrow_multiply(
                    span,
                    &desc_place,
                    &msg_place,
                    issued_span,
                    &msg_borrow,
                    None,
                    Origin::Mir,
                )
            }

            (BorrowKind::Unique, _, _, BorrowKind::Unique, _, _) => {
                first_borrow_desc = "first ";
                tcx.cannot_uniquely_borrow_by_two_closures(
                    span,
                    &desc_place,
                    issued_span,
                    None,
                    Origin::Mir,
                )
            }

            (BorrowKind::Mut { .. }, _, _, BorrowKind::Shallow, _, _)
            | (BorrowKind::Unique, _, _, BorrowKind::Shallow, _, _) => {
                let mut err = tcx.cannot_mutate_in_match_guard(
                    span,
                    issued_span,
                    &desc_place,
                    "mutably borrow",
                    Origin::Mir,
                );
                borrow_spans.var_span_label(
                    &mut err,
                    format!(
                        "borrow occurs due to use of `{}`{}", desc_place, borrow_spans.describe()
                    ),
                );

                return err;
            }

            (BorrowKind::Unique, _, _, _, _, _) => {
                first_borrow_desc = "first ";
                tcx.cannot_uniquely_borrow_by_one_closure(
                    span,
                    container_name,
                    &desc_place,
                    "",
                    issued_span,
                    "it",
                    "",
                    None,
                    Origin::Mir,
                )
            },

            (BorrowKind::Shared, lft, _, BorrowKind::Unique, _, _) => {
                first_borrow_desc = "first ";
                tcx.cannot_reborrow_already_uniquely_borrowed(
                    span,
                    container_name,
                    &desc_place,
                    "",
                    lft,
                    issued_span,
                    "",
                    None,
                    second_borrow_desc,
                    Origin::Mir,
                )
            }

            (BorrowKind::Mut { .. }, _, lft, BorrowKind::Unique, _, _) => {
                first_borrow_desc = "first ";
                tcx.cannot_reborrow_already_uniquely_borrowed(
                    span,
                    container_name,
                    &desc_place,
                    "",
                    lft,
                    issued_span,
                    "",
                    None,
                    second_borrow_desc,
                    Origin::Mir,
                )
            }

            (BorrowKind::Shared, _, _, BorrowKind::Shared, _, _)
            | (BorrowKind::Shared, _, _, BorrowKind::Shallow, _, _)
            | (BorrowKind::Shallow, _, _, BorrowKind::Mut { .. }, _, _)
            | (BorrowKind::Shallow, _, _, BorrowKind::Unique, _, _)
            | (BorrowKind::Shallow, _, _, BorrowKind::Shared, _, _)
            | (BorrowKind::Shallow, _, _, BorrowKind::Shallow, _, _) => unreachable!(),
        };

        if issued_spans == borrow_spans {
            borrow_spans.var_span_label(
                &mut err,
                format!("borrows occur due to use of `{}`{}", desc_place, borrow_spans.describe()),
            );
        } else {
            let borrow_place = &issued_borrow.borrowed_place;
            let borrow_place_desc = self.describe_place(borrow_place)
                                        .unwrap_or_else(|| "_".to_owned());
            issued_spans.var_span_label(
                &mut err,
                format!(
                    "first borrow occurs due to use of `{}`{}",
                    borrow_place_desc,
                    issued_spans.describe(),
                ),
            );

            borrow_spans.var_span_label(
                &mut err,
                format!(
                    "second borrow occurs due to use of `{}`{}",
                    desc_place,
                    borrow_spans.describe(),
                ),
            );
        }

        if union_type_name != "" {
            err.note(&format!(
                "`{}` is a field of the union `{}`, so it overlaps the field `{}`",
                msg_place, union_type_name, msg_borrow,
            ));
        }

        explanation.add_explanation_to_diagnostic(
            self.infcx.tcx,
            self.body,
            &mut err,
            first_borrow_desc,
            None,
        );

        err
    }

    /// Returns the description of the root place for a conflicting borrow and the full
    /// descriptions of the places that caused the conflict.
    ///
    /// In the simplest case, where there are no unions involved, if a mutable borrow of `x` is
    /// attempted while a shared borrow is live, then this function will return:
    ///
    ///     ("x", "", "")
    ///
    /// In the simple union case, if a mutable borrow of a union field `x.z` is attempted while
    /// a shared borrow of another field `x.y`, then this function will return:
    ///
    ///     ("x", "x.z", "x.y")
    ///
    /// In the more complex union case, where the union is a field of a struct, then if a mutable
    /// borrow of a union field in a struct `x.u.z` is attempted while a shared borrow of
    /// another field `x.u.y`, then this function will return:
    ///
    ///     ("x.u", "x.u.z", "x.u.y")
    ///
    /// This is used when creating error messages like below:
    ///
    /// >  cannot borrow `a.u` (via `a.u.z.c`) as immutable because it is also borrowed as
    /// >  mutable (via `a.u.s.b`) [E0502]
    pub(super) fn describe_place_for_conflicting_borrow(
        &self,
        first_borrowed_place: &Place<'tcx>,
        second_borrowed_place: &Place<'tcx>,
    ) -> (String, String, String, String) {
        // Define a small closure that we can use to check if the type of a place
        // is a union.
        let union_ty = |place: &Place<'tcx>| -> Option<Ty<'tcx>> {
            let ty = place.ty(self.body, self.infcx.tcx).ty;
            ty.ty_adt_def().filter(|adt| adt.is_union()).map(|_| ty)
        };
        let describe_place = |place| self.describe_place(place).unwrap_or_else(|| "_".to_owned());

        // Start with an empty tuple, so we can use the functions on `Option` to reduce some
        // code duplication (particularly around returning an empty description in the failure
        // case).
        Some(())
            .filter(|_| {
                // If we have a conflicting borrow of the same place, then we don't want to add
                // an extraneous "via x.y" to our diagnostics, so filter out this case.
                first_borrowed_place != second_borrowed_place
            })
            .and_then(|_| {
                // We're going to want to traverse the first borrowed place to see if we can find
                // field access to a union. If we find that, then we will keep the place of the
                // union being accessed and the field that was being accessed so we can check the
                // second borrowed place for the same union and a access to a different field.
                let mut current = first_borrowed_place;
                while let Place::Projection(box Projection { base, elem }) = current {
                    match elem {
                        ProjectionElem::Field(field, _) if union_ty(base).is_some() => {
                            return Some((base, field));
                        },
                        _ => current = base,
                    }
                }
                None
            })
            .and_then(|(target_base, target_field)| {
                // With the place of a union and a field access into it, we traverse the second
                // borrowed place and look for a access to a different field of the same union.
                let mut current = second_borrowed_place;
                while let Place::Projection(box Projection { base, elem }) = current {
                    if let ProjectionElem::Field(field, _) = elem {
                        if let Some(union_ty) = union_ty(base) {
                            if field != target_field && base == target_base {
                                return Some((
                                    describe_place(base),
                                    describe_place(first_borrowed_place),
                                    describe_place(second_borrowed_place),
                                    union_ty.to_string(),
                                ));
                            }
                        }
                    }

                    current = base;
                }
                None
            })
            .unwrap_or_else(|| {
                // If we didn't find a field access into a union, or both places match, then
                // only return the description of the first place.
                (
                    describe_place(first_borrowed_place),
                    "".to_string(),
                    "".to_string(),
                    "".to_string(),
                )
            })
    }

    /// Reports StorageDeadOrDrop of `place` conflicts with `borrow`.
    ///
    /// This means that some data referenced by `borrow` needs to live
    /// past the point where the StorageDeadOrDrop of `place` occurs.
    /// This is usually interpreted as meaning that `place` has too
    /// short a lifetime. (But sometimes it is more useful to report
    /// it as a more direct conflict between the execution of a
    /// `Drop::drop` with an aliasing borrow.)
    pub(super) fn report_borrowed_value_does_not_live_long_enough(
        &mut self,
        location: Location,
        borrow: &BorrowData<'tcx>,
        place_span: (&Place<'tcx>, Span),
        kind: Option<WriteKind>,
    ) {
        debug!(
            "report_borrowed_value_does_not_live_long_enough(\
             {:?}, {:?}, {:?}, {:?}\
             )",
            location, borrow, place_span, kind
        );

        let drop_span = place_span.1;
        let root_place = self.prefixes(&borrow.borrowed_place, PrefixSet::All)
            .last()
            .unwrap();

        let borrow_spans = self.retrieve_borrow_spans(borrow);
        let borrow_span = borrow_spans.var_or_use();

        let proper_span = match *root_place {
            Place::Base(PlaceBase::Local(local)) => self.body.local_decls[local].source_info.span,
            _ => drop_span,
        };

        if self.access_place_error_reported
            .contains(&(root_place.clone(), borrow_span))
        {
            debug!(
                "suppressing access_place error when borrow doesn't live long enough for {:?}",
                borrow_span
            );
            return;
        }

        self.access_place_error_reported
            .insert((root_place.clone(), borrow_span));

        if let StorageDeadOrDrop::Destructor(dropped_ty) =
            self.classify_drop_access_kind(&borrow.borrowed_place)
        {
            // If a borrow of path `B` conflicts with drop of `D` (and
            // we're not in the uninteresting case where `B` is a
            // prefix of `D`), then report this as a more interesting
            // destructor conflict.
            if !borrow.borrowed_place.is_prefix_of(place_span.0) {
                self.report_borrow_conflicts_with_destructor(
                    location, borrow, place_span, kind, dropped_ty,
                );
                return;
            }
        }

        let place_desc = self.describe_place(&borrow.borrowed_place);

        let kind_place = kind.filter(|_| place_desc.is_some()).map(|k| (k, place_span.0));
        let explanation = self.explain_why_borrow_contains_point(location, &borrow, kind_place);

        let err = match (place_desc, explanation) {
            (Some(_), _) if self.is_place_thread_local(root_place) => {
                self.report_thread_local_value_does_not_live_long_enough(drop_span, borrow_span)
            }
            // If the outlives constraint comes from inside the closure,
            // for example:
            //
            // let x = 0;
            // let y = &x;
            // Box::new(|| y) as Box<Fn() -> &'static i32>
            //
            // then just use the normal error. The closure isn't escaping
            // and `move` will not help here.
            (
                Some(ref name),
                BorrowExplanation::MustBeValidFor {
                    category: category @ ConstraintCategory::Return,
                    from_closure: false,
                    ref region_name,
                    span,
                    ..
                },
            )
            | (
                Some(ref name),
                BorrowExplanation::MustBeValidFor {
                    category: category @ ConstraintCategory::CallArgument,
                    from_closure: false,
                    ref region_name,
                    span,
                    ..
                },
            ) if borrow_spans.for_closure() => self.report_escaping_closure_capture(
                borrow_spans.args_or_use(),
                borrow_span,
                region_name,
                category,
                span,
                &format!("`{}`", name),
            ),
            (
                ref name,
                BorrowExplanation::MustBeValidFor {
                    category: ConstraintCategory::Assignment,
                    from_closure: false,
                    region_name: RegionName {
                        source: RegionNameSource::AnonRegionFromUpvar(upvar_span, ref upvar_name),
                        ..
                    },
                    span,
                    ..
                },
            ) => self.report_escaping_data(borrow_span, name, upvar_span, upvar_name, span),
            (Some(name), explanation) => self.report_local_value_does_not_live_long_enough(
                location,
                &name,
                &borrow,
                drop_span,
                borrow_spans,
                explanation,
            ),
            (None, explanation) => self.report_temporary_value_does_not_live_long_enough(
                location,
                &borrow,
                drop_span,
                borrow_spans,
                proper_span,
                explanation,
            ),
        };

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

    fn report_local_value_does_not_live_long_enough(
        &mut self,
        location: Location,
        name: &str,
        borrow: &BorrowData<'tcx>,
        drop_span: Span,
        borrow_spans: UseSpans,
        explanation: BorrowExplanation,
    ) -> DiagnosticBuilder<'cx> {
        debug!(
            "report_local_value_does_not_live_long_enough(\
             {:?}, {:?}, {:?}, {:?}, {:?}\
             )",
            location, name, borrow, drop_span, borrow_spans
        );

        let borrow_span = borrow_spans.var_or_use();
        if let BorrowExplanation::MustBeValidFor {
            category,
            span,
            ref opt_place_desc,
            from_closure: false,
            ..
        } = explanation {
            if let Some(diag) = self.try_report_cannot_return_reference_to_local(
                borrow,
                borrow_span,
                span,
                category,
                opt_place_desc.as_ref(),
            ) {
                return diag;
            }
        }

        let mut err = self.infcx.tcx.path_does_not_live_long_enough(
            borrow_span,
            &format!("`{}`", name),
            Origin::Mir,
        );

        if let Some(annotation) = self.annotate_argument_and_return_for_borrow(borrow) {
            let region_name = annotation.emit(self, &mut err);

            err.span_label(
                borrow_span,
                format!("`{}` would have to be valid for `{}`...", name, region_name),
            );

            if let Some(fn_hir_id) = self.infcx.tcx.hir().as_local_hir_id(self.mir_def_id) {
                err.span_label(
                    drop_span,
                    format!(
                        "...but `{}` will be dropped here, when the function `{}` returns",
                        name,
                        self.infcx.tcx.hir().name(fn_hir_id),
                    ),
                );

                err.note(
                    "functions cannot return a borrow to data owned within the function's scope, \
                     functions can only return borrows to data passed as arguments",
                );
                err.note(
                    "to learn more, visit <https://doc.rust-lang.org/book/ch04-02-\
                     references-and-borrowing.html#dangling-references>",
                );
            } else {
                err.span_label(
                    drop_span,
                    format!("...but `{}` dropped here while still borrowed", name),
                );
            }

            if let BorrowExplanation::MustBeValidFor { .. } = explanation {
            } else {
                explanation.add_explanation_to_diagnostic(
                    self.infcx.tcx,
                    self.body,
                    &mut err,
                    "",
                    None,
                );
            }
        } else {
            err.span_label(borrow_span, "borrowed value does not live long enough");
            err.span_label(
                drop_span,
                format!("`{}` dropped here while still borrowed", name),
            );

            let within = if borrow_spans.for_generator() {
                " by generator"
            } else {
                ""
            };

            borrow_spans.args_span_label(
                &mut err,
                format!("value captured here{}", within),
            );

            explanation.add_explanation_to_diagnostic(
                self.infcx.tcx, self.body, &mut err, "", None);
        }

        err
    }

    fn report_borrow_conflicts_with_destructor(
        &mut self,
        location: Location,
        borrow: &BorrowData<'tcx>,
        (place, drop_span): (&Place<'tcx>, Span),
        kind: Option<WriteKind>,
        dropped_ty: Ty<'tcx>,
    ) {
        debug!(
            "report_borrow_conflicts_with_destructor(\
             {:?}, {:?}, ({:?}, {:?}), {:?}\
             )",
            location, borrow, place, drop_span, kind,
        );

        let borrow_spans = self.retrieve_borrow_spans(borrow);
        let borrow_span = borrow_spans.var_or_use();

        let mut err = self.infcx
            .tcx
            .cannot_borrow_across_destructor(borrow_span, Origin::Mir);

        let what_was_dropped = match self.describe_place(place) {
            Some(name) => format!("`{}`", name.as_str()),
            None => String::from("temporary value"),
        };

        let label = match self.describe_place(&borrow.borrowed_place) {
            Some(borrowed) => format!(
                "here, drop of {D} needs exclusive access to `{B}`, \
                 because the type `{T}` implements the `Drop` trait",
                D = what_was_dropped,
                T = dropped_ty,
                B = borrowed
            ),
            None => format!(
                "here is drop of {D}; whose type `{T}` implements the `Drop` trait",
                D = what_was_dropped,
                T = dropped_ty
            ),
        };
        err.span_label(drop_span, label);

        // Only give this note and suggestion if they could be relevant.
        let explanation =
            self.explain_why_borrow_contains_point(location, borrow, kind.map(|k| (k, place)));
        match explanation {
            BorrowExplanation::UsedLater { .. }
            | BorrowExplanation::UsedLaterWhenDropped { .. } => {
                err.note("consider using a `let` binding to create a longer lived value");
            }
            _ => {}
        }

        explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.body, &mut err, "", None);

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

    fn report_thread_local_value_does_not_live_long_enough(
        &mut self,
        drop_span: Span,
        borrow_span: Span,
    ) -> DiagnosticBuilder<'cx> {
        debug!(
            "report_thread_local_value_does_not_live_long_enough(\
             {:?}, {:?}\
             )",
            drop_span, borrow_span
        );

        let mut err = self.infcx
            .tcx
            .thread_local_value_does_not_live_long_enough(borrow_span, Origin::Mir);

        err.span_label(
            borrow_span,
            "thread-local variables cannot be borrowed beyond the end of the function",
        );
        err.span_label(drop_span, "end of enclosing function is here");

        err
    }

    fn report_temporary_value_does_not_live_long_enough(
        &mut self,
        location: Location,
        borrow: &BorrowData<'tcx>,
        drop_span: Span,
        borrow_spans: UseSpans,
        proper_span: Span,
        explanation: BorrowExplanation,
    ) -> DiagnosticBuilder<'cx> {
        debug!(
            "report_temporary_value_does_not_live_long_enough(\
             {:?}, {:?}, {:?}, {:?}\
             )",
            location, borrow, drop_span, proper_span
        );

        if let BorrowExplanation::MustBeValidFor {
            category,
            span,
            from_closure: false,
            ..
        } = explanation {
            if let Some(diag) = self.try_report_cannot_return_reference_to_local(
                borrow,
                proper_span,
                span,
                category,
                None,
            ) {
                return diag;
            }
        }

        let tcx = self.infcx.tcx;
        let mut err = tcx.temporary_value_borrowed_for_too_long(proper_span, Origin::Mir);
        err.span_label(
            proper_span,
            "creates a temporary which is freed while still in use",
        );
        err.span_label(
            drop_span,
            "temporary value is freed at the end of this statement",
        );

        match explanation {
            BorrowExplanation::UsedLater(..)
            | BorrowExplanation::UsedLaterInLoop(..)
            | BorrowExplanation::UsedLaterWhenDropped { .. } => {
                // Only give this note and suggestion if it could be relevant.
                err.note("consider using a `let` binding to create a longer lived value");
            }
            _ => {}
        }
        explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.body, &mut err, "", None);

        let within = if borrow_spans.for_generator() {
            " by generator"
        } else {
            ""
        };

        borrow_spans.args_span_label(
            &mut err,
            format!("value captured here{}", within),
        );

        err
    }

    fn try_report_cannot_return_reference_to_local(
        &self,
        borrow: &BorrowData<'tcx>,
        borrow_span: Span,
        return_span: Span,
        category: ConstraintCategory,
        opt_place_desc: Option<&String>,
    ) -> Option<DiagnosticBuilder<'cx>> {
        let tcx = self.infcx.tcx;

        let return_kind = match category {
            ConstraintCategory::Return => "return",
            ConstraintCategory::Yield => "yield",
            _ => return None,
        };

        // FIXME use a better heuristic than Spans
        let reference_desc = if return_span == self.body.source_info(borrow.reserve_location).span {
            "reference to"
        } else {
            "value referencing"
        };

        let (place_desc, note) = if let Some(place_desc) = opt_place_desc {
            let local_kind = match borrow.borrowed_place {
                Place::Base(PlaceBase::Local(local)) => {
                    match self.body.local_kind(local) {
                        LocalKind::ReturnPointer
                        | LocalKind::Temp => bug!("temporary or return pointer with a name"),
                        LocalKind::Var => "local variable ",
                        LocalKind::Arg
                        if !self.upvars.is_empty()
                            && local == Local::new(1) => {
                            "variable captured by `move` "
                        }
                        LocalKind::Arg => {
                            "function parameter "
                        }
                    }
                }
                _ => "local data ",
            };
            (
                format!("{}`{}`", local_kind, place_desc),
                format!("`{}` is borrowed here", place_desc),
            )
        } else {
            let root_place = self.prefixes(&borrow.borrowed_place, PrefixSet::All)
                .last()
                .unwrap();
            let local = if let Place::Base(PlaceBase::Local(local)) = *root_place {
                local
            } else {
                bug!("try_report_cannot_return_reference_to_local: not a local")
            };
            match self.body.local_kind(local) {
                LocalKind::ReturnPointer | LocalKind::Temp => (
                    "temporary value".to_string(),
                    "temporary value created here".to_string(),
                ),
                LocalKind::Arg => (
                    "function parameter".to_string(),
                    "function parameter borrowed here".to_string(),
                ),
                LocalKind::Var => (
                    "local binding".to_string(),
                    "local binding introduced here".to_string(),
                ),
            }
        };

        let mut err = tcx.cannot_return_reference_to_local(
            return_span,
            return_kind,
            reference_desc,
            &place_desc,
            Origin::Mir,
        );

        if return_span != borrow_span {
            err.span_label(borrow_span, note);
        }

        Some(err)
    }

    fn report_escaping_closure_capture(
        &mut self,
        args_span: Span,
        var_span: Span,
        fr_name: &RegionName,
        category: ConstraintCategory,
        constraint_span: Span,
        captured_var: &str,
    ) -> DiagnosticBuilder<'cx> {
        let tcx = self.infcx.tcx;

        let mut err = tcx.cannot_capture_in_long_lived_closure(
            args_span,
            captured_var,
            var_span,
          Origin::Mir,
        );

        let suggestion = match tcx.sess.source_map().span_to_snippet(args_span) {
            Ok(string) => format!("move {}", string),
            Err(_) => "move |<args>| <body>".to_string()
        };

        err.span_suggestion(
            args_span,
            &format!("to force the closure to take ownership of {} (and any \
                      other referenced variables), use the `move` keyword",
                      captured_var),
            suggestion,
            Applicability::MachineApplicable,
        );

        match category {
            ConstraintCategory::Return => {
                err.span_note(constraint_span, "closure is returned here");
            }
            ConstraintCategory::CallArgument => {
                fr_name.highlight_region_name(&mut err);
                err.span_note(
                    constraint_span,
                    &format!("function requires argument type to outlive `{}`", fr_name),
                );
            }
            _ => bug!("report_escaping_closure_capture called with unexpected constraint \
                       category: `{:?}`", category),
        }
        err
    }

    fn report_escaping_data(
        &mut self,
        borrow_span: Span,
        name: &Option<String>,
        upvar_span: Span,
        upvar_name: &str,
        escape_span: Span,
    ) -> DiagnosticBuilder<'cx> {
        let tcx = self.infcx.tcx;

        let escapes_from = if tcx.is_closure(self.mir_def_id) {
            let tables = tcx.typeck_tables_of(self.mir_def_id);
            let mir_hir_id = tcx.hir().def_index_to_hir_id(self.mir_def_id.index);
            match tables.node_type(mir_hir_id).sty {
                ty::Closure(..) => "closure",
                ty::Generator(..) => "generator",
                _ => bug!("Closure body doesn't have a closure or generator type"),
            }
        } else {
            "function"
        };

        let mut err = tcx.borrowed_data_escapes_closure(escape_span, escapes_from, Origin::Mir);

        err.span_label(
            upvar_span,
            format!(
                "`{}` is declared here, outside of the {} body",
                upvar_name, escapes_from
            ),
        );

        err.span_label(
            borrow_span,
            format!(
                "borrow is only valid in the {} body",
                escapes_from
            ),
        );

        if let Some(name) = name {
            err.span_label(
                escape_span,
                format!("reference to `{}` escapes the {} body here", name, escapes_from),
            );
        } else {
            err.span_label(
                escape_span,
                format!("reference escapes the {} body here", escapes_from),
            );
        }

        err
    }

    fn get_moved_indexes(&mut self, location: Location, mpi: MovePathIndex) -> Vec<MoveSite> {
        let body = self.body;

        let mut stack = Vec::new();
        stack.extend(body.predecessor_locations(location).map(|predecessor| {
            let is_back_edge = location.dominates(predecessor, &self.dominators);
            (predecessor, is_back_edge)
        }));

        let mut visited = FxHashSet::default();
        let mut result = vec![];

        'dfs: while let Some((location, is_back_edge)) = stack.pop() {
            debug!(
                "report_use_of_moved_or_uninitialized: (current_location={:?}, back_edge={})",
                location, is_back_edge
            );

            if !visited.insert(location) {
                continue;
            }

            // check for moves
            let stmt_kind = body[location.block]
                .statements
                .get(location.statement_index)
                .map(|s| &s.kind);
            if let Some(StatementKind::StorageDead(..)) = stmt_kind {
                // this analysis only tries to find moves explicitly
                // written by the user, so we ignore the move-outs
                // created by `StorageDead` and at the beginning
                // of a function.
            } else {
                // If we are found a use of a.b.c which was in error, then we want to look for
                // moves not only of a.b.c but also a.b and a.
                //
                // Note that the moves data already includes "parent" paths, so we don't have to
                // worry about the other case: that is, if there is a move of a.b.c, it is already
                // marked as a move of a.b and a as well, so we will generate the correct errors
                // there.
                let mut mpis = vec![mpi];
                let move_paths = &self.move_data.move_paths;
                mpis.extend(move_paths[mpi].parents(move_paths));

                for moi in &self.move_data.loc_map[location] {
                    debug!("report_use_of_moved_or_uninitialized: moi={:?}", moi);
                    if mpis.contains(&self.move_data.moves[*moi].path) {
                        debug!("report_use_of_moved_or_uninitialized: found");
                        result.push(MoveSite {
                            moi: *moi,
                            traversed_back_edge: is_back_edge,
                        });

                        // Strictly speaking, we could continue our DFS here. There may be
                        // other moves that can reach the point of error. But it is kind of
                        // confusing to highlight them.
                        //
                        // Example:
                        //
                        // ```
                        // let a = vec![];
                        // let b = a;
                        // let c = a;
                        // drop(a); // <-- current point of error
                        // ```
                        //
                        // Because we stop the DFS here, we only highlight `let c = a`,
                        // and not `let b = a`. We will of course also report an error at
                        // `let c = a` which highlights `let b = a` as the move.
                        continue 'dfs;
                    }
                }
            }

            // check for inits
            let mut any_match = false;
            drop_flag_effects::for_location_inits(
                self.infcx.tcx,
                self.body,
                self.move_data,
                location,
                |m| {
                    if m == mpi {
                        any_match = true;
                    }
                },
            );
            if any_match {
                continue 'dfs;
            }

            stack.extend(body.predecessor_locations(location).map(|predecessor| {
                let back_edge = location.dominates(predecessor, &self.dominators);
                (predecessor, is_back_edge || back_edge)
            }));
        }

        result
    }

    pub(super) fn report_illegal_mutation_of_borrowed(
        &mut self,
        location: Location,
        (place, span): (&Place<'tcx>, Span),
        loan: &BorrowData<'tcx>,
    ) {
        let loan_spans = self.retrieve_borrow_spans(loan);
        let loan_span = loan_spans.args_or_use();

        let tcx = self.infcx.tcx;
        if loan.kind == BorrowKind::Shallow {
            let mut err = tcx.cannot_mutate_in_match_guard(
                span,
                loan_span,
                &self.describe_place(place).unwrap_or_else(|| "_".to_owned()),
                "assign",
                Origin::Mir,
            );
            loan_spans.var_span_label(
                &mut err,
                format!("borrow occurs due to use{}", loan_spans.describe()),
            );

            err.buffer(&mut self.errors_buffer);

            return;
        }

        let mut err = tcx.cannot_assign_to_borrowed(
            span,
            loan_span,
            &self.describe_place(place).unwrap_or_else(|| "_".to_owned()),
            Origin::Mir,
        );

        loan_spans.var_span_label(
            &mut err,
            format!("borrow occurs due to use{}", loan_spans.describe()),
        );

        self.explain_why_borrow_contains_point(location, loan, None)
            .add_explanation_to_diagnostic(self.infcx.tcx, self.body, &mut err, "", None);

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

    /// Reports an illegal reassignment; for example, an assignment to
    /// (part of) a non-`mut` local that occurs potentially after that
    /// local has already been initialized. `place` is the path being
    /// assigned; `err_place` is a place providing a reason why
    /// `place` is not mutable (e.g., the non-`mut` local `x` in an
    /// assignment to `x.f`).
    pub(super) fn report_illegal_reassignment(
        &mut self,
        _location: Location,
        (place, span): (&Place<'tcx>, Span),
        assigned_span: Span,
        err_place: &Place<'tcx>,
    ) {
        let (from_arg, local_decl) = if let Place::Base(PlaceBase::Local(local)) = *err_place {
            if let LocalKind::Arg = self.body.local_kind(local) {
                (true, Some(&self.body.local_decls[local]))
            } else {
                (false, Some(&self.body.local_decls[local]))
            }
        } else {
            (false, None)
        };

        // If root local is initialized immediately (everything apart from let
        // PATTERN;) then make the error refer to that local, rather than the
        // place being assigned later.
        let (place_description, assigned_span) = match local_decl {
            Some(LocalDecl {
                is_user_variable: Some(ClearCrossCrate::Clear),
                ..
            })
            | Some(LocalDecl {
                is_user_variable:
                    Some(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
                        opt_match_place: None,
                        ..
                    }))),
                ..
            })
            | Some(LocalDecl {
                is_user_variable: None,
                ..
            })
            | None => (self.describe_place(place), assigned_span),
            Some(decl) => (self.describe_place(err_place), decl.source_info.span),
        };

        let mut err = self.infcx.tcx.cannot_reassign_immutable(
            span,
            place_description.as_ref().map(AsRef::as_ref).unwrap_or("_"),
            from_arg,
            Origin::Mir,
        );
        let msg = if from_arg {
            "cannot assign to immutable argument"
        } else {
            "cannot assign twice to immutable variable"
        };
        if span != assigned_span {
            if !from_arg {
                let value_msg = match place_description {
                    Some(name) => format!("`{}`", name),
                    None => "value".to_owned(),
                };
                err.span_label(assigned_span, format!("first assignment to {}", value_msg));
            }
        }
        if let Some(decl) = local_decl {
            if let Some(name) = decl.name {
                if decl.can_be_made_mutable() {
                    err.span_suggestion(
                        decl.source_info.span,
                        "make this binding mutable",
                        format!("mut {}", name),
                        Applicability::MachineApplicable,
                    );
                }
            }
        }
        err.span_label(span, msg);
        err.buffer(&mut self.errors_buffer);
    }

    fn classify_drop_access_kind(&self, place: &Place<'tcx>) -> StorageDeadOrDrop<'tcx> {
        let tcx = self.infcx.tcx;
        match place {
            Place::Base(PlaceBase::Local(_)) |
            Place::Base(PlaceBase::Static(_)) => {
                StorageDeadOrDrop::LocalStorageDead
            }
            Place::Projection(box Projection { base, elem }) => {
                let base_access = self.classify_drop_access_kind(base);
                match elem {
                    ProjectionElem::Deref => match base_access {
                        StorageDeadOrDrop::LocalStorageDead
                        | StorageDeadOrDrop::BoxedStorageDead => {
                            assert!(
                                base.ty(self.body, tcx).ty.is_box(),
                                "Drop of value behind a reference or raw pointer"
                            );
                            StorageDeadOrDrop::BoxedStorageDead
                        }
                        StorageDeadOrDrop::Destructor(_) => base_access,
                    },
                    ProjectionElem::Field(..) | ProjectionElem::Downcast(..) => {
                        let base_ty = base.ty(self.body, tcx).ty;
                        match base_ty.sty {
                            ty::Adt(def, _) if def.has_dtor(tcx) => {
                                // Report the outermost adt with a destructor
                                match base_access {
                                    StorageDeadOrDrop::Destructor(_) => base_access,
                                    StorageDeadOrDrop::LocalStorageDead
                                    | StorageDeadOrDrop::BoxedStorageDead => {
                                        StorageDeadOrDrop::Destructor(base_ty)
                                    }
                                }
                            }
                            _ => base_access,
                        }
                    }

                    ProjectionElem::ConstantIndex { .. }
                    | ProjectionElem::Subslice { .. }
                    | ProjectionElem::Index(_) => base_access,
                }
            }
        }
    }

    /// Annotate argument and return type of function and closure with (synthesized) lifetime for
    /// borrow of local value that does not live long enough.
    fn annotate_argument_and_return_for_borrow(
        &self,
        borrow: &BorrowData<'tcx>,
    ) -> Option<AnnotatedBorrowFnSignature<'tcx>> {
        // Define a fallback for when we can't match a closure.
        let fallback = || {
            let is_closure = self.infcx.tcx.is_closure(self.mir_def_id);
            if is_closure {
                None
            } else {
                let ty = self.infcx.tcx.type_of(self.mir_def_id);
                match ty.sty {
                    ty::FnDef(_, _) | ty::FnPtr(_) => self.annotate_fn_sig(
                        self.mir_def_id,
                        self.infcx.tcx.fn_sig(self.mir_def_id),
                    ),
                    _ => None,
                }
            }
        };

        // In order to determine whether we need to annotate, we need to check whether the reserve
        // place was an assignment into a temporary.
        //
        // If it was, we check whether or not that temporary is eventually assigned into the return
        // place. If it was, we can add annotations about the function's return type and arguments
        // and it'll make sense.
        let location = borrow.reserve_location;
        debug!(
            "annotate_argument_and_return_for_borrow: location={:?}",
            location
        );
        if let Some(&Statement { kind: StatementKind::Assign(ref reservation, _), ..})
             = &self.body[location.block].statements.get(location.statement_index)
        {
            debug!(
                "annotate_argument_and_return_for_borrow: reservation={:?}",
                reservation
            );
            // Check that the initial assignment of the reserve location is into a temporary.
            let mut target = *match reservation {
                Place::Base(PlaceBase::Local(local))
                    if self.body.local_kind(*local) == LocalKind::Temp => local,
                _ => return None,
            };

            // Next, look through the rest of the block, checking if we are assigning the
            // `target` (that is, the place that contains our borrow) to anything.
            let mut annotated_closure = None;
            for stmt in &self.body[location.block].statements[location.statement_index + 1..] {
                debug!(
                    "annotate_argument_and_return_for_borrow: target={:?} stmt={:?}",
                    target, stmt
                );
                if let StatementKind::Assign(
                    Place::Base(PlaceBase::Local(assigned_to)),
                    box rvalue
                ) = &stmt.kind {
                    debug!(
                        "annotate_argument_and_return_for_borrow: assigned_to={:?} \
                         rvalue={:?}",
                        assigned_to, rvalue
                    );
                    // Check if our `target` was captured by a closure.
                    if let Rvalue::Aggregate(
                        box AggregateKind::Closure(def_id, substs),
                        operands,
                    ) = rvalue
                    {
                        for operand in operands {
                            let assigned_from = match operand {
                                Operand::Copy(assigned_from) | Operand::Move(assigned_from) => {
                                    assigned_from
                                }
                                _ => continue,
                            };
                            debug!(
                                "annotate_argument_and_return_for_borrow: assigned_from={:?}",
                                assigned_from
                            );

                            // Find the local from the operand.
                            let assigned_from_local = match assigned_from.local_or_deref_local() {
                                Some(local) => local,
                                None => continue,
                            };

                            if assigned_from_local != target {
                                continue;
                            }

                            // If a closure captured our `target` and then assigned
                            // into a place then we should annotate the closure in
                            // case it ends up being assigned into the return place.
                            annotated_closure = self.annotate_fn_sig(
                                *def_id,
                                self.infcx.closure_sig(*def_id, *substs),
                            );
                            debug!(
                                "annotate_argument_and_return_for_borrow: \
                                 annotated_closure={:?} assigned_from_local={:?} \
                                 assigned_to={:?}",
                                annotated_closure, assigned_from_local, assigned_to
                            );

                            if *assigned_to == mir::RETURN_PLACE {
                                // If it was assigned directly into the return place, then
                                // return now.
                                return annotated_closure;
                            } else {
                                // Otherwise, update the target.
                                target = *assigned_to;
                            }
                        }

                        // If none of our closure's operands matched, then skip to the next
                        // statement.
                        continue;
                    }

                    // Otherwise, look at other types of assignment.
                    let assigned_from = match rvalue {
                        Rvalue::Ref(_, _, assigned_from) => assigned_from,
                        Rvalue::Use(operand) => match operand {
                            Operand::Copy(assigned_from) | Operand::Move(assigned_from) => {
                                assigned_from
                            }
                            _ => continue,
                        },
                        _ => continue,
                    };
                    debug!(
                        "annotate_argument_and_return_for_borrow: \
                         assigned_from={:?}",
                        assigned_from,
                    );

                    // Find the local from the rvalue.
                    let assigned_from_local = match assigned_from.local_or_deref_local() {
                        Some(local) => local,
                        None => continue,
                    };
                    debug!(
                        "annotate_argument_and_return_for_borrow: \
                         assigned_from_local={:?}",
                        assigned_from_local,
                    );

                    // Check if our local matches the target - if so, we've assigned our
                    // borrow to a new place.
                    if assigned_from_local != target {
                        continue;
                    }

                    // If we assigned our `target` into a new place, then we should
                    // check if it was the return place.
                    debug!(
                        "annotate_argument_and_return_for_borrow: \
                         assigned_from_local={:?} assigned_to={:?}",
                        assigned_from_local, assigned_to
                    );
                    if *assigned_to == mir::RETURN_PLACE {
                        // If it was then return the annotated closure if there was one,
                        // else, annotate this function.
                        return annotated_closure.or_else(fallback);
                    }

                    // If we didn't assign into the return place, then we just update
                    // the target.
                    target = *assigned_to;
                }
            }

            // Check the terminator if we didn't find anything in the statements.
            let terminator = &self.body[location.block].terminator();
            debug!(
                "annotate_argument_and_return_for_borrow: target={:?} terminator={:?}",
                target, terminator
            );
            if let TerminatorKind::Call {
                destination: Some((Place::Base(PlaceBase::Local(assigned_to)), _)),
                args,
                ..
            } = &terminator.kind
            {
                debug!(
                    "annotate_argument_and_return_for_borrow: assigned_to={:?} args={:?}",
                    assigned_to, args
                );
                for operand in args {
                    let assigned_from = match operand {
                        Operand::Copy(assigned_from) | Operand::Move(assigned_from) => {
                            assigned_from
                        }
                        _ => continue,
                    };
                    debug!(
                        "annotate_argument_and_return_for_borrow: assigned_from={:?}",
                        assigned_from,
                    );

                    if let Some(assigned_from_local) = assigned_from.local_or_deref_local() {
                        debug!(
                            "annotate_argument_and_return_for_borrow: assigned_from_local={:?}",
                            assigned_from_local,
                        );

                        if *assigned_to == mir::RETURN_PLACE && assigned_from_local == target {
                            return annotated_closure.or_else(fallback);
                        }
                    }
                }
            }
        }

        // If we haven't found an assignment into the return place, then we need not add
        // any annotations.
        debug!("annotate_argument_and_return_for_borrow: none found");
        None
    }

    /// Annotate the first argument and return type of a function signature if they are
    /// references.
    fn annotate_fn_sig(
        &self,
        did: DefId,
        sig: ty::PolyFnSig<'tcx>,
    ) -> Option<AnnotatedBorrowFnSignature<'tcx>> {
        debug!("annotate_fn_sig: did={:?} sig={:?}", did, sig);
        let is_closure = self.infcx.tcx.is_closure(did);
        let fn_hir_id = self.infcx.tcx.hir().as_local_hir_id(did)?;
        let fn_decl = self.infcx.tcx.hir().fn_decl_by_hir_id(fn_hir_id)?;

        // We need to work out which arguments to highlight. We do this by looking
        // at the return type, where there are three cases:
        //
        // 1. If there are named arguments, then we should highlight the return type and
        //    highlight any of the arguments that are also references with that lifetime.
        //    If there are no arguments that have the same lifetime as the return type,
        //    then don't highlight anything.
        // 2. The return type is a reference with an anonymous lifetime. If this is
        //    the case, then we can take advantage of (and teach) the lifetime elision
        //    rules.
        //
        //    We know that an error is being reported. So the arguments and return type
        //    must satisfy the elision rules. Therefore, if there is a single argument
        //    then that means the return type and first (and only) argument have the same
        //    lifetime and the borrow isn't meeting that, we can highlight the argument
        //    and return type.
        //
        //    If there are multiple arguments then the first argument must be self (else
        //    it would not satisfy the elision rules), so we can highlight self and the
        //    return type.
        // 3. The return type is not a reference. In this case, we don't highlight
        //    anything.
        let return_ty = sig.output();
        match return_ty.skip_binder().sty {
            ty::Ref(return_region, _, _) if return_region.has_name() && !is_closure => {
                // This is case 1 from above, return type is a named reference so we need to
                // search for relevant arguments.
                let mut arguments = Vec::new();
                for (index, argument) in sig.inputs().skip_binder().iter().enumerate() {
                    if let ty::Ref(argument_region, _, _) = argument.sty {
                        if argument_region == return_region {
                            // Need to use the `rustc::ty` types to compare against the
                            // `return_region`. Then use the `rustc::hir` type to get only
                            // the lifetime span.
                            if let hir::TyKind::Rptr(lifetime, _) = &fn_decl.inputs[index].node {
                                // With access to the lifetime, we can get
                                // the span of it.
                                arguments.push((*argument, lifetime.span));
                            } else {
                                bug!("ty type is a ref but hir type is not");
                            }
                        }
                    }
                }

                // We need to have arguments. This shouldn't happen, but it's worth checking.
                if arguments.is_empty() {
                    return None;
                }

                // We use a mix of the HIR and the Ty types to get information
                // as the HIR doesn't have full types for closure arguments.
                let return_ty = *sig.output().skip_binder();
                let mut return_span = fn_decl.output.span();
                if let hir::FunctionRetTy::Return(ty) = &fn_decl.output {
                    if let hir::TyKind::Rptr(lifetime, _) = ty.node {
                        return_span = lifetime.span;
                    }
                }

                Some(AnnotatedBorrowFnSignature::NamedFunction {
                    arguments,
                    return_ty,
                    return_span,
                })
            }
            ty::Ref(_, _, _) if is_closure => {
                // This is case 2 from above but only for closures, return type is anonymous
                // reference so we select
                // the first argument.
                let argument_span = fn_decl.inputs.first()?.span;
                let argument_ty = sig.inputs().skip_binder().first()?;

                // Closure arguments are wrapped in a tuple, so we need to get the first
                // from that.
                if let ty::Tuple(elems) = argument_ty.sty {
                    let argument_ty = elems.first()?.expect_ty();
                    if let ty::Ref(_, _, _) = argument_ty.sty {
                        return Some(AnnotatedBorrowFnSignature::Closure {
                            argument_ty,
                            argument_span,
                        });
                    }
                }

                None
            }
            ty::Ref(_, _, _) => {
                // This is also case 2 from above but for functions, return type is still an
                // anonymous reference so we select the first argument.
                let argument_span = fn_decl.inputs.first()?.span;
                let argument_ty = sig.inputs().skip_binder().first()?;

                let return_span = fn_decl.output.span();
                let return_ty = *sig.output().skip_binder();

                // We expect the first argument to be a reference.
                match argument_ty.sty {
                    ty::Ref(_, _, _) => {}
                    _ => return None,
                }

                Some(AnnotatedBorrowFnSignature::AnonymousFunction {
                    argument_ty,
                    argument_span,
                    return_ty,
                    return_span,
                })
            }
            _ => {
                // This is case 3 from above, return type is not a reference so don't highlight
                // anything.
                None
            }
        }
    }
}

#[derive(Debug)]
enum AnnotatedBorrowFnSignature<'tcx> {
    NamedFunction {
        arguments: Vec<(Ty<'tcx>, Span)>,
        return_ty: Ty<'tcx>,
        return_span: Span,
    },
    AnonymousFunction {
        argument_ty: Ty<'tcx>,
        argument_span: Span,
        return_ty: Ty<'tcx>,
        return_span: Span,
    },
    Closure {
        argument_ty: Ty<'tcx>,
        argument_span: Span,
    },
}

impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
    /// Annotate the provided diagnostic with information about borrow from the fn signature that
    /// helps explain.
    pub(super) fn emit(
        &self,
        cx: &mut MirBorrowckCtxt<'_, 'tcx>,
        diag: &mut DiagnosticBuilder<'_>,
    ) -> String {
        match self {
            AnnotatedBorrowFnSignature::Closure {
                argument_ty,
                argument_span,
            } => {
                diag.span_label(
                    *argument_span,
                    format!("has type `{}`", cx.get_name_for_ty(argument_ty, 0)),
                );

                cx.get_region_name_for_ty(argument_ty, 0)
            }
            AnnotatedBorrowFnSignature::AnonymousFunction {
                argument_ty,
                argument_span,
                return_ty,
                return_span,
            } => {
                let argument_ty_name = cx.get_name_for_ty(argument_ty, 0);
                diag.span_label(*argument_span, format!("has type `{}`", argument_ty_name));

                let return_ty_name = cx.get_name_for_ty(return_ty, 0);
                let types_equal = return_ty_name == argument_ty_name;
                diag.span_label(
                    *return_span,
                    format!(
                        "{}has type `{}`",
                        if types_equal { "also " } else { "" },
                        return_ty_name,
                    ),
                );

                diag.note(
                    "argument and return type have the same lifetime due to lifetime elision rules",
                );
                diag.note(
                    "to learn more, visit <https://doc.rust-lang.org/book/ch10-03-\
                     lifetime-syntax.html#lifetime-elision>",
                );

                cx.get_region_name_for_ty(return_ty, 0)
            }
            AnnotatedBorrowFnSignature::NamedFunction {
                arguments,
                return_ty,
                return_span,
            } => {
                // Region of return type and arguments checked to be the same earlier.
                let region_name = cx.get_region_name_for_ty(return_ty, 0);
                for (_, argument_span) in arguments {
                    diag.span_label(*argument_span, format!("has lifetime `{}`", region_name));
                }

                diag.span_label(
                    *return_span,
                    format!("also has lifetime `{}`", region_name,),
                );

                diag.help(&format!(
                    "use data from the highlighted arguments which match the `{}` lifetime of \
                     the return type",
                    region_name,
                ));

                region_name
            }
        }
    }
}
