Skip to content

Commit b322462

Browse files
committed
Fix lint attributes on non-item nodes.
Currently, late lint checking uses two HIR visitors: LateContext and IdVisitor. IdVisitor only overrides visit_id, and for each node searches for builtin lints previously added to the session; LateContext overrides a number of methods, and runs late lints. When LateContext encounters an item, it first has IdVisitor walk everything in it except nested items (OnlyBodies), then recurses into it itself - i.e. there are two separate walks. Aside from apparently being unnecessary, this separation prevents lint attributes (allow/deny/warn) on non-item HIR nodes from working properly. Test case: // generates warning without this change fn main() { #[allow(unreachable_code)] loop { break; break; } } LateContext contains logic to merge attributes seen into the current lint settings while walking (with_lint_attrs), but IdVisitor does not. So such attributes will affect late lints (because they are called from LateContext), and if the node contains any items within it, they will affect builtin lints within those items (because that IdVisitor is run while LateContext is within the attributed node), but otherwise the attributes will be ignored for builtin lints. This change simply removes IdVisitor and moves its visit_id into LateContext itself. Hopefully this doesn't break anything... Also added walk calls to visit_lifetime and visit_lifetime_def respectively, so visit_lifetime_def will recurse into the lifetime and visit_lifetime will recurse into the name. In principle this could confuse lint plugins. This is "necessary" because walk_lifetime calls visit_id on the lifetime; of course, an alternative would be directly calling visit_id (which would require manually iterating over the lifetimes in visit_lifetime_def), but that seems less clean.
1 parent 8f62c29 commit b322462

File tree

2 files changed

+13
-46
lines changed

2 files changed

+13
-46
lines changed

src/librustc/lint/context.rs

Lines changed: 12 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -718,15 +718,6 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> {
718718
level_stack: vec![],
719719
}
720720
}
721-
722-
fn visit_ids<'b, F: 'b>(&'b mut self, f: F)
723-
where F: FnOnce(&mut IdVisitor<'b, 'a, 'tcx>)
724-
{
725-
let mut v = IdVisitor::<'b, 'a, 'tcx> {
726-
cx: self
727-
};
728-
f(&mut v);
729-
}
730721
}
731722

732723
impl<'a, 'tcx> LintContext<'tcx> for LateContext<'a, 'tcx> {
@@ -795,10 +786,19 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
795786
hir_visit::NestedVisitorMap::All(&self.tcx.map)
796787
}
797788

789+
// Output any lints that were previously added to the session.
790+
fn visit_id(&mut self, id: ast::NodeId) {
791+
if let Some(lints) = self.sess().lints.borrow_mut().remove(&id) {
792+
debug!("LateContext::visit_id: id={:?} lints={:?}", id, lints);
793+
for early_lint in lints {
794+
self.early_lint(early_lint);
795+
}
796+
}
797+
}
798+
798799
fn visit_item(&mut self, it: &'tcx hir::Item) {
799800
self.with_lint_attrs(&it.attrs, |cx| {
800801
run_lints!(cx, check_item, late_passes, it);
801-
cx.visit_ids(|v| v.visit_item(it));
802802
hir_visit::walk_item(cx, it);
803803
run_lints!(cx, check_item_post, late_passes, it);
804804
})
@@ -918,7 +918,6 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
918918
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
919919
self.with_lint_attrs(&trait_item.attrs, |cx| {
920920
run_lints!(cx, check_trait_item, late_passes, trait_item);
921-
cx.visit_ids(|v| hir_visit::walk_trait_item(v, trait_item));
922921
hir_visit::walk_trait_item(cx, trait_item);
923922
run_lints!(cx, check_trait_item_post, late_passes, trait_item);
924923
});
@@ -927,18 +926,19 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
927926
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
928927
self.with_lint_attrs(&impl_item.attrs, |cx| {
929928
run_lints!(cx, check_impl_item, late_passes, impl_item);
930-
cx.visit_ids(|v| hir_visit::walk_impl_item(v, impl_item));
931929
hir_visit::walk_impl_item(cx, impl_item);
932930
run_lints!(cx, check_impl_item_post, late_passes, impl_item);
933931
});
934932
}
935933

936934
fn visit_lifetime(&mut self, lt: &'tcx hir::Lifetime) {
937935
run_lints!(self, check_lifetime, late_passes, lt);
936+
hir_visit::walk_lifetime(self, lt);
938937
}
939938

940939
fn visit_lifetime_def(&mut self, lt: &'tcx hir::LifetimeDef) {
941940
run_lints!(self, check_lifetime_def, late_passes, lt);
941+
hir_visit::walk_lifetime_def(self, lt);
942942
}
943943

944944
fn visit_path(&mut self, p: &'tcx hir::Path, id: ast::NodeId) {
@@ -1100,35 +1100,6 @@ impl<'a> ast_visit::Visitor<'a> for EarlyContext<'a> {
11001100
}
11011101
}
11021102

1103-
struct IdVisitor<'a, 'b: 'a, 'tcx: 'a+'b> {
1104-
cx: &'a mut LateContext<'b, 'tcx>
1105-
}
1106-
1107-
// Output any lints that were previously added to the session.
1108-
impl<'a, 'b, 'tcx> hir_visit::Visitor<'tcx> for IdVisitor<'a, 'b, 'tcx> {
1109-
fn nested_visit_map<'this>(&'this mut self) -> hir_visit::NestedVisitorMap<'this, 'tcx> {
1110-
hir_visit::NestedVisitorMap::OnlyBodies(&self.cx.tcx.map)
1111-
}
1112-
1113-
fn visit_id(&mut self, id: ast::NodeId) {
1114-
if let Some(lints) = self.cx.sess().lints.borrow_mut().remove(&id) {
1115-
debug!("LateContext::visit_id: id={:?} lints={:?}", id, lints);
1116-
for early_lint in lints {
1117-
self.cx.early_lint(early_lint);
1118-
}
1119-
}
1120-
}
1121-
1122-
fn visit_trait_item(&mut self, _ti: &'tcx hir::TraitItem) {
1123-
// Do not recurse into trait or impl items automatically. These are
1124-
// processed separately by calling hir_visit::walk_trait_item()
1125-
}
1126-
1127-
fn visit_impl_item(&mut self, _ii: &'tcx hir::ImplItem) {
1128-
// See visit_trait_item()
1129-
}
1130-
}
1131-
11321103
enum CheckLintNameResult {
11331104
Ok,
11341105
// Lint doesn't exist
@@ -1242,10 +1213,6 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
12421213

12431214
// Visit the whole crate.
12441215
cx.with_lint_attrs(&krate.attrs, |cx| {
1245-
cx.visit_ids(|v| {
1246-
hir_visit::walk_crate(v, krate);
1247-
});
1248-
12491216
// since the root module isn't visited as an item (because it isn't an
12501217
// item), warn for it here.
12511218
run_lints!(cx, check_crate, late_passes, krate);

src/llvm

Submodule llvm updated 155 files

0 commit comments

Comments
 (0)