Auto merge of #50929 - zackmdavis:hiridification_initiative, r=michaelwoerister
operate on `HirId` instead of `NodeId` in `hir::Pat::each_binding`, and consequences of that See #50928 for motivation. Questions— * Is #50928 actually a good idea as a plan of record, or is there some reason to keep `NodeId`s? * Are the uses of `find_node_for_hir_id` in this initial submission OK (see the FIXME comments)? * Can we bikeshed a better method names `struct_span_lint_hir` _&c._? (Coined in analogy to the `struct_span_lint_node` and `NodeId`, but it feels kind of semantically clunky.) r? @michaelwoerister
This commit is contained in:
commit
5bf68db6ec
13 changed files with 145 additions and 135 deletions
|
@ -487,14 +487,6 @@ impl Definitions {
|
|||
self.node_to_hir_id[node_id]
|
||||
}
|
||||
|
||||
pub fn find_node_for_hir_id(&self, hir_id: hir::HirId) -> ast::NodeId {
|
||||
self.node_to_hir_id
|
||||
.iter()
|
||||
.position(|x| *x == hir_id)
|
||||
.map(|idx| ast::NodeId::new(idx))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn def_index_to_hir_id(&self, def_index: DefIndex) -> hir::HirId {
|
||||
let space_index = def_index.address_space().index();
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
use hir::def::Def;
|
||||
use hir::def_id::DefId;
|
||||
use hir::{self, PatKind};
|
||||
use hir::{self, HirId, PatKind};
|
||||
use syntax::ast;
|
||||
use syntax::codemap::Spanned;
|
||||
use syntax_pos::Span;
|
||||
|
@ -91,11 +91,11 @@ impl hir::Pat {
|
|||
/// Call `f` on every "binding" in a pattern, e.g., on `a` in
|
||||
/// `match foo() { Some(a) => (), None => () }`
|
||||
pub fn each_binding<F>(&self, mut f: F)
|
||||
where F: FnMut(hir::BindingAnnotation, ast::NodeId, Span, &Spanned<ast::Name>),
|
||||
where F: FnMut(hir::BindingAnnotation, HirId, Span, &Spanned<ast::Name>),
|
||||
{
|
||||
self.walk(|p| {
|
||||
if let PatKind::Binding(binding_mode, _, ref pth, _) = p.node {
|
||||
f(binding_mode, p.id, p.span, pth);
|
||||
f(binding_mode, p.hir_id, p.span, pth);
|
||||
}
|
||||
true
|
||||
});
|
||||
|
|
|
@ -608,9 +608,9 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
|||
fn walk_local(&mut self, local: &hir::Local) {
|
||||
match local.init {
|
||||
None => {
|
||||
let delegate = &mut self.delegate;
|
||||
local.pat.each_binding(|_, id, span, _| {
|
||||
delegate.decl_without_init(id, span);
|
||||
local.pat.each_binding(|_, hir_id, span, _| {
|
||||
let node_id = self.mc.tcx.hir.hir_to_node_id(hir_id);
|
||||
self.delegate.decl_without_init(node_id, span);
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ use hir::def::*;
|
|||
use ty::{self, TyCtxt};
|
||||
use lint;
|
||||
use errors::Applicability;
|
||||
use util::nodemap::{NodeMap, NodeSet};
|
||||
use util::nodemap::{NodeMap, HirIdMap, HirIdSet};
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::{fmt, u32};
|
||||
|
@ -122,7 +122,7 @@ use syntax::ptr::P;
|
|||
use syntax::symbol::keywords;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use hir::Expr;
|
||||
use hir::{Expr, HirId};
|
||||
use hir;
|
||||
use hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap};
|
||||
|
||||
|
@ -236,19 +236,19 @@ fn invalid_node() -> LiveNode { LiveNode(u32::MAX) }
|
|||
|
||||
struct CaptureInfo {
|
||||
ln: LiveNode,
|
||||
var_nid: NodeId
|
||||
var_hid: HirId
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
struct LocalInfo {
|
||||
id: NodeId,
|
||||
id: HirId,
|
||||
name: ast::Name,
|
||||
is_shorthand: bool,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
enum VarKind {
|
||||
Arg(NodeId, ast::Name),
|
||||
Arg(HirId, ast::Name),
|
||||
Local(LocalInfo),
|
||||
CleanExit
|
||||
}
|
||||
|
@ -258,8 +258,8 @@ struct IrMaps<'a, 'tcx: 'a> {
|
|||
|
||||
num_live_nodes: usize,
|
||||
num_vars: usize,
|
||||
live_node_map: NodeMap<LiveNode>,
|
||||
variable_map: NodeMap<Variable>,
|
||||
live_node_map: HirIdMap<LiveNode>,
|
||||
variable_map: HirIdMap<Variable>,
|
||||
capture_info_map: NodeMap<Rc<Vec<CaptureInfo>>>,
|
||||
var_kinds: Vec<VarKind>,
|
||||
lnks: Vec<LiveNodeKind>,
|
||||
|
@ -271,8 +271,8 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> {
|
|||
tcx,
|
||||
num_live_nodes: 0,
|
||||
num_vars: 0,
|
||||
live_node_map: NodeMap(),
|
||||
variable_map: NodeMap(),
|
||||
live_node_map: HirIdMap(),
|
||||
variable_map: HirIdMap(),
|
||||
capture_info_map: NodeMap(),
|
||||
var_kinds: Vec::new(),
|
||||
lnks: Vec::new(),
|
||||
|
@ -290,11 +290,11 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> {
|
|||
ln
|
||||
}
|
||||
|
||||
fn add_live_node_for_node(&mut self, node_id: NodeId, lnk: LiveNodeKind) {
|
||||
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(node_id, ln);
|
||||
self.live_node_map.insert(hir_id, ln);
|
||||
|
||||
debug!("{:?} is node {}", ln, node_id);
|
||||
debug!("{:?} is node {:?}", ln, hir_id);
|
||||
}
|
||||
|
||||
fn add_variable(&mut self, vk: VarKind) -> Variable {
|
||||
|
@ -314,11 +314,11 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> {
|
|||
v
|
||||
}
|
||||
|
||||
fn variable(&self, node_id: NodeId, span: Span) -> Variable {
|
||||
match self.variable_map.get(&node_id) {
|
||||
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 {}", node_id);
|
||||
span_bug!(span, "no variable registered for id {:?}", hir_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -374,10 +374,10 @@ fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>,
|
|||
let body = ir.tcx.hir.body(body_id);
|
||||
|
||||
for arg in &body.arguments {
|
||||
arg.pat.each_binding(|_bm, arg_id, _x, path1| {
|
||||
debug!("adding argument {}", arg_id);
|
||||
arg.pat.each_binding(|_bm, hir_id, _x, path1| {
|
||||
debug!("adding argument {:?}", hir_id);
|
||||
let name = path1.node;
|
||||
fn_maps.add_variable(Arg(arg_id, name));
|
||||
fn_maps.add_variable(Arg(hir_id, name));
|
||||
})
|
||||
};
|
||||
|
||||
|
@ -397,11 +397,7 @@ fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>,
|
|||
fn add_from_pat<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, pat: &P<hir::Pat>) {
|
||||
// For struct patterns, take note of which fields used shorthand
|
||||
// (`x` rather than `x: x`).
|
||||
//
|
||||
// FIXME: according to the rust-lang-nursery/rustc-guide book, `NodeId`s are to be
|
||||
// phased out in favor of `HirId`s; however, we need to match the signature of
|
||||
// `each_binding`, which uses `NodeIds`.
|
||||
let mut shorthand_field_ids = NodeSet();
|
||||
let mut shorthand_field_ids = HirIdSet();
|
||||
let mut pats = VecDeque::new();
|
||||
pats.push_back(pat);
|
||||
while let Some(pat) = pats.pop_front() {
|
||||
|
@ -413,7 +409,7 @@ fn add_from_pat<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, pat: &P<hir::Pat>) {
|
|||
Struct(_, ref fields, _) => {
|
||||
for field in fields {
|
||||
if field.node.is_shorthand {
|
||||
shorthand_field_ids.insert(field.node.pat.id);
|
||||
shorthand_field_ids.insert(field.node.pat.hir_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -434,13 +430,13 @@ fn add_from_pat<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, pat: &P<hir::Pat>) {
|
|||
}
|
||||
}
|
||||
|
||||
pat.each_binding(|_bm, p_id, _sp, path1| {
|
||||
pat.each_binding(|_bm, hir_id, _sp, path1| {
|
||||
let name = path1.node;
|
||||
ir.add_live_node_for_node(p_id, VarDefNode(path1.span));
|
||||
ir.add_live_node_for_node(hir_id, VarDefNode(path1.span));
|
||||
ir.add_variable(Local(LocalInfo {
|
||||
id: p_id,
|
||||
id: hir_id,
|
||||
name,
|
||||
is_shorthand: shorthand_field_ids.contains(&p_id)
|
||||
is_shorthand: shorthand_field_ids.contains(&hir_id)
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
@ -463,14 +459,14 @@ fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) {
|
|||
hir::ExprPath(hir::QPath::Resolved(_, ref path)) => {
|
||||
debug!("expr {}: path that leads to {:?}", expr.id, path.def);
|
||||
if let Def::Local(..) = path.def {
|
||||
ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
|
||||
ir.add_live_node_for_node(expr.hir_id, ExprNode(expr.span));
|
||||
}
|
||||
intravisit::walk_expr(ir, expr);
|
||||
}
|
||||
hir::ExprClosure(..) => {
|
||||
// Interesting control flow (for loops can contain labeled
|
||||
// breaks or continues)
|
||||
ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
|
||||
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
|
||||
|
@ -481,8 +477,8 @@ fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) {
|
|||
for fv in freevars {
|
||||
if let Def::Local(rv) = fv.def {
|
||||
let fv_ln = ir.add_live_node(FreeVarNode(fv.span));
|
||||
call_caps.push(CaptureInfo {ln: fv_ln,
|
||||
var_nid: rv});
|
||||
let var_hid = ir.tcx.hir.node_to_hir_id(rv);
|
||||
call_caps.push(CaptureInfo { ln: fv_ln, var_hid });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -493,11 +489,11 @@ fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) {
|
|||
|
||||
// live nodes required for interesting control flow:
|
||||
hir::ExprIf(..) | hir::ExprMatch(..) | hir::ExprWhile(..) | hir::ExprLoop(..) => {
|
||||
ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
|
||||
ir.add_live_node_for_node(expr.hir_id, ExprNode(expr.span));
|
||||
intravisit::walk_expr(ir, expr);
|
||||
}
|
||||
hir::ExprBinary(op, ..) if op.node.is_lazy() => {
|
||||
ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
|
||||
ir.add_live_node_for_node(expr.hir_id, ExprNode(expr.span));
|
||||
intravisit::walk_expr(ir, expr);
|
||||
}
|
||||
|
||||
|
@ -590,8 +586,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn live_node(&self, node_id: NodeId, span: Span) -> LiveNode {
|
||||
match self.ir.live_node_map.get(&node_id) {
|
||||
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
|
||||
|
@ -600,28 +596,28 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
// creating liveness nodes for.
|
||||
span_bug!(
|
||||
span,
|
||||
"no live node registered for node {}",
|
||||
node_id);
|
||||
"no live node registered for node {:?}",
|
||||
hir_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn variable(&self, node_id: NodeId, span: Span) -> Variable {
|
||||
self.ir.variable(node_id, span)
|
||||
fn variable(&self, hir_id: HirId, span: Span) -> Variable {
|
||||
self.ir.variable(hir_id, span)
|
||||
}
|
||||
|
||||
fn pat_bindings<F>(&mut self, pat: &hir::Pat, mut f: F) where
|
||||
F: FnMut(&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, NodeId),
|
||||
F: FnMut(&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, HirId),
|
||||
{
|
||||
pat.each_binding(|_bm, p_id, sp, n| {
|
||||
let ln = self.live_node(p_id, sp);
|
||||
let var = self.variable(p_id, n.span);
|
||||
f(self, ln, var, n.span, p_id);
|
||||
pat.each_binding(|_bm, hir_id, sp, n| {
|
||||
let ln = self.live_node(hir_id, sp);
|
||||
let var = self.variable(hir_id, n.span);
|
||||
f(self, ln, var, n.span, hir_id);
|
||||
})
|
||||
}
|
||||
|
||||
fn arm_pats_bindings<F>(&mut self, pat: Option<&hir::Pat>, f: F) where
|
||||
F: FnMut(&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, NodeId),
|
||||
F: FnMut(&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, HirId),
|
||||
{
|
||||
if let Some(pat) = pat {
|
||||
self.pat_bindings(pat, f);
|
||||
|
@ -927,7 +923,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
match expr.node {
|
||||
// Interesting cases with control flow or which gen/kill
|
||||
hir::ExprPath(hir::QPath::Resolved(_, ref path)) => {
|
||||
self.access_path(expr.id, path, succ, ACC_READ | ACC_USE)
|
||||
self.access_path(expr.hir_id, path, succ, ACC_READ | ACC_USE)
|
||||
}
|
||||
|
||||
hir::ExprField(ref e, _) => {
|
||||
|
@ -937,11 +933,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
hir::ExprClosure(.., blk_id, _, _) => {
|
||||
debug!("{} is an ExprClosure", self.ir.tcx.hir.node_to_pretty_string(expr.id));
|
||||
|
||||
/*
|
||||
The next-node for a break is the successor of the entire
|
||||
loop. The next-node for a continue is the top of this loop.
|
||||
*/
|
||||
let node = self.live_node(expr.id, expr.span);
|
||||
// The next-node for a break is the successor of the entire
|
||||
// loop. The next-node for a continue is the top of this loop.
|
||||
let node = self.live_node(expr.hir_id, expr.span);
|
||||
|
||||
let break_ln = succ;
|
||||
let cont_ln = node;
|
||||
|
@ -958,7 +952,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
};
|
||||
caps.iter().rev().fold(succ, |succ, cap| {
|
||||
self.init_from_succ(cap.ln, succ);
|
||||
let var = self.variable(cap.var_nid, expr.span);
|
||||
let var = self.variable(cap.var_hid, expr.span);
|
||||
self.acc(cap.ln, var, ACC_READ | ACC_USE);
|
||||
cap.ln
|
||||
})
|
||||
|
@ -980,7 +974,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
//
|
||||
let else_ln = self.propagate_through_opt_expr(els.as_ref().map(|e| &**e), succ);
|
||||
let then_ln = self.propagate_through_expr(&then, succ);
|
||||
let ln = self.live_node(expr.id, expr.span);
|
||||
let ln = self.live_node(expr.hir_id, expr.span);
|
||||
self.init_from_succ(ln, else_ln);
|
||||
self.merge_from_succ(ln, then_ln, false);
|
||||
self.propagate_through_expr(&cond, ln)
|
||||
|
@ -1011,7 +1005,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
// ( succ )
|
||||
//
|
||||
//
|
||||
let ln = self.live_node(expr.id, expr.span);
|
||||
let ln = self.live_node(expr.hir_id, expr.span);
|
||||
self.init_empty(ln, succ);
|
||||
let mut first_merge = true;
|
||||
for arm in arms {
|
||||
|
@ -1132,7 +1126,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
hir::ExprBinary(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.id, expr.span);
|
||||
let ln = self.live_node(expr.hir_id, expr.span);
|
||||
self.init_from_succ(ln, succ);
|
||||
self.merge_from_succ(ln, r_succ, false);
|
||||
|
||||
|
@ -1249,7 +1243,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
-> LiveNode {
|
||||
match expr.node {
|
||||
hir::ExprPath(hir::QPath::Resolved(_, ref path)) => {
|
||||
self.access_path(expr.id, path, succ, acc)
|
||||
self.access_path(expr.hir_id, path, succ, acc)
|
||||
}
|
||||
|
||||
// We do not track other places, so just propagate through
|
||||
|
@ -1260,22 +1254,23 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn access_var(&mut self, id: NodeId, nid: NodeId, succ: LiveNode, acc: u32, span: Span)
|
||||
fn access_var(&mut self, hir_id: HirId, nid: NodeId, succ: LiveNode, acc: u32, span: Span)
|
||||
-> LiveNode {
|
||||
let ln = self.live_node(id, span);
|
||||
let ln = self.live_node(hir_id, span);
|
||||
if acc != 0 {
|
||||
self.init_from_succ(ln, succ);
|
||||
let var = self.variable(nid, span);
|
||||
let var_hid = self.ir.tcx.hir.node_to_hir_id(nid);
|
||||
let var = self.variable(var_hid, span);
|
||||
self.acc(ln, var, acc);
|
||||
}
|
||||
ln
|
||||
}
|
||||
|
||||
fn access_path(&mut self, id: NodeId, path: &hir::Path, succ: LiveNode, acc: u32)
|
||||
fn access_path(&mut self, hir_id: HirId, path: &hir::Path, succ: LiveNode, acc: u32)
|
||||
-> LiveNode {
|
||||
match path.def {
|
||||
Def::Local(nid) => {
|
||||
self.access_var(id, nid, succ, acc, path.span)
|
||||
self.access_var(hir_id, nid, succ, acc, path.span)
|
||||
}
|
||||
_ => succ
|
||||
}
|
||||
|
@ -1309,7 +1304,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
|
||||
// first iteration:
|
||||
let mut first_merge = true;
|
||||
let ln = self.live_node(expr.id, expr.span);
|
||||
let ln = self.live_node(expr.hir_id, expr.span);
|
||||
self.init_empty(ln, succ);
|
||||
match kind {
|
||||
LoopLoop => {}
|
||||
|
@ -1455,9 +1450,10 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
// 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.id, expr.span);
|
||||
let var = self.variable(nid, expr.span);
|
||||
self.warn_about_dead_assign(expr.span, expr.id, ln, var);
|
||||
let ln = self.live_node(expr.hir_id, expr.span);
|
||||
let var_hid = self.ir.tcx.hir.node_to_hir_id(nid);
|
||||
let var = self.variable(var_hid, expr.span);
|
||||
self.warn_about_dead_assign(expr.span, expr.hir_id, ln, var);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
@ -1479,15 +1475,15 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
|
||||
fn warn_about_unused_args(&self, body: &hir::Body, entry_ln: LiveNode) {
|
||||
for arg in &body.arguments {
|
||||
arg.pat.each_binding(|_bm, p_id, _, path1| {
|
||||
arg.pat.each_binding(|_bm, hir_id, _, path1| {
|
||||
let sp = path1.span;
|
||||
let var = self.variable(p_id, sp);
|
||||
let var = self.variable(hir_id, sp);
|
||||
// Ignore unused self.
|
||||
let name = path1.node;
|
||||
if name != keywords::SelfValue.name() {
|
||||
if !self.warn_about_unused(sp, p_id, entry_ln, var) {
|
||||
if !self.warn_about_unused(sp, hir_id, entry_ln, var) {
|
||||
if self.live_on_entry(entry_ln, var).is_none() {
|
||||
self.report_dead_assign(p_id, sp, var, true);
|
||||
self.report_dead_assign(hir_id, sp, var, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1505,7 +1501,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
|
||||
fn warn_about_unused(&self,
|
||||
sp: Span,
|
||||
id: NodeId,
|
||||
hir_id: HirId,
|
||||
ln: LiveNode,
|
||||
var: Variable)
|
||||
-> bool {
|
||||
|
@ -1527,14 +1523,14 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
|
||||
if is_assigned {
|
||||
self.ir.tcx
|
||||
.lint_node_note(lint::builtin::UNUSED_VARIABLES, id, sp,
|
||||
&format!("variable `{}` is assigned to, but never used",
|
||||
name),
|
||||
&suggest_underscore_msg);
|
||||
.lint_hir_note(lint::builtin::UNUSED_VARIABLES, hir_id, sp,
|
||||
&format!("variable `{}` is assigned to, but never used",
|
||||
name),
|
||||
&suggest_underscore_msg);
|
||||
} else if name != "self" {
|
||||
let msg = format!("unused variable: `{}`", name);
|
||||
let mut err = self.ir.tcx
|
||||
.struct_span_lint_node(lint::builtin::UNUSED_VARIABLES, id, sp, &msg);
|
||||
.struct_span_lint_hir(lint::builtin::UNUSED_VARIABLES, hir_id, sp, &msg);
|
||||
if self.ir.variable_is_shorthand(var) {
|
||||
err.span_suggestion_with_applicability(sp, "try ignoring the field",
|
||||
format!("{}: _", name),
|
||||
|
@ -1557,21 +1553,21 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
|
||||
fn warn_about_dead_assign(&self,
|
||||
sp: Span,
|
||||
id: NodeId,
|
||||
hir_id: HirId,
|
||||
ln: LiveNode,
|
||||
var: Variable) {
|
||||
if self.live_on_exit(ln, var).is_none() {
|
||||
self.report_dead_assign(id, sp, var, false);
|
||||
self.report_dead_assign(hir_id, sp, var, false);
|
||||
}
|
||||
}
|
||||
|
||||
fn report_dead_assign(&self, id: NodeId, sp: Span, var: Variable, is_argument: bool) {
|
||||
fn report_dead_assign(&self, hir_id: HirId, sp: Span, var: Variable, is_argument: bool) {
|
||||
if let Some(name) = self.should_warn(var) {
|
||||
if is_argument {
|
||||
self.ir.tcx.lint_node(lint::builtin::UNUSED_ASSIGNMENTS, id, sp,
|
||||
self.ir.tcx.lint_hir(lint::builtin::UNUSED_ASSIGNMENTS, hir_id, sp,
|
||||
&format!("value passed to `{}` is never read", name));
|
||||
} else {
|
||||
self.ir.tcx.lint_node(lint::builtin::UNUSED_ASSIGNMENTS, id, sp,
|
||||
self.ir.tcx.lint_hir(lint::builtin::UNUSED_ASSIGNMENTS, hir_id, sp,
|
||||
&format!("value assigned to `{}` is never read", name));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -488,7 +488,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
|||
// FIXME
|
||||
None if self.is_tainted_by_errors() => Err(()),
|
||||
None => {
|
||||
let id = self.tcx.hir.definitions().find_node_for_hir_id(id);
|
||||
let id = self.tcx.hir.hir_to_node_id(id);
|
||||
bug!("no type for node {}: {} in mem_categorization",
|
||||
id, self.tcx.hir.node_to_string(id));
|
||||
}
|
||||
|
|
|
@ -266,9 +266,7 @@ fn validate_hir_id_for_typeck_tables(local_id_root: Option<DefId>,
|
|||
if let Some(local_id_root) = local_id_root {
|
||||
if hir_id.owner != local_id_root.index {
|
||||
ty::tls::with(|tcx| {
|
||||
let node_id = tcx.hir
|
||||
.definitions()
|
||||
.find_node_for_hir_id(hir_id);
|
||||
let node_id = tcx.hir.hir_to_node_id(hir_id);
|
||||
|
||||
bug!("node {} with HirId::owner {:?} cannot be placed in \
|
||||
TypeckTables with local_id_root {:?}",
|
||||
|
@ -527,7 +525,7 @@ impl<'tcx> TypeckTables<'tcx> {
|
|||
None => {
|
||||
bug!("node_id_to_type: no type for node `{}`",
|
||||
tls::with(|tcx| {
|
||||
let id = tcx.hir.definitions().find_node_for_hir_id(id);
|
||||
let id = tcx.hir.hir_to_node_id(id);
|
||||
tcx.hir.node_to_string(id)
|
||||
}))
|
||||
}
|
||||
|
@ -2544,6 +2542,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
&self.intern_goals(&[goal])[0]
|
||||
}
|
||||
|
||||
pub fn lint_hir<S: Into<MultiSpan>>(self,
|
||||
lint: &'static Lint,
|
||||
hir_id: HirId,
|
||||
span: S,
|
||||
msg: &str) {
|
||||
self.struct_span_lint_hir(lint, hir_id, span.into(), msg).emit()
|
||||
}
|
||||
|
||||
pub fn lint_node<S: Into<MultiSpan>>(self,
|
||||
lint: &'static Lint,
|
||||
id: NodeId,
|
||||
|
@ -2552,6 +2558,17 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
self.struct_span_lint_node(lint, id, span.into(), msg).emit()
|
||||
}
|
||||
|
||||
pub fn lint_hir_note<S: Into<MultiSpan>>(self,
|
||||
lint: &'static Lint,
|
||||
hir_id: HirId,
|
||||
span: S,
|
||||
msg: &str,
|
||||
note: &str) {
|
||||
let mut err = self.struct_span_lint_hir(lint, hir_id, span.into(), msg);
|
||||
err.note(note);
|
||||
err.emit()
|
||||
}
|
||||
|
||||
pub fn lint_node_note<S: Into<MultiSpan>>(self,
|
||||
lint: &'static Lint,
|
||||
id: NodeId,
|
||||
|
@ -2590,6 +2607,18 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn struct_span_lint_hir<S: Into<MultiSpan>>(self,
|
||||
lint: &'static Lint,
|
||||
hir_id: HirId,
|
||||
span: S,
|
||||
msg: &str)
|
||||
-> DiagnosticBuilder<'tcx>
|
||||
{
|
||||
let node_id = self.hir.hir_to_node_id(hir_id);
|
||||
let (level, src) = self.lint_level_at_node(lint, node_id);
|
||||
lint::struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg)
|
||||
}
|
||||
|
||||
pub fn struct_span_lint_node<S: Into<MultiSpan>>(self,
|
||||
lint: &'static Lint,
|
||||
id: NodeId,
|
||||
|
|
|
@ -19,20 +19,16 @@ use syntax::ast;
|
|||
pub use rustc_data_structures::fx::FxHashMap;
|
||||
pub use rustc_data_structures::fx::FxHashSet;
|
||||
|
||||
pub type NodeMap<T> = FxHashMap<ast::NodeId, T>;
|
||||
pub type DefIdMap<T> = FxHashMap<DefId, T>;
|
||||
pub type HirIdMap<T> = FxHashMap<HirId, T>;
|
||||
pub type ItemLocalMap<T> = FxHashMap<ItemLocalId, T>;
|
||||
|
||||
pub type NodeSet = FxHashSet<ast::NodeId>;
|
||||
pub type DefIdSet = FxHashSet<DefId>;
|
||||
pub type HirIdSet = FxHashSet<HirId>;
|
||||
pub type ItemLocalSet = FxHashSet<ItemLocalId>;
|
||||
|
||||
pub fn NodeMap<T>() -> NodeMap<T> { FxHashMap() }
|
||||
pub fn DefIdMap<T>() -> DefIdMap<T> { FxHashMap() }
|
||||
pub fn ItemLocalMap<T>() -> ItemLocalMap<T> { FxHashMap() }
|
||||
pub fn NodeSet() -> NodeSet { FxHashSet() }
|
||||
pub fn DefIdSet() -> DefIdSet { FxHashSet() }
|
||||
pub fn ItemLocalSet() -> ItemLocalSet { FxHashSet() }
|
||||
macro_rules! define_id_collections {
|
||||
($map_name:ident, $set_name:ident, $key:ty) => {
|
||||
pub type $map_name<T> = FxHashMap<$key, T>;
|
||||
pub fn $map_name<T>() -> $map_name<T> { FxHashMap() }
|
||||
pub type $set_name = FxHashSet<$key>;
|
||||
pub fn $set_name() -> $set_name { FxHashSet() }
|
||||
}
|
||||
}
|
||||
|
||||
define_id_collections!(NodeMap, NodeSet, ast::NodeId);
|
||||
define_id_collections!(DefIdMap, DefIdSet, DefId);
|
||||
define_id_collections!(HirIdMap, HirIdSet, HirId);
|
||||
define_id_collections!(ItemLocalMap, ItemLocalSet, ItemLocalId);
|
||||
|
|
|
@ -46,17 +46,16 @@ impl<'a, 'tcx> UnusedMutCx<'a, 'tcx> {
|
|||
let tcx = self.bccx.tcx;
|
||||
let mut mutables = FxHashMap();
|
||||
for p in pats {
|
||||
p.each_binding(|_, id, span, path1| {
|
||||
p.each_binding(|_, hir_id, span, path1| {
|
||||
let name = path1.node;
|
||||
|
||||
// Skip anything that looks like `_foo`
|
||||
if name.as_str().starts_with("_") {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip anything that looks like `&foo` or `&mut foo`, only look
|
||||
// for by-value bindings
|
||||
let hir_id = tcx.hir.node_to_hir_id(id);
|
||||
let bm = match self.bccx.tables.pat_binding_modes().get(hir_id) {
|
||||
Some(&bm) => bm,
|
||||
None => span_bug!(span, "missing binding mode"),
|
||||
|
@ -66,25 +65,26 @@ impl<'a, 'tcx> UnusedMutCx<'a, 'tcx> {
|
|||
_ => return,
|
||||
}
|
||||
|
||||
mutables.entry(name).or_insert(Vec::new()).push((id, hir_id, span));
|
||||
mutables.entry(name).or_insert(Vec::new()).push((hir_id, span));
|
||||
});
|
||||
}
|
||||
|
||||
for (_name, ids) in mutables {
|
||||
// If any id for this name was used mutably then consider them all
|
||||
// ok, so move on to the next
|
||||
if ids.iter().any(|&(_, ref id, _)| self.used_mut.contains(id)) {
|
||||
continue
|
||||
if ids.iter().any(|&(ref hir_id, _)| self.used_mut.contains(hir_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut_span = tcx.sess.codemap().span_until_non_whitespace(ids[0].2);
|
||||
let (hir_id, span) = ids[0];
|
||||
let mut_span = tcx.sess.codemap().span_until_non_whitespace(span);
|
||||
|
||||
// Ok, every name wasn't used mutably, so issue a warning that this
|
||||
// didn't need to be mutable.
|
||||
tcx.struct_span_lint_node(UNUSED_MUT,
|
||||
ids[0].0,
|
||||
ids[0].2,
|
||||
"variable does not need to be mutable")
|
||||
tcx.struct_span_lint_hir(UNUSED_MUT,
|
||||
hir_id,
|
||||
span,
|
||||
"variable does not need to be mutable")
|
||||
.span_suggestion_short(mut_span, "remove this `mut`", "".to_owned())
|
||||
.emit();
|
||||
}
|
||||
|
|
|
@ -499,8 +499,7 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor,
|
|||
pats: &[P<Pat>]) {
|
||||
let mut by_ref_span = None;
|
||||
for pat in pats {
|
||||
pat.each_binding(|_, id, span, _path| {
|
||||
let hir_id = cx.tcx.hir.node_to_hir_id(id);
|
||||
pat.each_binding(|_, hir_id, span, _path| {
|
||||
let bm = *cx.tables
|
||||
.pat_binding_modes()
|
||||
.get(hir_id)
|
||||
|
|
|
@ -2110,7 +2110,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
Some(&t) => t,
|
||||
None if self.is_tainted_by_errors() => self.tcx.types.err,
|
||||
None => {
|
||||
let node_id = self.tcx.hir.definitions().find_node_for_hir_id(id);
|
||||
let node_id = self.tcx.hir.hir_to_node_id(id);
|
||||
bug!("no type for node {}: {} in fcx {}",
|
||||
node_id, self.tcx.hir.node_to_string(node_id),
|
||||
self.tag());
|
||||
|
|
|
@ -380,7 +380,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||
|
||||
fn constrain_bindings_in_pat(&mut self, pat: &hir::Pat) {
|
||||
debug!("regionck::visit_pat(pat={:?})", pat);
|
||||
pat.each_binding(|_, id, span, _| {
|
||||
pat.each_binding(|_, hir_id, span, _| {
|
||||
// If we have a variable that contains region'd data, that
|
||||
// data will be accessible from anywhere that the variable is
|
||||
// accessed. We must be wary of loops like this:
|
||||
|
@ -403,8 +403,6 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||
// iteration. The easiest way to guarantee this is to require
|
||||
// that the lifetime of any regions that appear in a
|
||||
// variable's type enclose at least the variable's scope.
|
||||
|
||||
let hir_id = self.tcx.hir.node_to_hir_id(id);
|
||||
let var_scope = self.region_scope_tree.var_scope(hir_id.local_id);
|
||||
let var_region = self.tcx.mk_region(ty::ReScope(var_scope));
|
||||
|
||||
|
|
|
@ -560,7 +560,7 @@ impl Locatable for DefIndex {
|
|||
|
||||
impl Locatable for hir::HirId {
|
||||
fn to_span(&self, tcx: &TyCtxt) -> Span {
|
||||
let node_id = tcx.hir.definitions().find_node_for_hir_id(*self);
|
||||
let node_id = tcx.hir.hir_to_node_id(*self);
|
||||
tcx.hir.span(node_id)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,7 +106,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
|||
}
|
||||
assert_eq!(def_id.krate, LOCAL_CRATE);
|
||||
let hir_id = tcx.hir.definitions().def_index_to_hir_id(def_id.index);
|
||||
let id = tcx.hir.definitions().find_node_for_hir_id(hir_id);
|
||||
let id = tcx.hir.hir_to_node_id(hir_id);
|
||||
let lint = lint::builtin::UNUSED_EXTERN_CRATES;
|
||||
let msg = "unused extern crate";
|
||||
tcx.lint_node(lint, id, span, msg);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue