Skip to content

Commit 38a8c80

Browse files
committed
Fix dead code check for associated const impls.
1 parent 23cd0bd commit 38a8c80

File tree

3 files changed

+55
-23
lines changed

3 files changed

+55
-23
lines changed

src/librustc/middle/dead.rs

+32-22
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ impl<'v> Visitor<'v> for LifeSeeder {
346346
ast::ItemTrait(_, _, _, ref trait_items) => {
347347
for trait_item in trait_items {
348348
match trait_item.node {
349+
ast::ConstTraitItem(_, Some(_)) |
349350
ast::MethodTraitItem(_, Some(_)) => {
350351
if has_allow_dead_code_or_lang_attr(&trait_item.attrs) {
351352
self.worklist.push(trait_item.id);
@@ -358,7 +359,7 @@ impl<'v> Visitor<'v> for LifeSeeder {
358359
ast::ItemImpl(_, _, _, ref opt_trait, _, ref impl_items) => {
359360
for impl_item in impl_items {
360361
match impl_item.node {
361-
ast::ConstImplItem(..) => {}
362+
ast::ConstImplItem(..) |
362363
ast::MethodImplItem(..) => {
363364
if opt_trait.is_some() ||
364365
has_allow_dead_code_or_lang_attr(&impl_item.attrs) {
@@ -400,7 +401,7 @@ fn create_and_seed_worklist(tcx: &ty::ctxt,
400401
None => ()
401402
}
402403

403-
// Seed implemented trait methods
404+
// Seed implemented trait items
404405
let mut life_seeder = LifeSeeder {
405406
worklist: worklist
406407
};
@@ -481,7 +482,7 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
481482
|ctor| self.live_symbols.contains(&ctor)) {
482483
return true;
483484
}
484-
// If it's a type whose methods are live, then it's live, too.
485+
// If it's a type whose items are live, then it's live, too.
485486
// This is done to handle the case where, for example, the static
486487
// method of a private type is used, but the type itself is never
487488
// called directly.
@@ -551,21 +552,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
551552
visit::walk_foreign_item(self, fi);
552553
}
553554

554-
fn visit_fn(&mut self, fk: visit::FnKind<'v>,
555-
_: &'v ast::FnDecl, block: &'v ast::Block,
556-
span: codemap::Span, id: ast::NodeId) {
557-
// Have to warn method here because methods are not ast::Item
558-
match fk {
559-
visit::FkMethod(name, _, _) => {
560-
if !self.symbol_is_live(id, None) {
561-
self.warn_dead_code(id, span, name.name, "method");
562-
}
563-
}
564-
_ => ()
565-
}
566-
visit::walk_block(self, block);
567-
}
568-
569555
fn visit_struct_field(&mut self, field: &ast::StructField) {
570556
if self.should_warn_about_field(&field.node) {
571557
self.warn_dead_code(field.node.id, field.span,
@@ -575,13 +561,37 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
575561
visit::walk_struct_field(self, field);
576562
}
577563

578-
// Overwrite so that we don't warn the trait method itself.
579-
fn visit_trait_item(&mut self, trait_method: &ast::TraitItem) {
580-
match trait_method.node {
581-
ast::ConstTraitItem(_, _) => {}
564+
fn visit_impl_item(&mut self, impl_item: &ast::ImplItem) {
565+
match impl_item.node {
566+
ast::ConstImplItem(_, ref expr) => {
567+
if !self.symbol_is_live(impl_item.id, None) {
568+
self.warn_dead_code(impl_item.id, impl_item.span,
569+
impl_item.ident.name, "associated const");
570+
}
571+
visit::walk_expr(self, expr)
572+
}
573+
ast::MethodImplItem(_, ref body) => {
574+
if !self.symbol_is_live(impl_item.id, None) {
575+
self.warn_dead_code(impl_item.id, impl_item.span,
576+
impl_item.ident.name, "method");
577+
}
578+
visit::walk_block(self, body)
579+
}
580+
ast::TypeImplItem(..) |
581+
ast::MacImplItem(..) => {}
582+
}
583+
}
584+
585+
// Overwrite so that we don't warn the trait item itself.
586+
fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
587+
match trait_item.node {
588+
ast::ConstTraitItem(_, Some(ref expr)) => {
589+
visit::walk_expr(self, expr)
590+
}
582591
ast::MethodTraitItem(_, Some(ref body)) => {
583592
visit::walk_block(self, body)
584593
}
594+
ast::ConstTraitItem(_, None) |
585595
ast::MethodTraitItem(_, None) |
586596
ast::TypeTraitItem(..) => {}
587597
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![deny(dead_code)]
12+
13+
struct MyFoo;
14+
15+
impl MyFoo {
16+
const BAR: u32 = 1;
17+
//~^ ERROR associated const is never used: `BAR`
18+
}
19+
20+
fn main() {
21+
let _: MyFoo = MyFoo;
22+
}

src/test/run-pass/associated-const-marks-live-code.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ impl Foo {
1818
const BAR: u32 = GLOBAL_BAR;
1919
}
2020

21-
fn main() {
21+
pub fn main() {
2222
let _: u32 = Foo::BAR;
2323
}

0 commit comments

Comments
 (0)