|
1 | 1 | #![feature(box_patterns)] |
2 | 2 | #![feature(in_band_lifetimes)] |
3 | 3 | #![feature(iter_zip)] |
| 4 | +#![feature(let_else)] |
4 | 5 | #![feature(rustc_private)] |
5 | 6 | #![feature(control_flow_enum)] |
6 | 7 | #![recursion_limit = "512"] |
@@ -68,7 +69,7 @@ use rustc_hir as hir; |
68 | 69 | use rustc_hir::def::{DefKind, Res}; |
69 | 70 | use rustc_hir::def_id::DefId; |
70 | 71 | use rustc_hir::hir_id::{HirIdMap, HirIdSet}; |
71 | | -use rustc_hir::intravisit::{self, walk_expr, ErasedMap, FnKind, NestedVisitorMap, Visitor}; |
| 72 | +use rustc_hir::intravisit::{walk_expr, ErasedMap, FnKind, NestedVisitorMap, Visitor}; |
72 | 73 | use rustc_hir::itemlikevisit::ItemLikeVisitor; |
73 | 74 | use rustc_hir::LangItem::{OptionNone, ResultErr, ResultOk}; |
74 | 75 | use rustc_hir::{ |
@@ -96,6 +97,7 @@ use rustc_target::abi::Integer; |
96 | 97 |
|
97 | 98 | use crate::consts::{constant, Constant}; |
98 | 99 | use crate::ty::{can_partially_move_ty, is_copy, is_recursively_primitive_type}; |
| 100 | +use crate::visitors::expr_visitor_no_bodies; |
99 | 101 |
|
100 | 102 | pub fn parse_msrv(msrv: &str, sess: Option<&Session>, span: Option<Span>) -> Option<RustcVersion> { |
101 | 103 | if let Ok(version) = RustcVersion::parse(msrv) { |
@@ -1107,63 +1109,30 @@ pub fn contains_name(name: Symbol, expr: &Expr<'_>) -> bool { |
1107 | 1109 |
|
1108 | 1110 | /// Returns `true` if `expr` contains a return expression |
1109 | 1111 | pub fn contains_return(expr: &hir::Expr<'_>) -> bool { |
1110 | | - struct RetCallFinder { |
1111 | | - found: bool, |
1112 | | - } |
1113 | | - |
1114 | | - impl<'tcx> hir::intravisit::Visitor<'tcx> for RetCallFinder { |
1115 | | - type Map = Map<'tcx>; |
1116 | | - |
1117 | | - fn visit_expr(&mut self, expr: &'tcx hir::Expr<'_>) { |
1118 | | - if self.found { |
1119 | | - return; |
1120 | | - } |
| 1112 | + let mut found = false; |
| 1113 | + expr_visitor_no_bodies(|expr| { |
| 1114 | + if !found { |
1121 | 1115 | if let hir::ExprKind::Ret(..) = &expr.kind { |
1122 | | - self.found = true; |
1123 | | - } else { |
1124 | | - hir::intravisit::walk_expr(self, expr); |
| 1116 | + found = true; |
1125 | 1117 | } |
1126 | 1118 | } |
1127 | | - |
1128 | | - fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<Self::Map> { |
1129 | | - hir::intravisit::NestedVisitorMap::None |
1130 | | - } |
1131 | | - } |
1132 | | - |
1133 | | - let mut visitor = RetCallFinder { found: false }; |
1134 | | - visitor.visit_expr(expr); |
1135 | | - visitor.found |
1136 | | -} |
1137 | | - |
1138 | | -struct FindMacroCalls<'a, 'b> { |
1139 | | - names: &'a [&'b str], |
1140 | | - result: Vec<Span>, |
1141 | | -} |
1142 | | - |
1143 | | -impl<'a, 'b, 'tcx> Visitor<'tcx> for FindMacroCalls<'a, 'b> { |
1144 | | - type Map = Map<'tcx>; |
1145 | | - |
1146 | | - fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { |
1147 | | - if self.names.iter().any(|fun| is_expn_of(expr.span, fun).is_some()) { |
1148 | | - self.result.push(expr.span); |
1149 | | - } |
1150 | | - // and check sub-expressions |
1151 | | - intravisit::walk_expr(self, expr); |
1152 | | - } |
1153 | | - |
1154 | | - fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> { |
1155 | | - NestedVisitorMap::None |
1156 | | - } |
| 1119 | + !found |
| 1120 | + }) |
| 1121 | + .visit_expr(expr); |
| 1122 | + found |
1157 | 1123 | } |
1158 | 1124 |
|
1159 | 1125 | /// Finds calls of the specified macros in a function body. |
1160 | 1126 | pub fn find_macro_calls(names: &[&str], body: &Body<'_>) -> Vec<Span> { |
1161 | | - let mut fmc = FindMacroCalls { |
1162 | | - names, |
1163 | | - result: Vec::new(), |
1164 | | - }; |
1165 | | - fmc.visit_expr(&body.value); |
1166 | | - fmc.result |
| 1127 | + let mut result = Vec::new(); |
| 1128 | + expr_visitor_no_bodies(|expr| { |
| 1129 | + if names.iter().any(|fun| is_expn_of(expr.span, fun).is_some()) { |
| 1130 | + result.push(expr.span); |
| 1131 | + } |
| 1132 | + true |
| 1133 | + }) |
| 1134 | + .visit_expr(&body.value); |
| 1135 | + result |
1167 | 1136 | } |
1168 | 1137 |
|
1169 | 1138 | /// Extends the span to the beginning of the spans line, incl. whitespaces. |
|
0 commit comments