Fix dead code check for associated const impls.

This commit is contained in:
Sean Patrick Santos 2015-03-22 19:24:56 -06:00
parent 7f78887547
commit 91ae5e31ab
3 changed files with 55 additions and 23 deletions

View File

@ -346,6 +346,7 @@ impl<'v> Visitor<'v> for LifeSeeder {
ast::ItemTrait(_, _, _, ref trait_items) => {
for trait_item in trait_items {
match trait_item.node {
ast::ConstTraitItem(_, Some(_)) |
ast::MethodTraitItem(_, Some(_)) => {
if has_allow_dead_code_or_lang_attr(&trait_item.attrs) {
self.worklist.push(trait_item.id);
@ -358,7 +359,7 @@ impl<'v> Visitor<'v> for LifeSeeder {
ast::ItemImpl(_, _, _, ref opt_trait, _, ref impl_items) => {
for impl_item in impl_items {
match impl_item.node {
ast::ConstImplItem(..) => {}
ast::ConstImplItem(..) |
ast::MethodImplItem(..) => {
if opt_trait.is_some() ||
has_allow_dead_code_or_lang_attr(&impl_item.attrs) {
@ -400,7 +401,7 @@ fn create_and_seed_worklist(tcx: &ty::ctxt,
None => ()
}
// Seed implemented trait methods
// Seed implemented trait items
let mut life_seeder = LifeSeeder {
worklist: worklist
};
@ -481,7 +482,7 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
|ctor| self.live_symbols.contains(&ctor)) {
return true;
}
// If it's a type whose methods are live, then it's live, too.
// If it's a type whose items are live, then it's live, too.
// 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.
@ -551,21 +552,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
visit::walk_foreign_item(self, fi);
}
fn visit_fn(&mut self, fk: visit::FnKind<'v>,
_: &'v ast::FnDecl, block: &'v ast::Block,
span: codemap::Span, id: ast::NodeId) {
// Have to warn method here because methods are not ast::Item
match fk {
visit::FkMethod(name, _, _) => {
if !self.symbol_is_live(id, None) {
self.warn_dead_code(id, span, name.name, "method");
}
}
_ => ()
}
visit::walk_block(self, block);
}
fn visit_struct_field(&mut self, field: &ast::StructField) {
if self.should_warn_about_field(&field.node) {
self.warn_dead_code(field.node.id, field.span,
@ -575,13 +561,37 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
visit::walk_struct_field(self, field);
}
// Overwrite so that we don't warn the trait method itself.
fn visit_trait_item(&mut self, trait_method: &ast::TraitItem) {
match trait_method.node {
ast::ConstTraitItem(_, _) => {}
fn visit_impl_item(&mut self, impl_item: &ast::ImplItem) {
match impl_item.node {
ast::ConstImplItem(_, ref expr) => {
if !self.symbol_is_live(impl_item.id, None) {
self.warn_dead_code(impl_item.id, impl_item.span,
impl_item.ident.name, "associated const");
}
visit::walk_expr(self, expr)
}
ast::MethodImplItem(_, ref body) => {
if !self.symbol_is_live(impl_item.id, None) {
self.warn_dead_code(impl_item.id, impl_item.span,
impl_item.ident.name, "method");
}
visit::walk_block(self, body)
}
ast::TypeImplItem(..) |
ast::MacImplItem(..) => {}
}
}
// Overwrite so that we don't warn the trait item itself.
fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
match trait_item.node {
ast::ConstTraitItem(_, Some(ref expr)) => {
visit::walk_expr(self, expr)
}
ast::MethodTraitItem(_, Some(ref body)) => {
visit::walk_block(self, body)
}
ast::ConstTraitItem(_, None) |
ast::MethodTraitItem(_, None) |
ast::TypeTraitItem(..) => {}
}

View File

@ -0,0 +1,22 @@
// Copyright 2015 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(dead_code)]
struct MyFoo;
impl MyFoo {
const BAR: u32 = 1;
//~^ ERROR associated const is never used: `BAR`
}
fn main() {
let _: MyFoo = MyFoo;
}

View File

@ -18,6 +18,6 @@ impl Foo {
const BAR: u32 = GLOBAL_BAR;
}
fn main() {
pub fn main() {
let _: u32 = Foo::BAR;
}