//! A classic liveness analysis based on dataflow over the AST. Computes,
//! for each local variable in a function, whether that variable is live
//! at a given point. Program execution points are identified by their
//! IDs.
//!
//! # Basic idea
//!
//! The basic model is that each local variable is assigned an index. We
//! represent sets of local variables using a vector indexed by this
//! index. The value in the vector is either 0, indicating the variable
//! is dead, or the ID of an expression that uses the variable.
//!
//! We conceptually walk over the AST in reverse execution order. If we
//! find a use of a variable, we add it to the set of live variables. If
//! we find an assignment to a variable, we remove it from the set of live
//! variables. When we have to merge two flows, we take the union of
//! those two flows -- if the variable is live on both paths, we simply
//! pick one ID. In the event of loops, we continue doing this until a
//! fixed point is reached.
//!
//! ## Checking initialization
//!
//! At the function entry point, all variables must be dead. If this is
//! not the case, we can report an error using the ID found in the set of
//! live variables, which identifies a use of the variable which is not
//! dominated by an assignment.
//!
//! ## Checking moves
//!
//! After each explicit move, the variable must be dead.
//!
//! ## Computing last uses
//!
//! Any use of the variable where the variable is dead afterwards is a
//! last use.
//!
//! # Implementation details
//!
//! The actual implementation contains two (nested) walks over the AST.
//! The outer walk has the job of building up the ir_maps instance for the
//! enclosing function. On the way down the tree, it identifies those AST
//! nodes and variable IDs that will be needed for the liveness analysis
//! and assigns them contiguous IDs. The liveness ID for an AST node is
//! called a `live_node` (it's a newtype'd `u32`) and the ID for a variable
//! is called a `variable` (another newtype'd `u32`).
//!
//! On the way back up the tree, as we are about to exit from a function
//! declaration we allocate a `liveness` instance. Now that we know
//! precisely how many nodes and variables we need, we can allocate all
//! the various arrays that we will need to precisely the right size. We then
//! perform the actual propagation on the `liveness` instance.
//!
//! This propagation is encoded in the various `propagate_through_*()`
//! methods. It effectively does a reverse walk of the AST; whenever we
//! reach a loop node, we iterate until a fixed point is reached.
//!
//! ## The `RWU` struct
//!
//! At each live node `N`, we track three pieces of information for each
//! variable `V` (these are encapsulated in the `RWU` struct):
//!
//! - `reader`: the `LiveNode` ID of some node which will read the value
//!    that `V` holds on entry to `N`. Formally: a node `M` such
//!    that there exists a path `P` from `N` to `M` where `P` does not
//!    write `V`. If the `reader` is `invalid_node()`, then the current
//!    value will never be read (the variable is dead, essentially).
//!
//! - `writer`: the `LiveNode` ID of some node which will write the
//!    variable `V` and which is reachable from `N`. Formally: a node `M`
//!    such that there exists a path `P` from `N` to `M` and `M` writes
//!    `V`. If the `writer` is `invalid_node()`, then there is no writer
//!    of `V` that follows `N`.
//!
//! - `used`: a boolean value indicating whether `V` is *used*. We
//!   distinguish a *read* from a *use* in that a *use* is some read that
//!   is not just used to generate a new value. For example, `x += 1` is
//!   a read but not a use. This is used to generate better warnings.
//!
//! ## Special Variables
//!
//! We generate various special variables for various, well, special purposes.
//! These are described in the `specials` struct:
//!
//! - `exit_ln`: a live node that is generated to represent every 'exit' from
//!   the function, whether it be by explicit return, panic, or other means.
//!
//! - `fallthrough_ln`: a live node that represents a fallthrough
//!
//! - `clean_exit_var`: a synthetic variable that is only 'read' from the
//!   fallthrough node. It is only live if the function could converge
//!   via means other than an explicit `return` expression. That is, it is
//!   only dead if the end of the function's block can never be reached.
//!   It is the responsibility of typeck to ensure that there are no
//!   `return` expressions in a function declared as diverging.

use self::LiveNodeKind::*;
use self::VarKind::*;

use rustc_ast::ast;
use rustc_data_structures::fx::FxIndexMap;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::def::*;
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::{self, FnKind, NestedVisitorMap, Visitor};
use rustc_hir::{Expr, HirId, HirIdMap, HirIdSet, Node};
use rustc_middle::hir::map::Map;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::lint;
use rustc_span::symbol::sym;
use rustc_span::Span;

use std::collections::VecDeque;
use std::io;
use std::io::prelude::*;
use std::rc::Rc;
use std::{fmt, u32};

#[derive(Copy, Clone, PartialEq)]
struct Variable(u32);

#[derive(Copy, Clone, PartialEq)]
struct LiveNode(u32);

impl Variable {
    fn get(&self) -> usize {
        self.0 as usize
    }
}

impl LiveNode {
    fn get(&self) -> usize {
        self.0 as usize
    }
}

#[derive(Copy, Clone, PartialEq, Debug)]
enum LiveNodeKind {
    UpvarNode(Span),
    ExprNode(Span),
    VarDefNode(Span),
    ExitNode,
}

fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt<'_>) -> String {
    let sm = tcx.sess.source_map();
    match lnk {
        UpvarNode(s) => format!("Upvar node [{}]", sm.span_to_string(s)),
        ExprNode(s) => format!("Expr node [{}]", sm.span_to_string(s)),
        VarDefNode(s) => format!("Var def node [{}]", sm.span_to_string(s)),
        ExitNode => "Exit node".to_owned(),
    }
}

impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> {
    type Map = Map<'tcx>;

    fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
        NestedVisitorMap::OnlyBodies(self.tcx.hir())
    }

    fn visit_fn(
        &mut self,
        fk: FnKind<'tcx>,
        fd: &'tcx hir::FnDecl<'tcx>,
        b: hir::BodyId,
        s: Span,
        id: HirId,
    ) {
        visit_fn(self, fk, fd, b, s, id);
    }

    fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) {
        visit_local(self, l);
    }
    fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
        visit_expr(self, ex);
    }
    fn visit_arm(&mut self, a: &'tcx hir::Arm<'tcx>) {
        visit_arm(self, a);
    }
}

fn check_mod_liveness(tcx: TyCtxt<'_>, module_def_id: DefId) {
    tcx.hir().visit_item_likes_in_module(
        module_def_id,
        &mut IrMaps::new(tcx, module_def_id).as_deep_visitor(),
    );
}

pub fn provide(providers: &mut Providers<'_>) {
    *providers = Providers { check_mod_liveness, ..*providers };
}

impl fmt::Debug for LiveNode {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "ln({})", self.get())
    }
}

impl fmt::Debug for Variable {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "v({})", self.get())
    }
}

