]> git.proxmox.com Git - rustc.git/blame - src/librustc_resolve/check_unused.rs
Imported Upstream version 1.9.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//
19
20use std::ops::{Deref, DerefMut};
21
22use Resolver;
23use Namespace::{TypeNS, ValueNS};
24
25use rustc::lint;
1a4d82fc 26use syntax::ast;
1a4d82fc 27use syntax::codemap::{Span, DUMMY_SP};
e9174d1e 28
54a0048b
SL
29use rustc::hir;
30use rustc::hir::{ViewPathGlob, ViewPathList, ViewPathSimple};
31use rustc::hir::intravisit::Visitor;
1a4d82fc 32
92a42be0
SL
33struct UnusedImportCheckVisitor<'a, 'b: 'a, 'tcx: 'b> {
34 resolver: &'a mut Resolver<'b, 'tcx>,
1a4d82fc
JJ
35}
36
37// Deref and DerefMut impls allow treating UnusedImportCheckVisitor as Resolver.
38impl<'a, 'b, 'tcx:'b> Deref for UnusedImportCheckVisitor<'a, 'b, 'tcx> {
39 type Target = Resolver<'b, 'tcx>;
40
41 fn deref<'c>(&'c self) -> &'c Resolver<'b, 'tcx> {
42 &*self.resolver
43 }
44}
45
46impl<'a, 'b, 'tcx:'b> DerefMut for UnusedImportCheckVisitor<'a, 'b, 'tcx> {
47 fn deref_mut<'c>(&'c mut self) -> &'c mut Resolver<'b, 'tcx> {
48 &mut *self.resolver
49 }
50}
51
52impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> {
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)) {
58 self.session.add_lint(lint::builtin::UNUSED_IMPORTS,
59 id,
60 span,
61 "unused import".to_string());
62 }
1a4d82fc
JJ
63 }
64}
65
66impl<'a, 'b, 'v, 'tcx> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b, 'tcx> {
e9174d1e 67 fn visit_item(&mut self, item: &hir::Item) {
1a4d82fc
JJ
68 // Ignore is_public import statements because there's no way to be sure
69 // whether they're used or not. Also ignore imports with a dummy span
70 // because this means that they were generated in some fashion by the
71 // compiler and we don't need to consider them.
7453a54e 72 if item.vis == hir::Public || item.span.source_equal(&DUMMY_SP) {
1a4d82fc
JJ
73 return;
74 }
75
85aaf69f 76 match item.node {
e9174d1e 77 hir::ItemExternCrate(_) => {
92a42be0 78 if let Some(crate_num) = self.session.cstore.extern_mod_stmt_cnum(item.id) {
1a4d82fc
JJ
79 if !self.used_crates.contains(&crate_num) {
80 self.session.add_lint(lint::builtin::UNUSED_EXTERN_CRATES,
85aaf69f
SL
81 item.id,
82 item.span,
1a4d82fc
JJ
83 "unused extern crate".to_string());
84 }
85 }
92a42be0 86 }
e9174d1e 87 hir::ItemUse(ref p) => {
1a4d82fc 88 match p.node {
85aaf69f 89 ViewPathSimple(_, _) => {
54a0048b 90 self.check_import(item.id, p.span)
1a4d82fc
JJ
91 }
92
85aaf69f
SL
93 ViewPathList(_, ref list) => {
94 for i in list {
54a0048b 95 self.check_import(i.node.id(), i.span);
1a4d82fc
JJ
96 }
97 }
85aaf69f 98 ViewPathGlob(_) => {
54a0048b 99 self.check_import(item.id, p.span)
1a4d82fc
JJ
100 }
101 }
102 }
85aaf69f 103 _ => {}
1a4d82fc 104 }
1a4d82fc
JJ
105 }
106}
107
e9174d1e 108pub fn check_crate(resolver: &mut Resolver, krate: &hir::Crate) {
1a4d82fc 109 let mut visitor = UnusedImportCheckVisitor { resolver: resolver };
92a42be0 110 krate.visit_all_items(&mut visitor);
1a4d82fc 111}