Fix dead code check for associated const impls.
This commit is contained in:
parent
7f78887547
commit
91ae5e31ab
@ -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(..) => {}
|
||||
}
|
||||
|
22
src/test/compile-fail/associated-const-dead-code.rs
Normal file
22
src/test/compile-fail/associated-const-dead-code.rs
Normal 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;
|
||||
}
|
@ -18,6 +18,6 @@ impl Foo {
|
||||
const BAR: u32 = GLOBAL_BAR;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
pub fn main() {
|
||||
let _: u32 = Foo::BAR;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user