// ______________________________________________________________________
// Creating ir_maps
//
// This is the first pass and the one that drives the main
// computation.  It walks up and down the IR once.  On the way down,
// we count for each function the number of variables as well as
// liveness nodes.  A liveness node is basically an expression or
// capture clause that does something of interest: either it has
// interesting control flow or it uses/defines a local variable.
//
// On the way back up, at each function node we create liveness sets
// (we now know precisely how big to make our various vectors and so
// forth) and then do the data-flow propagation to compute the set
// of live variables at each program point.
//
// Finally, we run back over the IR one last time and, using the
// computed liveness, check various safety conditions.  For example,
// there must be no live nodes at the definition site for a variable
// unless it has an initializer.  Similarly, each non-mutable local
// variable must not be assigned if there is some successor
// assignment.  And so forth.

impl LiveNode {
    fn is_valid(&self) -> bool {
        self.0 != u32::MAX
    }
}

fn invalid_node() -> LiveNode {
    LiveNode(u32::MAX)
}

struct CaptureInfo {
    ln: LiveNode,
    var_hid: HirId,
}

#[derive(Copy, Clone, Debug)]
struct LocalInfo {
    id: HirId,
    name: ast::Name,
    is_shorthand: bool,
}

#[derive(Copy, Clone, Debug)]
enum VarKind {
    Param(HirId, ast::Name),
    Local(LocalInfo),
    CleanExit,
}

struct IrMaps<'tcx> {
    tcx: TyCtxt<'tcx>,
    body_owner: DefId,
    num_live_nodes: usize,
    num_vars: usize,
    live_node_map: HirIdMap<LiveNode>,
    variable_map: HirIdMap<Variable>,
    capture_info_map: HirIdMap<Rc<Vec<CaptureInfo>>>,
    var_kinds: Vec<VarKind>,
    lnks: Vec<LiveNodeKind>,
}

impl IrMaps<'tcx> {
    fn new(tcx: TyCtxt<'tcx>, body_owner: DefId) -> IrMaps<'tcx> {
        IrMaps {
            tcx,
            body_owner,
            num_live_nodes: 0,
            num_vars: 0,
            live_node_map: HirIdMap::default(),
            variable_map: HirIdMap::default(),
            capture_info_map: Default::default(),
            var_kinds: Vec::new(),
            lnks: Vec::new(),
        }
    }

    fn add_live_node(&mut self, lnk: LiveNodeKind) -> LiveNode {
        let ln = LiveNode(self.num_live_nodes as u32);
        self.lnks.push(lnk);
        self.num_live_nodes += 1;

        debug!("{:?} is of kind {}", ln, live_node_kind_to_string(lnk, self.tcx));

        ln
    }

    fn add_live_node_for_node(&mut self, hir_id: HirId, lnk: LiveNodeKind) {
        let ln = self.add_live_node(lnk);
        self.live_node_map.insert(hir_id, ln);

        debug!("{:?} is node {:?}", ln, hir_id);
    }

    fn add_variable(&mut self, vk: VarKind) -> Variable {
        let v = Variable(self.num_vars as u32);
        self.var_kinds.push(vk);
        self.num_vars += 1;

        match vk {
            Local(LocalInfo { id: node_id, .. }) | Param(node_id, _) => {
                self.variable_map.insert(node_id, v);
            }
            CleanExit => {}
        }

        debug!("{:?} is {:?}", v, vk);

        v
    }

    fn variable(&self, hir_id: HirId, span: Span) -> Variable {
        match self.variable_map.get(&hir_id) {
            Some(&var) => var,
            None => {
                span_bug!(span, "no variable registered for id {:?}", hir_id);
            }
        }
    }

    fn variable_name(&self, var: Variable) -> String {
        match self.var_kinds[var.get()] {
            Local(LocalInfo { name, .. }) | Param(_, name) => name.to_string(),
            CleanExit => "<clean-exit>".to_owned(),
        }
    }

    fn variable_is_shorthand(&self, var: Variable) -> bool {
        match self.var_kinds[var.get()] {
            Local(LocalInfo { is_shorthand, .. }) => is_shorthand,
            Param(..) | CleanExit => false,
        }
    }

    fn set_captures(&mut self, hir_id: HirId, cs: Vec<CaptureInfo>) {
        self.capture_info_map.insert(hir_id, Rc::new(cs));
    }

    fn lnk(&self, ln: LiveNode) -> LiveNodeKind {
        self.lnks[ln.get()]
    }
}

fn visit_fn<'tcx>(
    ir: &mut IrMaps<'tcx>,
    fk: FnKind<'tcx>,
    decl: &'tcx hir::FnDecl<'tcx>,
    body_id: hir::BodyId,
    sp: Span,
    id: hir::HirId,
) {
    debug!("visit_fn");

    // swap in a new set of IR maps for this function body:
    let def_id = ir.tcx.hir().local_def_id(id);
    let mut fn_maps = IrMaps::new(ir.tcx, def_id);

    // Don't run unused pass for #[derive()]
    if let FnKind::Method(..) = fk {
        let parent = ir.tcx.hir().get_parent_item(id);
        if let Some(Node::Item(i)) = ir.tcx.hir().find(parent) {
            if i.attrs.iter().any(|a| a.check_name(sym::automatically_derived)) {
                return;
            }
        }
    }

    debug!("creating fn_maps: {:p}", &fn_maps);

    let body = ir.tcx.hir().body(body_id);

    for param in body.params {
        let is_shorthand = match param.pat.kind {
            rustc_hir::PatKind::Struct(..) => true,
            _ => false,
        };
        param.pat.each_binding(|_bm, hir_id, _x, ident| {
            debug!("adding parameters {:?}", hir_id);
            let var = if is_shorthand {
                Local(LocalInfo { id: hir_id, name: ident.name, is_shorthand: true })
            } else {
                Param(hir_id, ident.name)
            };
            fn_maps.add_variable(var);
        })
    }

    // gather up the various local variables, significant expressions,
    // and so forth:
    intravisit::walk_fn(&mut fn_maps, fk, decl, body_id, sp, id);

    // compute liveness
    let mut lsets = Liveness::new(&mut fn_maps, def_id);
    let entry_ln = lsets.compute(&body.value);

    // check for various error conditions
    lsets.visit_body(body);
    lsets.warn_about_unused_args(body, entry_ln);
}

fn add_from_pat(ir: &mut IrMaps<'_>, pat: &hir::Pat<'_>) {
    // For struct patterns, take note of which fields used shorthand
    // (`x` rather than `x: x`).
    let mut shorthand_field_ids = HirIdSet::default();
    let mut pats = VecDeque::new();
    pats.push_back(pat);
    while let Some(pat) = pats.pop_front() {
        use rustc_hir::PatKind::*;
        match &pat.kind {
            Binding(.., inner_pat) => {
                pats.extend(inner_pat.iter());
            }
            Struct(_, fields, _) => {
                let ids = fields.iter().filter(|f| f.is_shorthand).map(|f| f.pat.hir_id);
                shorthand_field_ids.extend(ids);
            }
            Ref(inner_pat, _) | Box(inner_pat) => {
                pats.push_back(inner_pat);
            }
            TupleStruct(_, inner_pats, _) | Tuple(inner_pats, _) | Or(inner_pats) => {
                pats.extend(inner_pats.iter());
            }
            Slice(pre_pats, inner_pat, post_pats) => {
                pats.extend(pre_pats.iter());
                pats.extend(inner_pat.iter());
                pats.extend(post_pats.iter());
            }
            _ => {}
        }
    }

    pat.each_binding(|_, hir_id, _, ident| {
        ir.add_live_node_for_node(hir_id, VarDefNode(ident.span));
        ir.add_variable(Local(LocalInfo {
            id: hir_id,
            name: ident.name,
            is_shorthand: shorthand_field_ids.contains(&hir_id),
        }));
    });
}

