|
1 | 1 | use super::{contains_return, BIND_INSTEAD_OF_MAP}; |
2 | 2 | use crate::utils::{ |
3 | 3 | in_macro, match_qpath, match_type, method_calls, multispan_sugg_with_applicability, paths, remove_blocks, snippet, |
4 | | - snippet_with_macro_callsite, span_lint_and_sugg, span_lint_and_then, |
| 4 | + snippet_with_macro_callsite, span_lint_and_sugg, span_lint_and_then, visitors::find_all_ret_expressions, |
5 | 5 | }; |
6 | 6 | use if_chain::if_chain; |
7 | 7 | use rustc_errors::Applicability; |
8 | 8 | use rustc_hir as hir; |
9 | | -use rustc_hir::intravisit::{self, Visitor}; |
10 | 9 | use rustc_lint::LateContext; |
11 | | -use rustc_middle::hir::map::Map; |
12 | 10 | use rustc_span::Span; |
13 | 11 |
|
14 | 12 | pub(crate) struct OptionAndThenSome; |
@@ -193,124 +191,3 @@ pub(crate) trait BindInsteadOfMap { |
193 | 191 | } |
194 | 192 | } |
195 | 193 | } |
196 | | - |
197 | | -/// returns `true` if expr contains match expr desugared from try |
198 | | -fn contains_try(expr: &hir::Expr<'_>) -> bool { |
199 | | - struct TryFinder { |
200 | | - found: bool, |
201 | | - } |
202 | | - |
203 | | - impl<'hir> intravisit::Visitor<'hir> for TryFinder { |
204 | | - type Map = Map<'hir>; |
205 | | - |
206 | | - fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap<Self::Map> { |
207 | | - intravisit::NestedVisitorMap::None |
208 | | - } |
209 | | - |
210 | | - fn visit_expr(&mut self, expr: &'hir hir::Expr<'hir>) { |
211 | | - if self.found { |
212 | | - return; |
213 | | - } |
214 | | - match expr.kind { |
215 | | - hir::ExprKind::Match(_, _, hir::MatchSource::TryDesugar) => self.found = true, |
216 | | - _ => intravisit::walk_expr(self, expr), |
217 | | - } |
218 | | - } |
219 | | - } |
220 | | - |
221 | | - let mut visitor = TryFinder { found: false }; |
222 | | - visitor.visit_expr(expr); |
223 | | - visitor.found |
224 | | -} |
225 | | - |
226 | | -fn find_all_ret_expressions<'hir, F>(_cx: &LateContext<'_>, expr: &'hir hir::Expr<'hir>, callback: F) -> bool |
227 | | -where |
228 | | - F: FnMut(&'hir hir::Expr<'hir>) -> bool, |
229 | | -{ |
230 | | - struct RetFinder<F> { |
231 | | - in_stmt: bool, |
232 | | - failed: bool, |
233 | | - cb: F, |
234 | | - } |
235 | | - |
236 | | - struct WithStmtGuarg<'a, F> { |
237 | | - val: &'a mut RetFinder<F>, |
238 | | - prev_in_stmt: bool, |
239 | | - } |
240 | | - |
241 | | - impl<F> RetFinder<F> { |
242 | | - fn inside_stmt(&mut self, in_stmt: bool) -> WithStmtGuarg<'_, F> { |
243 | | - let prev_in_stmt = std::mem::replace(&mut self.in_stmt, in_stmt); |
244 | | - WithStmtGuarg { |
245 | | - val: self, |
246 | | - prev_in_stmt, |
247 | | - } |
248 | | - } |
249 | | - } |
250 | | - |
251 | | - impl<F> std::ops::Deref for WithStmtGuarg<'_, F> { |
252 | | - type Target = RetFinder<F>; |
253 | | - |
254 | | - fn deref(&self) -> &Self::Target { |
255 | | - self.val |
256 | | - } |
257 | | - } |
258 | | - |
259 | | - impl<F> std::ops::DerefMut for WithStmtGuarg<'_, F> { |
260 | | - fn deref_mut(&mut self) -> &mut Self::Target { |
261 | | - self.val |
262 | | - } |
263 | | - } |
264 | | - |
265 | | - impl<F> Drop for WithStmtGuarg<'_, F> { |
266 | | - fn drop(&mut self) { |
267 | | - self.val.in_stmt = self.prev_in_stmt; |
268 | | - } |
269 | | - } |
270 | | - |
271 | | - impl<'hir, F: FnMut(&'hir hir::Expr<'hir>) -> bool> intravisit::Visitor<'hir> for RetFinder<F> { |
272 | | - type Map = Map<'hir>; |
273 | | - |
274 | | - fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap<Self::Map> { |
275 | | - intravisit::NestedVisitorMap::None |
276 | | - } |
277 | | - |
278 | | - fn visit_stmt(&mut self, stmt: &'hir hir::Stmt<'_>) { |
279 | | - intravisit::walk_stmt(&mut *self.inside_stmt(true), stmt) |
280 | | - } |
281 | | - |
282 | | - fn visit_expr(&mut self, expr: &'hir hir::Expr<'_>) { |
283 | | - if self.failed { |
284 | | - return; |
285 | | - } |
286 | | - if self.in_stmt { |
287 | | - match expr.kind { |
288 | | - hir::ExprKind::Ret(Some(expr)) => self.inside_stmt(false).visit_expr(expr), |
289 | | - _ => intravisit::walk_expr(self, expr), |
290 | | - } |
291 | | - } else { |
292 | | - match expr.kind { |
293 | | - hir::ExprKind::Match(cond, arms, _) => { |
294 | | - self.inside_stmt(true).visit_expr(cond); |
295 | | - for arm in arms { |
296 | | - self.visit_expr(arm.body); |
297 | | - } |
298 | | - }, |
299 | | - hir::ExprKind::Block(..) => intravisit::walk_expr(self, expr), |
300 | | - hir::ExprKind::Ret(Some(expr)) => self.visit_expr(expr), |
301 | | - _ => self.failed |= !(self.cb)(expr), |
302 | | - } |
303 | | - } |
304 | | - } |
305 | | - } |
306 | | - |
307 | | - !contains_try(expr) && { |
308 | | - let mut ret_finder = RetFinder { |
309 | | - in_stmt: false, |
310 | | - failed: false, |
311 | | - cb: callback, |
312 | | - }; |
313 | | - ret_finder.visit_expr(expr); |
314 | | - !ret_finder.failed |
315 | | - } |
316 | | -} |
0 commit comments