]> git.proxmox.com Git - rustc.git/blame - src/librustc_resolve/check_unused.rs
New upstream version 1.14.0+dfsg1
[rustc.git] / src / librustc_resolve / check_unused.rs
CommitLineData
1a4d82fc
JJ
1// Copyright 2012-2014 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
12//
13// Unused import checking
14//
15// Although this is mostly a lint pass, it lives in here because it depends on
16// resolve data structures and because it finalises the privacy information for
17// `use` directives.
18//
a7813a04
XL
19// Unused trait imports can't be checked until the method resolution. We save
20// candidates here, and do the acutal check in librustc_typeck/check_unused.rs.
1a4d82fc
JJ
21
22use std::ops::{Deref, DerefMut};
23
24use Resolver;
25use Namespace::{TypeNS, ValueNS};
26
27use rustc::lint;
a7813a04
XL
28use syntax::ast::{self, ViewPathGlob, ViewPathList, ViewPathSimple};
29use syntax::visit::{self, Visitor};
3157f602 30use syntax_pos::{Span, DUMMY_SP};
e9174d1e 31
1a4d82fc 32
a7813a04
XL
33struct UnusedImportCheckVisitor<'a, 'b: 'a> {
34 resolver: &'a mut Resolver<'b>,
1a4d82fc
JJ
35}
36
37// Deref and DerefMut impls allow treating UnusedImportCheckVisitor as Resolver.
a7813a04
XL
38impl<'a, 'b> Deref for UnusedImportCheckVisitor<'a, 'b> {
39 type Target = Resolver<'b>;
1a4d82fc 40
a7813a04 41 fn deref<'c>(&'c self) -> &'c Resolver<'b> {
1a4d82fc
JJ
42 &*self.resolver
43 }
44}
45
a7813a04
XL
46impl<'a, 'b> DerefMut for UnusedImportCheckVisitor<'a, 'b> {
47 fn deref_mut<'c>(&'c mut self) -> &'c mut Resolver<'b> {
1a4d82fc
JJ
48 &mut *self.resolver
49 }
50}
51
a7813a04 52impl<'a, 'b> UnusedImportCheckVisitor<'a, 'b> {
92a42be0 53 // We have information about whether `use` (import) directives are actually
54a0048b
SL
54 // used now. If an import is not used at all, we signal a lint error.
55 fn check_import(&mut self, id: ast::NodeId, span: Span) {
1a4d82fc
JJ
56 if !self.used_imports.contains(&(id, TypeNS)) &&
57 !self.used_imports.contains(&(id, ValueNS)) {
a7813a04
XL
58 if self.maybe_unused_trait_imports.contains(&id) {
59 // Check later.
60 return;
61 }
c30ab7b3
SL
62 let msg = if let Ok(snippet) = self.session.codemap().span_to_snippet(span) {
63 format!("unused import: `{}`", snippet)
64 } else {
65 "unused import".to_string()
66 };
67 self.session.add_lint(lint::builtin::UNUSED_IMPORTS, id, span, msg);
a7813a04
XL
68 } else {
69 // This trait import is definitely used, in a way other than
70 // method resolution.
71 self.maybe_unused_trait_imports.remove(&id);
1a4d82fc 72 }
1a4d82fc
JJ
73 }
74}
75
3157f602 76impl<'a, 'b> Visitor for UnusedImportCheckVisitor<'a, 'b> {
a7813a04
XL
77 fn visit_item(&mut self, item: &ast::Item) {
78 visit::walk_item(self, item);
1a4d82fc
JJ
79 // Ignore is_public import statements because there's no way to be sure
80 // whether they're used or not. Also ignore imports with a dummy span
81 // because this means that they were generated in some fashion by the
82 // compiler and we don't need to consider them.
a7813a04 83 if item.vis == ast::Visibility::Public || item.span.source_equal(&DUMMY_SP) {
1a4d82fc
JJ
84 return;
85 }
86
85aaf69f 87 match item.node {
a7813a04 88 ast::ItemKind::ExternCrate(_) => {
92a42be0 89 if let Some(crate_num) = self.session.cstore.extern_mod_stmt_cnum(item.id) {
1a4d82fc
JJ
90 if !self.used_crates.contains(&crate_num) {
91 self.session.add_lint(lint::builtin::UNUSED_EXTERN_CRATES,
85aaf69f
SL
92 item.id,
93 item.span,
1a4d82fc
JJ
94 "unused extern crate".to_string());
95 }
96 }
92a42be0 97 }
a7813a04 98 ast::ItemKind::Use(ref p) => {
1a4d82fc 99 match p.node {
9e0c209e 100 ViewPathSimple(..) => {
54a0048b 101 self.check_import(item.id, p.span)
1a4d82fc
JJ
102 }
103
85aaf69f
SL
104 ViewPathList(_, ref list) => {
105 for i in list {
9e0c209e 106 self.check_import(i.node.id, i.span);
1a4d82fc
JJ
107 }
108 }
85aaf69f 109 ViewPathGlob(_) => {
54a0048b 110 self.check_import(item.id, p.span)
1a4d82fc
JJ
111 }
112 }
113 }
85aaf69f 114 _ => {}
1a4d82fc 115 }
1a4d82fc
JJ
116 }
117}
118
a7813a04 119pub fn check_crate(resolver: &mut Resolver, krate: &ast::Crate) {
1a4d82fc 120 let mut visitor = UnusedImportCheckVisitor { resolver: resolver };
a7813a04 121 visit::walk_crate(&mut visitor, krate);
1a4d82fc 122}