fn visit_local<'tcx>(ir: &mut IrMaps<'tcx>, local: &'tcx hir::Local<'tcx>) {
    add_from_pat(ir, &local.pat);
    intravisit::walk_local(ir, local);
}

fn visit_arm<'tcx>(ir: &mut IrMaps<'tcx>, arm: &'tcx hir::Arm<'tcx>) {
    add_from_pat(ir, &arm.pat);
    intravisit::walk_arm(ir, arm);
}

fn visit_expr<'tcx>(ir: &mut IrMaps<'tcx>, expr: &'tcx Expr<'tcx>) {
    match expr.kind {
        // live nodes required for uses or definitions of variables:
        hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) => {
            debug!("expr {}: path that leads to {:?}", expr.hir_id, path.res);
            if let Res::Local(var_hir_id) = path.res {
                let upvars = ir.tcx.upvars(ir.body_owner);
                if !upvars.map_or(false, |upvars| upvars.contains_key(&var_hir_id)) {
                    ir.add_live_node_for_node(expr.hir_id, ExprNode(expr.span));
                }
            }
            intravisit::walk_expr(ir, expr);
        }
        hir::ExprKind::Closure(..) => {
            // Interesting control flow (for loops can contain labeled
            // breaks or continues)
            ir.add_live_node_for_node(expr.hir_id, ExprNode(expr.span));

            // Make a live_node for each captured variable, with the span
            // being the location that the variable is used.  This results
            // in better error messages than just pointing at the closure
            // construction site.
            let mut call_caps = Vec::new();
            let closure_def_id = ir.tcx.hir().local_def_id(expr.hir_id);
            if let Some(upvars) = ir.tcx.upvars(closure_def_id) {
                let parent_upvars = ir.tcx.upvars(ir.body_owner);
                call_caps.extend(upvars.iter().filter_map(|(&var_id, upvar)| {
                    let has_parent =
                        parent_upvars.map_or(false, |upvars| upvars.contains_key(&var_id));
                    if !has_parent {
                        let upvar_ln = ir.add_live_node(UpvarNode(upvar.span));
                        Some(CaptureInfo { ln: upvar_ln, var_hid: var_id })
                    } else {
                        None
                    }
                }));
            }
            ir.set_captures(expr.hir_id, call_caps);
            let old_body_owner = ir.body_owner;
            ir.body_owner = closure_def_id;
            intravisit::walk_expr(ir, expr);
            ir.body_owner = old_body_owner;
        }

        // live nodes required for interesting control flow:
        hir::ExprKind::Match(..) | hir::ExprKind::Loop(..) => {
            ir.add_live_node_for_node(expr.hir_id, ExprNode(expr.span));
            intravisit::walk_expr(ir, expr);
        }
        hir::ExprKind::Binary(op, ..) if op.node.is_lazy() => {
            ir.add_live_node_for_node(expr.hir_id, ExprNode(expr.span));
            intravisit::walk_expr(ir, expr);
        }

        // otherwise, live nodes are not required:
        hir::ExprKind::Index(..)
        | hir::ExprKind::Field(..)
        | hir::ExprKind::Array(..)
        | hir::ExprKind::Call(..)
        | hir::ExprKind::MethodCall(..)
        | hir::ExprKind::Tup(..)
        | hir::ExprKind::Binary(..)
        | hir::ExprKind::AddrOf(..)
        | hir::ExprKind::Cast(..)
        | hir::ExprKind::DropTemps(..)
        | hir::ExprKind::Unary(..)
        | hir::ExprKind::Break(..)
        | hir::ExprKind::Continue(_)
        | hir::ExprKind::Lit(_)
        | hir::ExprKind::Ret(..)
        | hir::ExprKind::Block(..)
        | hir::ExprKind::Assign(..)
        | hir::ExprKind::AssignOp(..)
        | hir::ExprKind::Struct(..)
        | hir::ExprKind::Repeat(..)
        | hir::ExprKind::LlvmInlineAsm(..)
        | hir::ExprKind::Box(..)
        | hir::ExprKind::Yield(..)
        | hir::ExprKind::Type(..)
        | hir::ExprKind::Err
        | hir::ExprKind::Path(hir::QPath::TypeRelative(..)) => {
            intravisit::walk_expr(ir, expr);
        }
    }
}

// ______________________________________________________________________
// Computing liveness sets
//
// Actually we compute just a bit more than just liveness, but we use
// the same basic propagation framework in all cases.

#[derive(Clone, Copy)]
struct RWU {
    reader: LiveNode,
    writer: LiveNode,
    used: bool,
}

/// Conceptually, this is like a `Vec<RWU>`. But the number of `RWU`s can get
/// very large, so it uses a more compact representation that takes advantage
/// of the fact that when the number of `RWU`s is large, most of them have an
/// invalid reader and an invalid writer.
struct RWUTable {
    /// Each entry in `packed_rwus` is either INV_INV_FALSE, INV_INV_TRUE, or
    /// an index into `unpacked_rwus`. In the common cases, this compacts the
    /// 65 bits of data into 32; in the uncommon cases, it expands the 65 bits
    /// in 96.
    ///
    /// More compact representations are possible -- e.g., use only 2 bits per
    /// packed `RWU` and make the secondary table a HashMap that maps from
    /// indices to `RWU`s -- but this one strikes a good balance between size
    /// and speed.
    packed_rwus: Vec<u32>,
    unpacked_rwus: Vec<RWU>,
}

// A constant representing `RWU { reader: invalid_node(); writer: invalid_node(); used: false }`.
const INV_INV_FALSE: u32 = u32::MAX;

// A constant representing `RWU { reader: invalid_node(); writer: invalid_node(); used: true }`.
const INV_INV_TRUE: u32 = u32::MAX - 1;

impl RWUTable {
    fn new(num_rwus: usize) -> RWUTable {
        Self { packed_rwus: vec![INV_INV_FALSE; num_rwus], unpacked_rwus: vec![] }
    }

    fn get(&self, idx: usize) -> RWU {
        let packed_rwu = self.packed_rwus[idx];
        match packed_rwu {
            INV_INV_FALSE => RWU { reader: invalid_node(), writer: invalid_node(), used: false },
            INV_INV_TRUE => RWU { reader: invalid_node(), writer: invalid_node(), used: true },
            _ => self.unpacked_rwus[packed_rwu as usize],
        }
    }

    fn get_reader(&self, idx: usize) -> LiveNode {
        let packed_rwu = self.packed_rwus[idx];
        match packed_rwu {
            INV_INV_FALSE | INV_INV_TRUE => invalid_node(),
            _ => self.unpacked_rwus[packed_rwu as usize].reader,
        }
    }

