rustc: Add Local to the HIR map of parents

When walking parents for lints we want to be sure to hit `let` statements which
can have attributes, so hook up these statements in the HIR map.

Closes #43910
This commit is contained in:
Alex Crichton 2017-08-17 23:56:11 -07:00
parent 9b6f9d0bc4
commit 4ba2df11d8
4 changed files with 36 additions and 14 deletions

View File

@ -195,6 +195,13 @@ impl<'hir> Visitor<'hir> for NodeCollector<'hir> {
}); });
} }
fn visit_local(&mut self, l: &'hir Local) {
self.insert(l.id, NodeLocal(l));
self.with_parent(l.id, |this| {
intravisit::walk_local(this, l)
})
}
fn visit_lifetime(&mut self, lifetime: &'hir Lifetime) { fn visit_lifetime(&mut self, lifetime: &'hir Lifetime) {
self.insert(lifetime.id, NodeLifetime(lifetime)); self.insert(lifetime.id, NodeLifetime(lifetime));
} }

View File

@ -56,6 +56,7 @@ pub enum Node<'hir> {
NodeBinding(&'hir Pat), NodeBinding(&'hir Pat),
NodePat(&'hir Pat), NodePat(&'hir Pat),
NodeBlock(&'hir Block), NodeBlock(&'hir Block),
NodeLocal(&'hir Local),
/// NodeStructCtor represents a tuple struct. /// NodeStructCtor represents a tuple struct.
NodeStructCtor(&'hir VariantData), NodeStructCtor(&'hir VariantData),
@ -90,6 +91,7 @@ enum MapEntry<'hir> {
EntryLifetime(NodeId, &'hir Lifetime), EntryLifetime(NodeId, &'hir Lifetime),
EntryTyParam(NodeId, &'hir TyParam), EntryTyParam(NodeId, &'hir TyParam),
EntryVisibility(NodeId, &'hir Visibility), EntryVisibility(NodeId, &'hir Visibility),
EntryLocal(NodeId, &'hir Local),
/// Roots for node trees. /// Roots for node trees.
RootCrate, RootCrate,
@ -121,6 +123,7 @@ impl<'hir> MapEntry<'hir> {
NodeLifetime(n) => EntryLifetime(p, n), NodeLifetime(n) => EntryLifetime(p, n),
NodeTyParam(n) => EntryTyParam(p, n), NodeTyParam(n) => EntryTyParam(p, n),
NodeVisibility(n) => EntryVisibility(p, n), NodeVisibility(n) => EntryVisibility(p, n),
NodeLocal(n) => EntryLocal(p, n),
} }
} }
@ -143,6 +146,7 @@ impl<'hir> MapEntry<'hir> {
EntryLifetime(id, _) => id, EntryLifetime(id, _) => id,
EntryTyParam(id, _) => id, EntryTyParam(id, _) => id,
EntryVisibility(id, _) => id, EntryVisibility(id, _) => id,
EntryLocal(id, _) => id,
NotPresent | NotPresent |
RootCrate => return None, RootCrate => return None,
@ -168,6 +172,7 @@ impl<'hir> MapEntry<'hir> {
EntryLifetime(_, n) => NodeLifetime(n), EntryLifetime(_, n) => NodeLifetime(n),
EntryTyParam(_, n) => NodeTyParam(n), EntryTyParam(_, n) => NodeTyParam(n),
EntryVisibility(_, n) => NodeVisibility(n), EntryVisibility(_, n) => NodeVisibility(n),
EntryLocal(_, n) => NodeLocal(n),
_ => return None _ => return None
}) })
} }
@ -325,7 +330,8 @@ impl<'hir> Map<'hir> {
EntryStructCtor(p, _) | EntryStructCtor(p, _) |
EntryLifetime(p, _) | EntryLifetime(p, _) |
EntryTyParam(p, _) | EntryTyParam(p, _) |
EntryVisibility(p, _) => EntryVisibility(p, _) |
EntryLocal(p, _) =>
id = p, id = p,
EntryExpr(p, _) => { EntryExpr(p, _) => {
@ -923,6 +929,7 @@ impl<'hir> Map<'hir> {
Some(EntryTyParam(_, ty_param)) => ty_param.span, Some(EntryTyParam(_, ty_param)) => ty_param.span,
Some(EntryVisibility(_, &Visibility::Restricted { ref path, .. })) => path.span, Some(EntryVisibility(_, &Visibility::Restricted { ref path, .. })) => path.span,
Some(EntryVisibility(_, v)) => bug!("unexpected Visibility {:?}", v), Some(EntryVisibility(_, v)) => bug!("unexpected Visibility {:?}", v),
Some(EntryLocal(_, local)) => local.span,
Some(RootCrate) => self.forest.krate.span, Some(RootCrate) => self.forest.krate.span,
Some(NotPresent) | None => { Some(NotPresent) | None => {
@ -1131,6 +1138,7 @@ impl<'a> print::State<'a> {
// hir_map to reconstruct their full structure for pretty // hir_map to reconstruct their full structure for pretty
// printing. // printing.
NodeStructCtor(_) => bug!("cannot print isolated StructCtor"), NodeStructCtor(_) => bug!("cannot print isolated StructCtor"),
NodeLocal(a) => self.print_local_decl(&a),
} }
} }
} }
@ -1232,6 +1240,9 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
Some(NodeBlock(_)) => { Some(NodeBlock(_)) => {
format!("block {}{}", map.node_to_pretty_string(id), id_str) format!("block {}{}", map.node_to_pretty_string(id), id_str)
} }
Some(NodeLocal(_)) => {
format!("local {}{}", map.node_to_pretty_string(id), id_str)
}
Some(NodeStructCtor(_)) => { Some(NodeStructCtor(_)) => {
format!("struct_ctor {}{}", path_str(), id_str) format!("struct_ctor {}{}", path_str(), id_str)
} }

View File

@ -68,19 +68,7 @@ fn get_pattern_source<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pat: &Pat) -> Patte
}); });
PatternSource::MatchExpr(e) PatternSource::MatchExpr(e)
} }
NodeStmt(ref s) => { NodeLocal(local) => PatternSource::LetDecl(local),
// the enclosing statement must be a `let` or something else
match s.node {
StmtDecl(ref decl, _) => {
match decl.node {
DeclLocal(ref local) => PatternSource::LetDecl(local),
_ => return PatternSource::Other,
}
}
_ => return PatternSource::Other,
}
}
_ => return PatternSource::Other, _ => return PatternSource::Other,
} }

View File

@ -0,0 +1,16 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![deny(unused_variables)]
fn main() {
#[allow(unused_variables)]
let x = 12;
}