]> git.lizzy.rs Git - rust.git/blob - src/librustc_lint/levels.rs
Rollup merge of #67875 - dtolnay:hidden, r=GuillaumeGomez
[rust.git] / src / librustc_lint / levels.rs
1 use rustc::hir::intravisit;
2 use rustc::lint::{LintLevelMap, LintLevelSets, LintLevelsBuilder, LintStore};
3 use rustc::ty::query::Providers;
4 use rustc::ty::TyCtxt;
5 use rustc_hir as hir;
6 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
7 use syntax::ast;
8
9 pub use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintId};
10
11 fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> &LintLevelMap {
12     assert_eq!(cnum, LOCAL_CRATE);
13     let store = &tcx.lint_store;
14     let mut builder = LintLevelMapBuilder {
15         levels: LintLevelSets::builder(tcx.sess, false, &store),
16         tcx: tcx,
17         store: store,
18     };
19     let krate = tcx.hir().krate();
20
21     let push = builder.levels.push(&krate.attrs, &store);
22     builder.levels.register_id(hir::CRATE_HIR_ID);
23     for macro_def in krate.exported_macros {
24         builder.levels.register_id(macro_def.hir_id);
25     }
26     intravisit::walk_crate(&mut builder, krate);
27     builder.levels.pop(push);
28
29     tcx.arena.alloc(builder.levels.build_map())
30 }
31
32 struct LintLevelMapBuilder<'a, 'tcx> {
33     levels: LintLevelsBuilder<'tcx>,
34     tcx: TyCtxt<'tcx>,
35     store: &'a LintStore,
36 }
37
38 impl LintLevelMapBuilder<'_, '_> {
39     fn with_lint_attrs<F>(&mut self, id: hir::HirId, attrs: &[ast::Attribute], f: F)
40     where
41         F: FnOnce(&mut Self),
42     {
43         let push = self.levels.push(attrs, self.store);
44         if push.changed {
45             self.levels.register_id(id);
46         }
47         f(self);
48         self.levels.pop(push);
49     }
50 }
51
52 impl<'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'_, 'tcx> {
53     fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'tcx> {
54         intravisit::NestedVisitorMap::All(&self.tcx.hir())
55     }
56
57     fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
58         self.with_lint_attrs(param.hir_id, &param.attrs, |builder| {
59             intravisit::walk_param(builder, param);
60         });
61     }
62
63     fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) {
64         self.with_lint_attrs(it.hir_id, &it.attrs, |builder| {
65             intravisit::walk_item(builder, it);
66         });
67     }
68
69     fn visit_foreign_item(&mut self, it: &'tcx hir::ForeignItem<'tcx>) {
70         self.with_lint_attrs(it.hir_id, &it.attrs, |builder| {
71             intravisit::walk_foreign_item(builder, it);
72         })
73     }
74
75     fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
76         self.with_lint_attrs(e.hir_id, &e.attrs, |builder| {
77             intravisit::walk_expr(builder, e);
78         })
79     }
80
81     fn visit_struct_field(&mut self, s: &'tcx hir::StructField<'tcx>) {
82         self.with_lint_attrs(s.hir_id, &s.attrs, |builder| {
83             intravisit::walk_struct_field(builder, s);
84         })
85     }
86
87     fn visit_variant(
88         &mut self,
89         v: &'tcx hir::Variant<'tcx>,
90         g: &'tcx hir::Generics<'tcx>,
91         item_id: hir::HirId,
92     ) {
93         self.with_lint_attrs(v.id, &v.attrs, |builder| {
94             intravisit::walk_variant(builder, v, g, item_id);
95         })
96     }
97
98     fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) {
99         self.with_lint_attrs(l.hir_id, &l.attrs, |builder| {
100             intravisit::walk_local(builder, l);
101         })
102     }
103
104     fn visit_arm(&mut self, a: &'tcx hir::Arm<'tcx>) {
105         self.with_lint_attrs(a.hir_id, &a.attrs, |builder| {
106             intravisit::walk_arm(builder, a);
107         })
108     }
109
110     fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
111         self.with_lint_attrs(trait_item.hir_id, &trait_item.attrs, |builder| {
112             intravisit::walk_trait_item(builder, trait_item);
113         });
114     }
115
116     fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
117         self.with_lint_attrs(impl_item.hir_id, &impl_item.attrs, |builder| {
118             intravisit::walk_impl_item(builder, impl_item);
119         });
120     }
121 }
122
123 pub fn provide(providers: &mut Providers<'_>) {
124     providers.lint_levels = lint_levels;
125 }