    fn get_writer(&self, idx: usize) -> LiveNode {
        let packed_rwu = self.packed_rwus[idx];
        match packed_rwu {
            INV_INV_FALSE | INV_INV_TRUE => invalid_node(),
            _ => self.unpacked_rwus[packed_rwu as usize].writer,
        }
    }

    fn get_used(&self, idx: usize) -> bool {
        let packed_rwu = self.packed_rwus[idx];
        match packed_rwu {
            INV_INV_FALSE => false,
            INV_INV_TRUE => true,
            _ => self.unpacked_rwus[packed_rwu as usize].used,
        }
    }

    #[inline]
    fn copy_packed(&mut self, dst_idx: usize, src_idx: usize) {
        self.packed_rwus[dst_idx] = self.packed_rwus[src_idx];
    }

    fn assign_unpacked(&mut self, idx: usize, rwu: RWU) {
        if rwu.reader == invalid_node() && rwu.writer == invalid_node() {
            // When we overwrite an indexing entry in `self.packed_rwus` with
            // `INV_INV_{TRUE,FALSE}` we don't remove the corresponding entry
            // from `self.unpacked_rwus`; it's not worth the effort, and we
            // can't have entries shifting around anyway.
            self.packed_rwus[idx] = if rwu.used { INV_INV_TRUE } else { INV_INV_FALSE }
        } else {
            // Add a new RWU to `unpacked_rwus` and make `packed_rwus[idx]`
            // point to it.
            self.packed_rwus[idx] = self.unpacked_rwus.len() as u32;
            self.unpacked_rwus.push(rwu);
        }
    }

    fn assign_inv_inv(&mut self, idx: usize) {
        self.packed_rwus[idx] = if self.get_used(idx) { INV_INV_TRUE } else { INV_INV_FALSE };
    }
}

#[derive(Copy, Clone)]
struct Specials {
    exit_ln: LiveNode,
    fallthrough_ln: LiveNode,
    clean_exit_var: Variable,
}

const ACC_READ: u32 = 1;
const ACC_WRITE: u32 = 2;
const ACC_USE: u32 = 4;

struct Liveness<'a, 'tcx> {
    ir: &'a mut IrMaps<'tcx>,
    tables: &'a ty::TypeckTables<'tcx>,
    param_env: ty::ParamEnv<'tcx>,
    s: Specials,
    successors: Vec<LiveNode>,
    rwu_table: RWUTable,

    // mappings from loop node ID to LiveNode
    // ("break" label should map to loop node ID,
    // it probably doesn't now)
    break_ln: HirIdMap<LiveNode>,
    cont_ln: HirIdMap<LiveNode>,
}

impl<'a, 'tcx> Liveness<'a, 'tcx> {
    fn new(ir: &'a mut IrMaps<'tcx>, def_id: DefId) -> Liveness<'a, 'tcx> {
        // Special nodes and variables:
        // - exit_ln represents the end of the fn, either by return or panic
        // - implicit_ret_var is a pseudo-variable that represents
        //   an implicit return
        let specials = Specials {
            exit_ln: ir.add_live_node(ExitNode),
            fallthrough_ln: ir.add_live_node(ExitNode),
            clean_exit_var: ir.add_variable(CleanExit),
        };

        let tables = ir.tcx.typeck_tables_of(def_id);
        let param_env = ir.tcx.param_env(def_id);

        let num_live_nodes = ir.num_live_nodes;
        let num_vars = ir.num_vars;

        Liveness {
            ir,
            tables,
            param_env,
            s: specials,
            successors: vec![invalid_node(); num_live_nodes],
            rwu_table: RWUTable::new(num_live_nodes * num_vars),
            break_ln: Default::default(),
            cont_ln: Default::default(),
        }
    }

    fn live_node(&self, hir_id: HirId, span: Span) -> LiveNode {
        match self.ir.live_node_map.get(&hir_id) {
            Some(&ln) => ln,
            None => {
                // This must be a mismatch between the ir_map construction
                // above and the propagation code below; the two sets of
                // code have to agree about which AST nodes are worth
                // creating liveness nodes for.
                span_bug!(span, "no live node registered for node {:?}", hir_id);
            }
        }
    }

    fn variable(&self, hir_id: HirId, span: Span) -> Variable {
        self.ir.variable(hir_id, span)
    }

    fn define_bindings_in_pat(&mut self, pat: &hir::Pat<'_>, mut succ: LiveNode) -> LiveNode {
        // In an or-pattern, only consider the first pattern; any later patterns
        // must have the same bindings, and we also consider the first pattern
        // to be the "authoritative" set of ids.
        pat.each_binding_or_first(&mut |_, hir_id, pat_sp, ident| {
            let ln = self.live_node(hir_id, pat_sp);
            let var = self.variable(hir_id, ident.span);
            self.init_from_succ(ln, succ);
            self.define(ln, var);
            succ = ln;
        });
        succ
    }

    fn idx(&self, ln: LiveNode, var: Variable) -> usize {
        ln.get() * self.ir.num_vars + var.get()
    }

    fn live_on_entry(&self, ln: LiveNode, var: Variable) -> Option<LiveNodeKind> {
        assert!(ln.is_valid());
        let reader = self.rwu_table.get_reader(self.idx(ln, var));
        if reader.is_valid() { Some(self.ir.lnk(reader)) } else { None }
    }

    // Is this variable live on entry to any of its successor nodes?
    fn live_on_exit(&self, ln: LiveNode, var: Variable) -> Option<LiveNodeKind> {
        let successor = self.successors[ln.get()];
        self.live_on_entry(successor, var)
    }

    fn used_on_entry(&self, ln: LiveNode, var: Variable) -> bool {
        assert!(ln.is_valid());
        self.rwu_table.get_used(self.idx(ln, var))
    }

    fn assigned_on_entry(&self, ln: LiveNode, var: Variable) -> Option<LiveNodeKind> {
        assert!(ln.is_valid());
        let writer = self.rwu_table.get_writer(self.idx(ln, var));
        if writer.is_valid() { Some(self.ir.lnk(writer)) } else { None }
    }

    fn assigned_on_exit(&self, ln: LiveNode, var: Variable) -> Option<LiveNodeKind> {
        let successor = self.successors[ln.get()];
        self.assigned_on_entry(successor, var)
    }

    fn indices2<F>(&mut self, ln: LiveNode, succ_ln: LiveNode, mut op: F)
    where
        F: FnMut(&mut Liveness<'a, 'tcx>, usize, usize),
    {
        let node_base_idx = self.idx(ln, Variable(0));
        let succ_base_idx = self.idx(succ_ln, Variable(0));
        for var_idx in 0..self.ir.num_vars {
            op(self, node_base_idx + var_idx, succ_base_idx + var_idx);
        }
    }

    fn write_vars<F>(&self, wr: &mut dyn Write, ln: LiveNode, mut test: F) -> io::Result<()>
    where
        F: FnMut(usize) -> LiveNode,
    {
        let node_base_idx = self.idx(ln, Variable(0));
        for var_idx in 0..self.ir.num_vars {
            let idx = node_base_idx + var_idx;
            if test(idx).is_valid() {
                write!(wr, " {:?}", Variable(var_idx as u32))?;
            }
        }
        Ok(())
    }

