]>
Commit | Line | Data |
---|---|---|
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 | ||
20 | use std::ops::{Deref, DerefMut}; | |
21 | ||
22 | use Resolver; | |
23 | use Namespace::{TypeNS, ValueNS}; | |
24 | ||
25 | use rustc::lint; | |
1a4d82fc | 26 | use syntax::ast; |
1a4d82fc | 27 | use syntax::codemap::{Span, DUMMY_SP}; |
e9174d1e | 28 | |
54a0048b SL |
29 | use rustc::hir; |
30 | use rustc::hir::{ViewPathGlob, ViewPathList, ViewPathSimple}; | |
31 | use rustc::hir::intravisit::Visitor; | |
1a4d82fc | 32 | |
92a42be0 SL |
33 | struct 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. | |
38 | impl<'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 | ||
46 | impl<'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 | ||
52 | impl<'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 | ||
66 | impl<'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 | 108 | pub 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 | } |