3 use rustc
::hir
::intravisit
::{walk_expr, walk_fn, FnKind, NestedVisitorMap, Visitor}
;
4 use std
::collections
::HashMap
;
6 use syntax
::codemap
::Span
;
7 use syntax
::symbol
::InternedString
;
8 use utils
::{in_macro, span_lint}
;
10 /// **What it does:** Checks for unused labels.
12 /// **Why is this bad?** Maybe the label should be used in which case there is
13 /// an error in the code or it should be removed.
15 /// **Known problems:** Hopefully none.
19 /// fn unused_label() {
20 /// 'label: for i in 1..2 {
21 /// if i > 4 { continue }
30 pub struct UnusedLabel
;
32 struct UnusedLabelVisitor
<'a
, 'tcx
: 'a
> {
33 labels
: HashMap
<InternedString
, Span
>,
34 cx
: &'a LateContext
<'a
, 'tcx
>,
37 impl LintPass
for UnusedLabel
{
38 fn get_lints(&self) -> LintArray
{
39 lint_array
!(UNUSED_LABEL
)
43 impl<'a
, 'tcx
> LateLintPass
<'a
, 'tcx
> for UnusedLabel
{
46 cx
: &LateContext
<'a
, 'tcx
>,
48 decl
: &'tcx hir
::FnDecl
,
49 body
: &'tcx hir
::Body
,
57 let mut v
= UnusedLabelVisitor
{
59 labels
: HashMap
::new(),
61 walk_fn(&mut v
, kind
, decl
, body
.id(), span
, fn_id
);
63 for (label
, span
) in v
.labels
{
64 span_lint(cx
, UNUSED_LABEL
, span
, &format
!("unused label `{}`", label
));
69 impl<'a
, 'tcx
: 'a
> Visitor
<'tcx
> for UnusedLabelVisitor
<'a
, 'tcx
> {
70 fn visit_expr(&mut self, expr
: &'tcx hir
::Expr
) {
72 hir
::ExprBreak(destination
, _
) | hir
::ExprAgain(destination
) => if let Some(label
) = destination
.ident
{
73 self.labels
.remove(&label
.node
.name
.as_str());
75 hir
::ExprLoop(_
, Some(label
), _
) | hir
::ExprWhile(_
, _
, Some(label
)) => {
76 self.labels
.insert(label
.node
.as_str(), expr
.span
);
81 walk_expr(self, expr
);
83 fn nested_visit_map
<'this
>(&'this
mut self) -> NestedVisitorMap
<'this
, 'tcx
> {
84 NestedVisitorMap
::All(&self.cx
.tcx
.hir
)