    #[allow(unused_must_use)]
    fn ln_str(&self, ln: LiveNode) -> String {
        let mut wr = Vec::new();
        {
            let wr = &mut wr as &mut dyn Write;
            write!(wr, "[ln({:?}) of kind {:?} reads", ln.get(), self.ir.lnk(ln));
            self.write_vars(wr, ln, |idx| self.rwu_table.get_reader(idx));
            write!(wr, "  writes");
            self.write_vars(wr, ln, |idx| self.rwu_table.get_writer(idx));
            write!(wr, "  precedes {:?}]", self.successors[ln.get()]);
        }
        String::from_utf8(wr).unwrap()
    }

    fn init_empty(&mut self, ln: LiveNode, succ_ln: LiveNode) {
        self.successors[ln.get()] = succ_ln;

        // It is not necessary to initialize the RWUs here because they are all
        // set to INV_INV_FALSE when they are created, and the sets only grow
        // during iterations.
    }

    fn init_from_succ(&mut self, ln: LiveNode, succ_ln: LiveNode) {
        // more efficient version of init_empty() / merge_from_succ()
        self.successors[ln.get()] = succ_ln;

        self.indices2(ln, succ_ln, |this, idx, succ_idx| {
            this.rwu_table.copy_packed(idx, succ_idx);
        });
        debug!("init_from_succ(ln={}, succ={})", self.ln_str(ln), self.ln_str(succ_ln));
    }

    fn merge_from_succ(&mut self, ln: LiveNode, succ_ln: LiveNode, first_merge: bool) -> bool {
        if ln == succ_ln {
            return false;
        }

        let mut any_changed = false;
        self.indices2(ln, succ_ln, |this, idx, succ_idx| {
            // This is a special case, pulled out from the code below, where we
            // don't have to do anything. It occurs about 60-70% of the time.
            if this.rwu_table.packed_rwus[succ_idx] == INV_INV_FALSE {
                return;
            }

            let mut changed = false;
            let mut rwu = this.rwu_table.get(idx);
            let succ_rwu = this.rwu_table.get(succ_idx);
            if succ_rwu.reader.is_valid() && !rwu.reader.is_valid() {
                rwu.reader = succ_rwu.reader;
                changed = true
            }

            if succ_rwu.writer.is_valid() && !rwu.writer.is_valid() {
                rwu.writer = succ_rwu.writer;
                changed = true
            }

            if succ_rwu.used && !rwu.used {
                rwu.used = true;
                changed = true;
            }

            if changed {
                this.rwu_table.assign_unpacked(idx, rwu);
                any_changed = true;
            }
        });

        debug!(
            "merge_from_succ(ln={:?}, succ={}, first_merge={}, changed={})",
            ln,
            self.ln_str(succ_ln),
            first_merge,
            any_changed
        );
        any_changed
    }

    // Indicates that a local variable was *defined*; we know that no
    // uses of the variable can precede the definition (resolve checks
    // this) so we just clear out all the data.
    fn define(&mut self, writer: LiveNode, var: Variable) {
        let idx = self.idx(writer, var);
        self.rwu_table.assign_inv_inv(idx);

        debug!("{:?} defines {:?} (idx={}): {}", writer, var, idx, self.ln_str(writer));
    }

    // Either read, write, or both depending on the acc bitset
    fn acc(&mut self, ln: LiveNode, var: Variable, acc: u32) {
        debug!("{:?} accesses[{:x}] {:?}: {}", ln, acc, var, self.ln_str(ln));

        let idx = self.idx(ln, var);
        let mut rwu = self.rwu_table.get(idx);

        if (acc & ACC_WRITE) != 0 {
            rwu.reader = invalid_node();
            rwu.writer = ln;
        }

        // Important: if we both read/write, must do read second
        // or else the write will override.
        if (acc & ACC_READ) != 0 {
            rwu.reader = ln;
        }

        if (acc & ACC_USE) != 0 {
            rwu.used = true;
        }

        self.rwu_table.assign_unpacked(idx, rwu);
    }

    fn compute(&mut self, body: &hir::Expr<'_>) -> LiveNode {
        debug!("compute: using id for body, {:?}", body);

        // the fallthrough exit is only for those cases where we do not
        // explicitly return:
        let s = self.s;
        self.init_from_succ(s.fallthrough_ln, s.exit_ln);
        self.acc(s.fallthrough_ln, s.clean_exit_var, ACC_READ);

        let entry_ln = self.propagate_through_expr(body, s.fallthrough_ln);

        // hack to skip the loop unless debug! is enabled:
        debug!(
            "^^ liveness computation results for body {} (entry={:?})",
            {
                for ln_idx in 0..self.ir.num_live_nodes {
                    debug!("{:?}", self.ln_str(LiveNode(ln_idx as u32)));
                }
                body.hir_id
            },
            entry_ln
        );

        entry_ln
    }

    fn propagate_through_block(&mut self, blk: &hir::Block<'_>, succ: LiveNode) -> LiveNode {
        if blk.targeted_by_break {
            self.break_ln.insert(blk.hir_id, succ);
        }
        let succ = self.propagate_through_opt_expr(blk.expr.as_ref().map(|e| &**e), succ);
        blk.stmts.iter().rev().fold(succ, |succ, stmt| self.propagate_through_stmt(stmt, succ))
    }

    fn propagate_through_stmt(&mut self, stmt: &hir::Stmt<'_>, succ: LiveNode) -> LiveNode {
        match stmt.kind {
            hir::StmtKind::Local(ref local) => {
                // Note: we mark the variable as defined regardless of whether
                // there is an initializer.  Initially I had thought to only mark
                // the live variable as defined if it was initialized, and then we
                // could check for uninit variables just by scanning what is live
                // at the start of the function. But that doesn't work so well for
                // immutable variables defined in a loop:
                //     loop { let x; x = 5; }
                // because the "assignment" loops back around and generates an error.
                //
                // So now we just check that variables defined w/o an
                // initializer are not live at the point of their
                // initialization, which is mildly more complex than checking
                // once at the func header but otherwise equivalent.

                let succ = self.propagate_through_opt_expr(local.init.as_ref().map(|e| &**e), succ);
                self.define_bindings_in_pat(&local.pat, succ)
            }
            hir::StmtKind::Item(..) => succ,
            hir::StmtKind::Expr(ref expr) | hir::StmtKind::Semi(ref expr) => {
                self.propagate_through_expr(&expr, succ)
            }
        }
    }

