middle: HirIdify dead

This commit is contained in:
ljedrz 2019-02-26 11:01:11 +01:00
parent 4543fc243e
commit 43294c6c8c

View File

@ -26,8 +26,8 @@ use syntax_pos;
// function, then we should explore its block to check for codes that
// may need to be marked as live.
fn should_explore<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
node_id: ast::NodeId) -> bool {
match tcx.hir().find(node_id) {
hir_id: hir::HirId) -> bool {
match tcx.hir().find_by_hir_id(hir_id) {
Some(Node::Item(..)) |
Some(Node::ImplItem(..)) |
Some(Node::ForeignItem(..)) |
@ -39,33 +39,33 @@ fn should_explore<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
struct MarkSymbolVisitor<'a, 'tcx: 'a> {
worklist: Vec<ast::NodeId>,
worklist: Vec<hir::HirId>,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
tables: &'a ty::TypeckTables<'tcx>,
live_symbols: FxHashSet<ast::NodeId>,
live_symbols: FxHashSet<hir::HirId>,
repr_has_repr_c: bool,
in_pat: bool,
inherited_pub_visibility: bool,
ignore_variant_stack: Vec<DefId>,
// maps from tuple struct constructors to tuple struct items
struct_constructors: FxHashMap<ast::NodeId, ast::NodeId>,
struct_constructors: FxHashMap<hir::HirId, hir::HirId>,
}
impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
fn check_def_id(&mut self, def_id: DefId) {
if let Some(node_id) = self.tcx.hir().as_local_node_id(def_id) {
if should_explore(self.tcx, node_id) ||
self.struct_constructors.contains_key(&node_id) {
self.worklist.push(node_id);
if let Some(hir_id) = self.tcx.hir().as_local_hir_id(def_id) {
if should_explore(self.tcx, hir_id) ||
self.struct_constructors.contains_key(&hir_id) {
self.worklist.push(hir_id);
}
self.live_symbols.insert(node_id);
self.live_symbols.insert(hir_id);
}
}
fn insert_def_id(&mut self, def_id: DefId) {
if let Some(node_id) = self.tcx.hir().as_local_node_id(def_id) {
debug_assert!(!should_explore(self.tcx, node_id));
self.live_symbols.insert(node_id);
if let Some(hir_id) = self.tcx.hir().as_local_hir_id(def_id) {
debug_assert!(!should_explore(self.tcx, hir_id));
self.live_symbols.insert(hir_id);
}
}
@ -136,7 +136,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
// tuple struct constructor function
let id = self.struct_constructors.get(&id).cloned().unwrap_or(id);
if let Some(node) = self.tcx.hir().find(id) {
if let Some(node) = self.tcx.hir().find_by_hir_id(id) {
self.live_symbols.insert(id);
self.visit_node(node);
}
@ -217,7 +217,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
let live_fields = def.fields().iter().filter(|f| {
has_repr_c || inherited_pub_visibility || f.vis.node.is_pub()
});
self.live_symbols.extend(live_fields.map(|f| f.id));
self.live_symbols.extend(live_fields.map(|f| f.hir_id));
intravisit::walk_struct_def(self, def);
}
@ -285,7 +285,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
}
fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_, '_, '_>,
id: ast::NodeId,
id: hir::HirId,
attrs: &[ast::Attribute]) -> bool {
if attr::contains_name(attrs, "lang") {
return true;
@ -306,7 +306,7 @@ fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_, '_, '_>,
return true;
}
let def_id = tcx.hir().local_def_id(id);
let def_id = tcx.hir().local_def_id_from_hir_id(id);
let cg_attrs = tcx.codegen_fn_attrs(def_id);
// #[used], #[no_mangle], #[export_name], etc also keeps the item alive
@ -333,25 +333,25 @@ fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_, '_, '_>,
// 2) We are not sure to be live or not
// * Implementation of a trait method
struct LifeSeeder<'k, 'tcx: 'k> {
worklist: Vec<ast::NodeId>,
worklist: Vec<hir::HirId>,
krate: &'k hir::Crate,
tcx: TyCtxt<'k, 'tcx, 'tcx>,
// see `MarkSymbolVisitor::struct_constructors`
struct_constructors: FxHashMap<ast::NodeId, ast::NodeId>,
struct_constructors: FxHashMap<hir::HirId, hir::HirId>,
}
impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> {
fn visit_item(&mut self, item: &hir::Item) {
let allow_dead_code = has_allow_dead_code_or_lang_attr(self.tcx,
item.id,
item.hir_id,
&item.attrs);
if allow_dead_code {
self.worklist.push(item.id);
self.worklist.push(item.hir_id);
}
match item.node {
hir::ItemKind::Enum(ref enum_def, _) if allow_dead_code => {
self.worklist.extend(enum_def.variants.iter()
.map(|variant| variant.node.data.id()));
.map(|variant| variant.node.data.hir_id()));
}
hir::ItemKind::Trait(.., ref trait_item_refs) => {
for trait_item_ref in trait_item_refs {
@ -360,9 +360,9 @@ impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> {
hir::TraitItemKind::Const(_, Some(_)) |
hir::TraitItemKind::Method(_, hir::TraitMethod::Provided(_)) => {
if has_allow_dead_code_or_lang_attr(self.tcx,
trait_item.id,
trait_item.hir_id,
&trait_item.attrs) {
self.worklist.push(trait_item.id);
self.worklist.push(trait_item.hir_id);
}
}
_ => {}
@ -374,14 +374,14 @@ impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> {
let impl_item = self.krate.impl_item(impl_item_ref.id);
if opt_trait.is_some() ||
has_allow_dead_code_or_lang_attr(self.tcx,
impl_item.id,
impl_item.hir_id,
&impl_item.attrs) {
self.worklist.push(impl_item_ref.id.node_id);
self.worklist.push(self.tcx.hir().node_to_hir_id(impl_item_ref.id.node_id));
}
}
}
hir::ItemKind::Struct(ref variant_data, _) => {
self.struct_constructors.insert(variant_data.id(), item.id);
self.struct_constructors.insert(variant_data.hir_id(), item.hir_id);
}
_ => ()
}
@ -400,16 +400,16 @@ fn create_and_seed_worklist<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
access_levels: &privacy::AccessLevels,
krate: &hir::Crate,
) -> (Vec<ast::NodeId>, FxHashMap<ast::NodeId, ast::NodeId>) {
) -> (Vec<hir::HirId>, FxHashMap<hir::HirId, hir::HirId>) {
let worklist = access_levels.map.iter().filter_map(|(&id, level)| {
if level >= &privacy::AccessLevel::Reachable {
Some(id)
Some(tcx.hir().node_to_hir_id(id))
} else {
None
}
}).chain(
// Seed entry point
tcx.entry_fn(LOCAL_CRATE).map(|(def_id, _)| tcx.hir().as_local_node_id(def_id).unwrap())
tcx.entry_fn(LOCAL_CRATE).map(|(def_id, _)| tcx.hir().as_local_hir_id(def_id).unwrap())
).collect::<Vec<_>>();
// Seed implemented trait items
@ -427,7 +427,7 @@ fn create_and_seed_worklist<'a, 'tcx>(
fn find_live<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
access_levels: &privacy::AccessLevels,
krate: &hir::Crate)
-> FxHashSet<ast::NodeId> {
-> FxHashSet<hir::HirId> {
let (worklist, struct_constructors) = create_and_seed_worklist(tcx, access_levels, krate);
let mut symbol_visitor = MarkSymbolVisitor {
worklist,
@ -446,7 +446,7 @@ fn find_live<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
struct DeadVisitor<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
live_symbols: FxHashSet<ast::NodeId>,
live_symbols: FxHashSet<hir::HirId>,
}
impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
@ -461,33 +461,33 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
| hir::ItemKind::Union(..) => true,
_ => false
};
should_warn && !self.symbol_is_live(item.id)
should_warn && !self.symbol_is_live(item.hir_id)
}
fn should_warn_about_field(&mut self, field: &hir::StructField) -> bool {
let field_type = self.tcx.type_of(self.tcx.hir().local_def_id(field.id));
!field.is_positional()
&& !self.symbol_is_live(field.id)
&& !self.symbol_is_live(field.hir_id)
&& !field_type.is_phantom_data()
&& !has_allow_dead_code_or_lang_attr(self.tcx, field.id, &field.attrs)
&& !has_allow_dead_code_or_lang_attr(self.tcx, field.hir_id, &field.attrs)
}
fn should_warn_about_variant(&mut self, variant: &hir::VariantKind) -> bool {
!self.symbol_is_live(variant.data.id())
!self.symbol_is_live(variant.data.hir_id())
&& !has_allow_dead_code_or_lang_attr(self.tcx,
variant.data.id(),
variant.data.hir_id(),
&variant.attrs)
}
fn should_warn_about_foreign_item(&mut self, fi: &hir::ForeignItem) -> bool {
!self.symbol_is_live(fi.id)
&& !has_allow_dead_code_or_lang_attr(self.tcx, fi.id, &fi.attrs)
!self.symbol_is_live(fi.hir_id)
&& !has_allow_dead_code_or_lang_attr(self.tcx, fi.hir_id, &fi.attrs)
}
// id := node id of an item's definition.
// id := HIR id of an item's definition.
fn symbol_is_live(
&mut self,
id: ast::NodeId,
id: hir::HirId,
) -> bool {
if self.live_symbols.contains(&id) {
return true;
@ -496,12 +496,12 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
// This is done to handle the case where, for example, the static
// method of a private type is used, but the type itself is never
// called directly.
let def_id = self.tcx.hir().local_def_id(id);
let def_id = self.tcx.hir().local_def_id_from_hir_id(id);
let inherent_impls = self.tcx.inherent_impls(def_id);
for &impl_did in inherent_impls.iter() {
for &item_did in &self.tcx.associated_item_def_ids(impl_did)[..] {
if let Some(item_node_id) = self.tcx.hir().as_local_node_id(item_did) {
if self.live_symbols.contains(&item_node_id) {
if let Some(item_hir_id) = self.tcx.hir().as_local_hir_id(item_did) {
if self.live_symbols.contains(&item_hir_id) {
return true;
}
}
@ -511,18 +511,18 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
}
fn warn_dead_code(&mut self,
id: ast::NodeId,
id: hir::HirId,
span: syntax_pos::Span,
name: ast::Name,
node_type: &str,
participle: &str) {
if !name.as_str().starts_with("_") {
self.tcx
.lint_node(lint::builtin::DEAD_CODE,
id,
span,
&format!("{} is never {}: `{}`",
node_type, participle, name));
.lint_hir(lint::builtin::DEAD_CODE,
id,
span,
&format!("{} is never {}: `{}`",
node_type, participle, name));
}
}
}
@ -555,7 +555,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
_ => "used"
};
self.warn_dead_code(
item.id,
item.hir_id,
span,
item.ident.name,
item.node.descriptive_variant(),
@ -572,7 +572,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
g: &'tcx hir::Generics,
id: hir::HirId) {
if self.should_warn_about_variant(&variant.node) {
self.warn_dead_code(variant.node.data.id(), variant.span, variant.node.ident.name,
self.warn_dead_code(variant.node.data.hir_id(), variant.span, variant.node.ident.name,
"variant", "constructed");
} else {
intravisit::walk_variant(self, variant, g, id);
@ -581,7 +581,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
fn visit_foreign_item(&mut self, fi: &'tcx hir::ForeignItem) {
if self.should_warn_about_foreign_item(fi) {
self.warn_dead_code(fi.id, fi.span, fi.ident.name,
self.warn_dead_code(fi.hir_id, fi.span, fi.ident.name,
fi.node.descriptive_variant(), "used");
}
intravisit::walk_foreign_item(self, fi);
@ -589,7 +589,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
fn visit_struct_field(&mut self, field: &'tcx hir::StructField) {
if self.should_warn_about_field(&field) {
self.warn_dead_code(field.id, field.span, field.ident.name, "field", "used");
self.warn_dead_code(field.hir_id, field.span, field.ident.name, "field", "used");
}
intravisit::walk_struct_field(self, field);
}
@ -597,8 +597,8 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
match impl_item.node {
hir::ImplItemKind::Const(_, body_id) => {
if !self.symbol_is_live(impl_item.id) {
self.warn_dead_code(impl_item.id,
if !self.symbol_is_live(impl_item.hir_id) {
self.warn_dead_code(impl_item.hir_id,
impl_item.span,
impl_item.ident.name,
"associated const",
@ -607,9 +607,10 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
self.visit_nested_body(body_id)
}
hir::ImplItemKind::Method(_, body_id) => {
if !self.symbol_is_live(impl_item.id) {
if !self.symbol_is_live(impl_item.hir_id) {
let span = self.tcx.sess.source_map().def_span(impl_item.span);
self.warn_dead_code(impl_item.id, span, impl_item.ident.name, "method", "used");
self.warn_dead_code(impl_item.hir_id, span, impl_item.ident.name, "method",
"used");
}
self.visit_nested_body(body_id)
}