|
1 | 1 | use rustc_hir as hir;
|
2 |
| -use rustc_hir::intravisit::{self, Visitor}; |
| 2 | +use rustc_hir::def::Res; |
| 3 | +use rustc_hir::intravisit::{self, walk_expr, NestedVisitorMap, Visitor}; |
| 4 | +use rustc_hir::{Arm, Expr, ExprKind, HirId, QPath, Stmt}; |
3 | 5 | use rustc_lint::LateContext;
|
4 | 6 | use rustc_middle::hir::map::Map;
|
5 | 7 |
|
@@ -123,3 +125,54 @@ where
|
123 | 125 | !ret_finder.failed
|
124 | 126 | }
|
125 | 127 | }
|
| 128 | + |
| 129 | +pub struct LocalUsedVisitor { |
| 130 | + pub local_hir_id: HirId, |
| 131 | + pub used: bool, |
| 132 | +} |
| 133 | + |
| 134 | +impl LocalUsedVisitor { |
| 135 | + pub fn new(local_hir_id: HirId) -> Self { |
| 136 | + Self { |
| 137 | + local_hir_id, |
| 138 | + used: false, |
| 139 | + } |
| 140 | + } |
| 141 | + |
| 142 | + fn check<T>(&mut self, t: T, visit: fn(&mut Self, T)) -> bool { |
| 143 | + visit(self, t); |
| 144 | + std::mem::replace(&mut self.used, false) |
| 145 | + } |
| 146 | + |
| 147 | + pub fn check_arm(&mut self, arm: &Arm<'_>) -> bool { |
| 148 | + self.check(arm, Self::visit_arm) |
| 149 | + } |
| 150 | + |
| 151 | + pub fn check_expr(&mut self, expr: &Expr<'_>) -> bool { |
| 152 | + self.check(expr, Self::visit_expr) |
| 153 | + } |
| 154 | + |
| 155 | + pub fn check_stmt(&mut self, stmt: &Stmt<'_>) -> bool { |
| 156 | + self.check(stmt, Self::visit_stmt) |
| 157 | + } |
| 158 | +} |
| 159 | + |
| 160 | +impl<'v> Visitor<'v> for LocalUsedVisitor { |
| 161 | + type Map = Map<'v>; |
| 162 | + |
| 163 | + fn visit_expr(&mut self, expr: &'v Expr<'v>) { |
| 164 | + if let ExprKind::Path(QPath::Resolved(None, path)) = expr.kind { |
| 165 | + if let Res::Local(id) = path.res { |
| 166 | + if id == self.local_hir_id { |
| 167 | + self.used = true; |
| 168 | + return; |
| 169 | + } |
| 170 | + } |
| 171 | + } |
| 172 | + walk_expr(self, expr); |
| 173 | + } |
| 174 | + |
| 175 | + fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> { |
| 176 | + NestedVisitorMap::None |
| 177 | + } |
| 178 | +} |
0 commit comments