    fn propagate_through_exprs(&mut self, exprs: &[Expr<'_>], succ: LiveNode) -> LiveNode {
        exprs.iter().rev().fold(succ, |succ, expr| self.propagate_through_expr(&expr, succ))
    }

    fn propagate_through_opt_expr(
        &mut self,
        opt_expr: Option<&Expr<'_>>,
        succ: LiveNode,
    ) -> LiveNode {
        opt_expr.map_or(succ, |expr| self.propagate_through_expr(expr, succ))
    }

    fn propagate_through_expr(&mut self, expr: &Expr<'_>, succ: LiveNode) -> LiveNode {
        debug!("propagate_through_expr: {:?}", expr);

        match expr.kind {
            // Interesting cases with control flow or which gen/kill
            hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) => {
                self.access_path(expr.hir_id, path, succ, ACC_READ | ACC_USE)
            }

            hir::ExprKind::Field(ref e, _) => self.propagate_through_expr(&e, succ),

            hir::ExprKind::Closure(..) => {
                debug!("{:?} is an ExprKind::Closure", expr);

                // the construction of a closure itself is not important,
                // but we have to consider the closed over variables.
                let caps = self
                    .ir
                    .capture_info_map
                    .get(&expr.hir_id)
                    .cloned()
                    .unwrap_or_else(|| span_bug!(expr.span, "no registered caps"));

                caps.iter().rev().fold(succ, |succ, cap| {
                    self.init_from_succ(cap.ln, succ);
                    let var = self.variable(cap.var_hid, expr.span);
                    self.acc(cap.ln, var, ACC_READ | ACC_USE);
                    cap.ln
                })
            }

            // Note that labels have been resolved, so we don't need to look
            // at the label ident
            hir::ExprKind::Loop(ref blk, _, _) => self.propagate_through_loop(expr, &blk, succ),

            hir::ExprKind::Match(ref e, arms, _) => {
                //
                //      (e)
                //       |
                //       v
                //     (expr)
                //     / | \
                //    |  |  |
                //    v  v  v
                //   (..arms..)
                //    |  |  |
                //    v  v  v
                //   (  succ  )
                //
                //
                let ln = self.live_node(expr.hir_id, expr.span);
                self.init_empty(ln, succ);
                let mut first_merge = true;
                for arm in arms {
                    let body_succ = self.propagate_through_expr(&arm.body, succ);

                    let guard_succ = self.propagate_through_opt_expr(
                        arm.guard.as_ref().map(|hir::Guard::If(e)| *e),
                        body_succ,
                    );
                    let arm_succ = self.define_bindings_in_pat(&arm.pat, guard_succ);
                    self.merge_from_succ(ln, arm_succ, first_merge);
                    first_merge = false;
                }
                self.propagate_through_expr(&e, ln)
            }

            hir::ExprKind::Ret(ref o_e) => {
                // ignore succ and subst exit_ln:
                let exit_ln = self.s.exit_ln;
                self.propagate_through_opt_expr(o_e.as_ref().map(|e| &**e), exit_ln)
            }

            hir::ExprKind::Break(label, ref opt_expr) => {
                // Find which label this break jumps to
                let target = match label.target_id {
                    Ok(hir_id) => self.break_ln.get(&hir_id),
                    Err(err) => span_bug!(expr.span, "loop scope error: {}", err),
                }
                .cloned();

                // Now that we know the label we're going to,
                // look it up in the break loop nodes table

                match target {
                    Some(b) => self.propagate_through_opt_expr(opt_expr.as_ref().map(|e| &**e), b),
                    None => {
                        // FIXME: This should have been checked earlier. Once this is fixed,
                        // replace with `delay_span_bug`. (#62480)
                        self.ir
                            .tcx
                            .sess
                            .struct_span_err(expr.span, "`break` to unknown label")
                            .emit();
                        rustc_errors::FatalError.raise()
                    }
                }
            }

            hir::ExprKind::Continue(label) => {
                // Find which label this expr continues to
                let sc = label
                    .target_id
                    .unwrap_or_else(|err| span_bug!(expr.span, "loop scope error: {}", err));

                // Now that we know the label we're going to,
                // look it up in the continue loop nodes table
                self.cont_ln
                    .get(&sc)
                    .cloned()
                    .unwrap_or_else(|| span_bug!(expr.span, "continue to unknown label"))
            }

            hir::ExprKind::Assign(ref l, ref r, _) => {
                // see comment on places in
                // propagate_through_place_components()
                let succ = self.write_place(&l, succ, ACC_WRITE);
                let succ = self.propagate_through_place_components(&l, succ);
                self.propagate_through_expr(&r, succ)
            }

            hir::ExprKind::AssignOp(_, ref l, ref r) => {
                // an overloaded assign op is like a method call
                if self.tables.is_method_call(expr) {
                    let succ = self.propagate_through_expr(&l, succ);
                    self.propagate_through_expr(&r, succ)
                } else {
                    // see comment on places in
                    // propagate_through_place_components()
                    let succ = self.write_place(&l, succ, ACC_WRITE | ACC_READ);
                    let succ = self.propagate_through_expr(&r, succ);
                    self.propagate_through_place_components(&l, succ)
                }
            }

            // Uninteresting cases: just propagate in rev exec order
            hir::ExprKind::Array(ref exprs) => self.propagate_through_exprs(exprs, succ),

            hir::ExprKind::Struct(_, ref fields, ref with_expr) => {
                let succ = self.propagate_through_opt_expr(with_expr.as_ref().map(|e| &**e), succ);
                fields
                    .iter()
                    .rev()
                    .fold(succ, |succ, field| self.propagate_through_expr(&field.expr, succ))
            }

            hir::ExprKind::Call(ref f, ref args) => {
                let m = self.ir.tcx.parent_module(expr.hir_id).to_def_id();
                let succ = if self.ir.tcx.is_ty_uninhabited_from(
                    m,
                    self.tables.expr_ty(expr),
                    self.param_env,
                ) {
                    self.s.exit_ln
                } else {
                    succ
                };
                let succ = self.propagate_through_exprs(args, succ);
                self.propagate_through_expr(&f, succ)
            }

            hir::ExprKind::MethodCall(.., ref args) => {
                let m = self.ir.tcx.parent_module(expr.hir_id).to_def_id();
                let succ = if self.ir.tcx.is_ty_uninhabited_from(
                    m,
                    self.tables.expr_ty(expr),
                    self.param_env,
                ) {
                    self.s.exit_ln
                } else {
                    succ
                };

                self.propagate_through_exprs(args, succ)
            }

            hir::ExprKind::Tup(ref exprs) => self.propagate_through_exprs(exprs, succ),

            hir::ExprKind::Binary(op, ref l, ref r) if op.node.is_lazy() => {
                let r_succ = self.propagate_through_expr(&r, succ);

                let ln = self.live_node(expr.hir_id, expr.span);
                self.init_from_succ(ln, succ);
                self.merge_from_succ(ln, r_succ, false);

                self.propagate_through_expr(&l, ln)
            }

            hir::ExprKind::Index(ref l, ref r) | hir::ExprKind::Binary(_, ref l, ref r) => {
                let r_succ = self.propagate_through_expr(&r, succ);
                self.propagate_through_expr(&l, r_succ)
            }

            hir::ExprKind::Box(ref e)
            | hir::ExprKind::AddrOf(_, _, ref e)
            | hir::ExprKind::Cast(ref e, _)
            | hir::ExprKind::Type(ref e, _)
            | hir::ExprKind::DropTemps(ref e)
            | hir::ExprKind::Unary(_, ref e)
            | hir::ExprKind::Yield(ref e, _)
            | hir::ExprKind::Repeat(ref e, _) => self.propagate_through_expr(&e, succ),

            hir::ExprKind::LlvmInlineAsm(ref asm) => {
                let ia = &asm.inner;
                let outputs = asm.outputs_exprs;
                let inputs = asm.inputs_exprs;
                let succ = ia.outputs.iter().zip(outputs).rev().fold(succ, |succ, (o, output)| {
                    // see comment on places
                    // in propagate_through_place_components()
                    if o.is_indirect {
                        self.propagate_through_expr(output, succ)
                    } else {
                        let acc = if o.is_rw { ACC_WRITE | ACC_READ } else { ACC_WRITE };
                        let succ = self.write_place(output, succ, acc);
                        self.propagate_through_place_components(output, succ)
                    }
                });

                // Inputs are executed first. Propagate last because of rev order
                self.propagate_through_exprs(inputs, succ)
            }

            hir::ExprKind::Lit(..)
            | hir::ExprKind::Err
            | hir::ExprKind::Path(hir::QPath::TypeRelative(..)) => succ,

            // Note that labels have been resolved, so we don't need to look
            // at the label ident
            hir::ExprKind::Block(ref blk, _) => self.propagate_through_block(&blk, succ),
        }
    }

    fn propagate_through_place_components(&mut self, expr: &Expr<'_>, succ: LiveNode) -> LiveNode {
        // # Places
        //
        // In general, the full flow graph structure for an
        // assignment/move/etc can be handled in one of two ways,
        // depending on whether what is being assigned is a "tracked
        // value" or not. A tracked value is basically a local
        // variable or argument.
        //
        // The two kinds of graphs are:
        //
        //    Tracked place          Untracked place
        // ----------------------++-----------------------
        //                       ||
        //         |             ||           |
        //         v             ||           v
        //     (rvalue)          ||       (rvalue)
        //         |             ||           |
        //         v             ||           v
        // (write of place)     ||   (place components)
        //         |             ||           |
        //         v             ||           v
        //      (succ)           ||        (succ)
        //                       ||
        // ----------------------++-----------------------
        //
        // I will cover the two cases in turn:
        //
        // # Tracked places
        //
        // A tracked place is a local variable/argument `x`.  In
        // these cases, the link_node where the write occurs is linked
        // to node id of `x`.  The `write_place()` routine generates
        // the contents of this node.  There are no subcomponents to
        // consider.
        //
        // # Non-tracked places
        //
        // These are places like `x[5]` or `x.f`.  In that case, we
        // basically ignore the value which is written to but generate
        // reads for the components---`x` in these two examples.  The
        // components reads are generated by
        // `propagate_through_place_components()` (this fn).
        //
        // # Illegal places
        //
        // It is still possible to observe assignments to non-places;
        // these errors are detected in the later pass borrowck.  We
        // just ignore such cases and treat them as reads.

        match expr.kind {
            hir::ExprKind::Path(_) => succ,
            hir::ExprKind::Field(ref e, _) => self.propagate_through_expr(&e, succ),
            _ => self.propagate_through_expr(expr, succ),
        }
    }

    // see comment on propagate_through_place()
    fn write_place(&mut self, expr: &Expr<'_>, succ: LiveNode, acc: u32) -> LiveNode {
        match expr.kind {
            hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) => {
                self.access_path(expr.hir_id, path, succ, acc)
            }

            // We do not track other places, so just propagate through
            // to their subcomponents.  Also, it may happen that
            // non-places occur here, because those are detected in the
            // later pass borrowck.
            _ => succ,
        }
    }

    fn access_var(
        &mut self,
        hir_id: HirId,
        var_hid: HirId,
        succ: LiveNode,
        acc: u32,
        span: Span,
    ) -> LiveNode {
        let ln = self.live_node(hir_id, span);
        if acc != 0 {
            self.init_from_succ(ln, succ);
            let var = self.variable(var_hid, span);
            self.acc(ln, var, acc);
        }
        ln
    }

    fn access_path(
        &mut self,
        hir_id: HirId,
        path: &hir::Path<'_>,
        succ: LiveNode,
        acc: u32,
    ) -> LiveNode {
        match path.res {
            Res::Local(hid) => {
                let upvars = self.ir.tcx.upvars(self.ir.body_owner);
                if !upvars.map_or(false, |upvars| upvars.contains_key(&hid)) {
                    self.access_var(hir_id, hid, succ, acc, path.span)
                } else {
                    succ
                }
            }
            _ => succ,
        }
    }

    fn propagate_through_loop(
        &mut self,
        expr: &Expr<'_>,
        body: &hir::Block<'_>,
        succ: LiveNode,
    ) -> LiveNode {
        /*
        We model control flow like this:

              (expr) <-+
                |      |
                v      |
              (body) --+

        Note that a `continue` expression targeting the `loop` will have a successor of `expr`.
        Meanwhile, a `break` expression will have a successor of `succ`.
        */

        // first iteration:
        let mut first_merge = true;
        let ln = self.live_node(expr.hir_id, expr.span);
        self.init_empty(ln, succ);
        debug!("propagate_through_loop: using id for loop body {} {:?}", expr.hir_id, body);

        self.break_ln.insert(expr.hir_id, succ);

        self.cont_ln.insert(expr.hir_id, ln);

        let body_ln = self.propagate_through_block(body, ln);

        // repeat until fixed point is reached:
        while self.merge_from_succ(ln, body_ln, first_merge) {
            first_merge = false;
            assert_eq!(body_ln, self.propagate_through_block(body, ln));
        }

        ln
    }
}

// _______________________________________________________________________
// Checking for error conditions

impl<'a, 'tcx> Visitor<'tcx> for Liveness<'a, 'tcx> {
    type Map = intravisit::ErasedMap<'tcx>;

    fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
        NestedVisitorMap::None
    }

    fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
        self.check_unused_vars_in_pat(&local.pat, None, |spans, hir_id, ln, var| {
            if local.init.is_some() {
                self.warn_about_dead_assign(spans, hir_id, ln, var);
            }
        });

        intravisit::walk_local(self, local);
    }

    fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
        check_expr(self, ex);
    }

    fn visit_arm(&mut self, arm: &'tcx hir::Arm<'tcx>) {
        self.check_unused_vars_in_pat(&arm.pat, None, |_, _, _, _| {});
        intravisit::walk_arm(self, arm);
    }
}

fn check_expr<'tcx>(this: &mut Liveness<'_, 'tcx>, expr: &'tcx Expr<'tcx>) {
    match expr.kind {
        hir::ExprKind::Assign(ref l, ..) => {
            this.check_place(&l);
        }

        hir::ExprKind::AssignOp(_, ref l, _) => {
            if !this.tables.is_method_call(expr) {
                this.check_place(&l);
            }
        }

        hir::ExprKind::LlvmInlineAsm(ref asm) => {
            for input in asm.inputs_exprs {
                this.visit_expr(input);
            }

            // Output operands must be places
            for (o, output) in asm.inner.outputs.iter().zip(asm.outputs_exprs) {
                if !o.is_indirect {
                    this.check_place(output);
                }
                this.visit_expr(output);
            }
        }

        // no correctness conditions related to liveness
        hir::ExprKind::Call(..)
        | hir::ExprKind::MethodCall(..)
        | hir::ExprKind::Match(..)
        | hir::ExprKind::Loop(..)
        | hir::ExprKind::Index(..)
        | hir::ExprKind::Field(..)
        | hir::ExprKind::Array(..)
        | hir::ExprKind::Tup(..)
        | hir::ExprKind::Binary(..)
        | hir::ExprKind::Cast(..)
        | hir::ExprKind::DropTemps(..)
        | hir::ExprKind::Unary(..)
        | hir::ExprKind::Ret(..)
        | hir::ExprKind::Break(..)
        | hir::ExprKind::Continue(..)
        | hir::ExprKind::Lit(_)
        | hir::ExprKind::Block(..)
        | hir::ExprKind::AddrOf(..)
        | hir::ExprKind::Struct(..)
        | hir::ExprKind::Repeat(..)
        | hir::ExprKind::Closure(..)
        | hir::ExprKind::Path(_)
        | hir::ExprKind::Yield(..)
        | hir::ExprKind::Box(..)
        | hir::ExprKind::Type(..)
        | hir::ExprKind::Err => {}
    }

    intravisit::walk_expr(this, expr);
}

impl<'tcx> Liveness<'_, 'tcx> {
    fn check_place(&mut self, expr: &'tcx Expr<'tcx>) {
        match expr.kind {
            hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) => {
                if let Res::Local(var_hid) = path.res {
                    let upvars = self.ir.tcx.upvars(self.ir.body_owner);
                    if !upvars.map_or(false, |upvars| upvars.contains_key(&var_hid)) {
                        // Assignment to an immutable variable or argument: only legal
                        // if there is no later assignment. If this local is actually
                        // mutable, then check for a reassignment to flag the mutability
                        // as being used.
                        let ln = self.live_node(expr.hir_id, expr.span);
                        let var = self.variable(var_hid, expr.span);
                        self.warn_about_dead_assign(vec![expr.span], expr.hir_id, ln, var);
                    }
                }
            }
            _ => {
                // For other kinds of places, no checks are required,
                // and any embedded expressions are actually rvalues
                intravisit::walk_expr(self, expr);
            }
        }
    }

    fn should_warn(&self, var: Variable) -> Option<String> {
        let name = self.ir.variable_name(var);
        if name.is_empty() || name.as_bytes()[0] == b'_' { None } else { Some(name) }
    }

    fn warn_about_unused_args(&self, body: &hir::Body<'_>, entry_ln: LiveNode) {
        for p in body.params {
            self.check_unused_vars_in_pat(&p.pat, Some(entry_ln), |spans, hir_id, ln, var| {
                if self.live_on_entry(ln, var).is_none() {
                    self.report_dead_assign(hir_id, spans, var, true);
                }
            });
        }
    }

    fn check_unused_vars_in_pat(
        &self,
        pat: &hir::Pat<'_>,
        entry_ln: Option<LiveNode>,
        on_used_on_entry: impl Fn(Vec<Span>, HirId, LiveNode, Variable),
    ) {
        // In an or-pattern, only consider the variable; any later patterns must have the same
        // bindings, and we also consider the first pattern to be the "authoritative" set of ids.
        // However, we should take the spans of variables with the same name from the later
        // patterns so the suggestions to prefix with underscores will apply to those too.
        let mut vars: FxIndexMap<String, (LiveNode, Variable, HirId, Vec<Span>)> = <_>::default();

        pat.each_binding(|_, hir_id, pat_sp, ident| {
            let ln = entry_ln.unwrap_or_else(|| self.live_node(hir_id, pat_sp));
            let var = self.variable(hir_id, ident.span);
            vars.entry(self.ir.variable_name(var))
                .and_modify(|(.., spans)| spans.push(ident.span))
                .or_insert_with(|| (ln, var, hir_id, vec![ident.span]));
        });

        for (_, (ln, var, id, spans)) in vars {
            if self.used_on_entry(ln, var) {
                on_used_on_entry(spans, id, ln, var);
            } else {
                self.report_unused(spans, id, ln, var);
            }
        }
    }

    fn report_unused(&self, spans: Vec<Span>, hir_id: HirId, ln: LiveNode, var: Variable) {
        if let Some(name) = self.should_warn(var).filter(|name| name != "self") {
            // annoying: for parameters in funcs like `fn(x: i32)
            // {ret}`, there is only one node, so asking about
            // assigned_on_exit() is not meaningful.
            let is_assigned =
                if ln == self.s.exit_ln { false } else { self.assigned_on_exit(ln, var).is_some() };

            if is_assigned {
                self.ir.tcx.struct_span_lint_hir(
                    lint::builtin::UNUSED_VARIABLES,
                    hir_id,
                    spans,
                    |lint| {
                        lint.build(&format!("variable `{}` is assigned to, but never used", name))
                            .note(&format!("consider using `_{}` instead", name))
                            .emit();
                    },
                )
            } else {
                self.ir.tcx.struct_span_lint_hir(
                    lint::builtin::UNUSED_VARIABLES,
                    hir_id,
                    spans.clone(),
                    |lint| {
                        let mut err = lint.build(&format!("unused variable: `{}`", name));
                        if self.ir.variable_is_shorthand(var) {
                            if let Node::Binding(pat) = self.ir.tcx.hir().get(hir_id) {
                                // Handle `ref` and `ref mut`.
                                let spans = spans
                                    .iter()
                                    .map(|_span| (pat.span, format!("{}: _", name)))
                                    .collect();

                                err.multipart_suggestion(
                                    "try ignoring the field",
                                    spans,
                                    Applicability::MachineApplicable,
                                );
                            }
                        } else {
                            err.multipart_suggestion(
                                "if this is intentional, prefix it with an underscore",
                                spans.iter().map(|span| (*span, format!("_{}", name))).collect(),
                                Applicability::MachineApplicable,
                            );
                        }
                        err.emit()
                    },
                );
            }
        }
    }

    fn warn_about_dead_assign(&self, spans: Vec<Span>, hir_id: HirId, ln: LiveNode, var: Variable) {
        if self.live_on_exit(ln, var).is_none() {
            self.report_dead_assign(hir_id, spans, var, false);
        }
    }

    fn report_dead_assign(&self, hir_id: HirId, spans: Vec<Span>, var: Variable, is_param: bool) {
        if let Some(name) = self.should_warn(var) {
            if is_param {
                self.ir.tcx.struct_span_lint_hir(
                    lint::builtin::UNUSED_ASSIGNMENTS,
                    hir_id,
                    spans,
                    |lint| {
                        lint.build(&format!("value passed to `{}` is never read", name))
                            .help("maybe it is overwritten before being read?")
                            .emit();
                    },
                )
            } else {
                self.ir.tcx.struct_span_lint_hir(
                    lint::builtin::UNUSED_ASSIGNMENTS,
                    hir_id,
                    spans,
                    |lint| {
                        lint.build(&format!("value assigned to `{}` is never read", name))
                            .help("maybe it is overwritten before being read?")
                            .emit();
                    },
                )
            }
        }
    }
}
