]>
Commit | Line | Data |
---|---|---|
e1599b0c XL |
1 | //! A `MutVisitor` represents an AST modification; it accepts an AST piece and |
2 | //! and mutates it in place. So, for instance, macro expansion is a `MutVisitor` | |
9fa01778 XL |
3 | //! that walks over an AST and modifies it. |
4 | //! | |
e1599b0c | 5 | //! Note: using a `MutVisitor` (other than the `MacroExpander` `MutVisitor`) on |
9fa01778 | 6 | //! an AST before macro expansion is probably a bad idea. For instance, |
e1599b0c | 7 | //! a `MutVisitor` renaming item names in a module will miss all of those |
9fa01778 XL |
8 | //! that are created by the expansion of a macro. |
9 | ||
10 | use crate::ast::*; | |
9fa01778 | 11 | use crate::ptr::P; |
dfeec247 | 12 | use crate::token::{self, Token}; |
9fa01778 | 13 | use crate::tokenstream::*; |
9fa01778 | 14 | |
ba9703b0 | 15 | use rustc_data_structures::map_in_place::MapInPlace; |
9fa01778 | 16 | use rustc_data_structures::sync::Lrc; |
1b1a35ee | 17 | use rustc_span::source_map::Spanned; |
f9f354fc | 18 | use rustc_span::symbol::Ident; |
dfeec247 XL |
19 | use rustc_span::Span; |
20 | ||
21 | use smallvec::{smallvec, Array, SmallVec}; | |
9fa01778 | 22 | use std::ops::DerefMut; |
532ac7d7 | 23 | use std::{panic, process, ptr}; |
9fa01778 XL |
24 | |
25 | pub trait ExpectOne<A: Array> { | |
26 | fn expect_one(self, err: &'static str) -> A::Item; | |
27 | } | |
28 | ||
29 | impl<A: Array> ExpectOne<A> for SmallVec<A> { | |
30 | fn expect_one(self, err: &'static str) -> A::Item { | |
5869c6ff | 31 | assert!(self.len() == 1, "{}", err); |
9fa01778 XL |
32 | self.into_iter().next().unwrap() |
33 | } | |
34 | } | |
35 | ||
36 | pub trait MutVisitor: Sized { | |
29967ef6 XL |
37 | /// Mutable token visiting only exists for the `macro_rules` token marker and should not be |
38 | /// used otherwise. Token visitor would be entirely separate from the regular visitor if | |
39 | /// the marker didn't have to visit AST fragments in nonterminal tokens. | |
40 | fn token_visiting_enabled(&self) -> bool { | |
41 | false | |
42 | } | |
43 | ||
9fa01778 XL |
44 | // Methods in this trait have one of three forms: |
45 | // | |
46 | // fn visit_t(&mut self, t: &mut T); // common | |
47 | // fn flat_map_t(&mut self, t: T) -> SmallVec<[T; 1]>; // rare | |
48 | // fn filter_map_t(&mut self, t: T) -> Option<T>; // rarest | |
49 | // | |
50 | // Any additions to this trait should happen in form of a call to a public | |
51 | // `noop_*` function that only calls out to the visitor again, not other | |
52 | // `noop_*` functions. This is a necessary API workaround to the problem of | |
53 | // not being able to call out to the super default method in an overridden | |
54 | // default method. | |
55 | // | |
56 | // When writing these methods, it is better to use destructuring like this: | |
57 | // | |
58 | // fn visit_abc(&mut self, ABC { a, b, c: _ }: &mut ABC) { | |
59 | // visit_a(a); | |
60 | // visit_b(b); | |
61 | // } | |
62 | // | |
63 | // than to use field access like this: | |
64 | // | |
65 | // fn visit_abc(&mut self, abc: &mut ABC) { | |
66 | // visit_a(&mut abc.a); | |
67 | // visit_b(&mut abc.b); | |
68 | // // ignore abc.c | |
69 | // } | |
70 | // | |
71 | // As well as being more concise, the former is explicit about which fields | |
72 | // are skipped. Furthermore, if a new field is added, the destructuring | |
73 | // version will cause a compile error, which is good. In comparison, the | |
74 | // field access version will continue working and it would be easy to | |
75 | // forget to add handling for it. | |
76 | ||
77 | fn visit_crate(&mut self, c: &mut Crate) { | |
78 | noop_visit_crate(c, self) | |
79 | } | |
80 | ||
81 | fn visit_meta_list_item(&mut self, list_item: &mut NestedMetaItem) { | |
82 | noop_visit_meta_list_item(list_item, self); | |
83 | } | |
84 | ||
85 | fn visit_meta_item(&mut self, meta_item: &mut MetaItem) { | |
86 | noop_visit_meta_item(meta_item, self); | |
87 | } | |
88 | ||
89 | fn visit_use_tree(&mut self, use_tree: &mut UseTree) { | |
90 | noop_visit_use_tree(use_tree, self); | |
91 | } | |
92 | ||
74b04a01 | 93 | fn flat_map_foreign_item(&mut self, ni: P<ForeignItem>) -> SmallVec<[P<ForeignItem>; 1]> { |
9fa01778 XL |
94 | noop_flat_map_foreign_item(ni, self) |
95 | } | |
96 | ||
97 | fn flat_map_item(&mut self, i: P<Item>) -> SmallVec<[P<Item>; 1]> { | |
98 | noop_flat_map_item(i, self) | |
99 | } | |
100 | ||
101 | fn visit_fn_header(&mut self, header: &mut FnHeader) { | |
102 | noop_visit_fn_header(header, self); | |
103 | } | |
104 | ||
6a06907d XL |
105 | fn flat_map_field_def(&mut self, fd: FieldDef) -> SmallVec<[FieldDef; 1]> { |
106 | noop_flat_map_field_def(fd, self) | |
9fa01778 XL |
107 | } |
108 | ||
109 | fn visit_item_kind(&mut self, i: &mut ItemKind) { | |
110 | noop_visit_item_kind(i, self); | |
111 | } | |
112 | ||
74b04a01 | 113 | fn flat_map_trait_item(&mut self, i: P<AssocItem>) -> SmallVec<[P<AssocItem>; 1]> { |
dfeec247 | 114 | noop_flat_map_assoc_item(i, self) |
9fa01778 XL |
115 | } |
116 | ||
74b04a01 | 117 | fn flat_map_impl_item(&mut self, i: P<AssocItem>) -> SmallVec<[P<AssocItem>; 1]> { |
dfeec247 | 118 | noop_flat_map_assoc_item(i, self) |
9fa01778 XL |
119 | } |
120 | ||
121 | fn visit_fn_decl(&mut self, d: &mut P<FnDecl>) { | |
122 | noop_visit_fn_decl(d, self); | |
123 | } | |
124 | ||
74b04a01 | 125 | fn visit_asyncness(&mut self, a: &mut Async) { |
9fa01778 XL |
126 | noop_visit_asyncness(a, self); |
127 | } | |
128 | ||
129 | fn visit_block(&mut self, b: &mut P<Block>) { | |
130 | noop_visit_block(b, self); | |
131 | } | |
132 | ||
133 | fn flat_map_stmt(&mut self, s: Stmt) -> SmallVec<[Stmt; 1]> { | |
134 | noop_flat_map_stmt(s, self) | |
135 | } | |
136 | ||
e1599b0c XL |
137 | fn flat_map_arm(&mut self, arm: Arm) -> SmallVec<[Arm; 1]> { |
138 | noop_flat_map_arm(arm, self) | |
9fa01778 XL |
139 | } |
140 | ||
9fa01778 XL |
141 | fn visit_pat(&mut self, p: &mut P<Pat>) { |
142 | noop_visit_pat(p, self); | |
143 | } | |
144 | ||
145 | fn visit_anon_const(&mut self, c: &mut AnonConst) { | |
146 | noop_visit_anon_const(c, self); | |
147 | } | |
148 | ||
149 | fn visit_expr(&mut self, e: &mut P<Expr>) { | |
150 | noop_visit_expr(e, self); | |
151 | } | |
152 | ||
153 | fn filter_map_expr(&mut self, e: P<Expr>) -> Option<P<Expr>> { | |
154 | noop_filter_map_expr(e, self) | |
155 | } | |
156 | ||
157 | fn visit_generic_arg(&mut self, arg: &mut GenericArg) { | |
158 | noop_visit_generic_arg(arg, self); | |
159 | } | |
160 | ||
161 | fn visit_ty(&mut self, t: &mut P<Ty>) { | |
162 | noop_visit_ty(t, self); | |
163 | } | |
164 | ||
165 | fn visit_lifetime(&mut self, l: &mut Lifetime) { | |
166 | noop_visit_lifetime(l, self); | |
167 | } | |
168 | ||
dc9dc135 XL |
169 | fn visit_ty_constraint(&mut self, t: &mut AssocTyConstraint) { |
170 | noop_visit_ty_constraint(t, self); | |
9fa01778 XL |
171 | } |
172 | ||
9fa01778 XL |
173 | fn visit_foreign_mod(&mut self, nm: &mut ForeignMod) { |
174 | noop_visit_foreign_mod(nm, self); | |
175 | } | |
176 | ||
dfeec247 | 177 | fn flat_map_variant(&mut self, v: Variant) -> SmallVec<[Variant; 1]> { |
e1599b0c | 178 | noop_flat_map_variant(v, self) |
9fa01778 XL |
179 | } |
180 | ||
181 | fn visit_ident(&mut self, i: &mut Ident) { | |
182 | noop_visit_ident(i, self); | |
183 | } | |
184 | ||
185 | fn visit_path(&mut self, p: &mut Path) { | |
186 | noop_visit_path(p, self); | |
187 | } | |
188 | ||
189 | fn visit_qself(&mut self, qs: &mut Option<QSelf>) { | |
190 | noop_visit_qself(qs, self); | |
191 | } | |
192 | ||
193 | fn visit_generic_args(&mut self, p: &mut GenericArgs) { | |
194 | noop_visit_generic_args(p, self); | |
195 | } | |
196 | ||
197 | fn visit_angle_bracketed_parameter_data(&mut self, p: &mut AngleBracketedArgs) { | |
198 | noop_visit_angle_bracketed_parameter_data(p, self); | |
199 | } | |
200 | ||
201 | fn visit_parenthesized_parameter_data(&mut self, p: &mut ParenthesizedArgs) { | |
202 | noop_visit_parenthesized_parameter_data(p, self); | |
203 | } | |
204 | ||
205 | fn visit_local(&mut self, l: &mut P<Local>) { | |
206 | noop_visit_local(l, self); | |
207 | } | |
208 | ||
29967ef6 XL |
209 | fn visit_mac_call(&mut self, mac: &mut MacCall) { |
210 | noop_visit_mac(mac, self); | |
9fa01778 XL |
211 | } |
212 | ||
213 | fn visit_macro_def(&mut self, def: &mut MacroDef) { | |
214 | noop_visit_macro_def(def, self); | |
215 | } | |
216 | ||
217 | fn visit_label(&mut self, label: &mut Label) { | |
218 | noop_visit_label(label, self); | |
219 | } | |
220 | ||
221 | fn visit_attribute(&mut self, at: &mut Attribute) { | |
222 | noop_visit_attribute(at, self); | |
223 | } | |
224 | ||
e1599b0c XL |
225 | fn flat_map_param(&mut self, param: Param) -> SmallVec<[Param; 1]> { |
226 | noop_flat_map_param(param, self) | |
9fa01778 XL |
227 | } |
228 | ||
229 | fn visit_generics(&mut self, generics: &mut Generics) { | |
230 | noop_visit_generics(generics, self); | |
231 | } | |
232 | ||
233 | fn visit_trait_ref(&mut self, tr: &mut TraitRef) { | |
234 | noop_visit_trait_ref(tr, self); | |
235 | } | |
236 | ||
237 | fn visit_poly_trait_ref(&mut self, p: &mut PolyTraitRef) { | |
238 | noop_visit_poly_trait_ref(p, self); | |
239 | } | |
240 | ||
241 | fn visit_variant_data(&mut self, vdata: &mut VariantData) { | |
242 | noop_visit_variant_data(vdata, self); | |
243 | } | |
244 | ||
e1599b0c XL |
245 | fn flat_map_generic_param(&mut self, param: GenericParam) -> SmallVec<[GenericParam; 1]> { |
246 | noop_flat_map_generic_param(param, self) | |
9fa01778 XL |
247 | } |
248 | ||
9fa01778 XL |
249 | fn visit_param_bound(&mut self, tpb: &mut GenericBound) { |
250 | noop_visit_param_bound(tpb, self); | |
251 | } | |
252 | ||
253 | fn visit_mt(&mut self, mt: &mut MutTy) { | |
254 | noop_visit_mt(mt, self); | |
255 | } | |
256 | ||
6a06907d XL |
257 | fn flat_map_expr_field(&mut self, f: ExprField) -> SmallVec<[ExprField; 1]> { |
258 | noop_flat_map_expr_field(f, self) | |
9fa01778 XL |
259 | } |
260 | ||
261 | fn visit_where_clause(&mut self, where_clause: &mut WhereClause) { | |
262 | noop_visit_where_clause(where_clause, self); | |
263 | } | |
264 | ||
265 | fn visit_where_predicate(&mut self, where_predicate: &mut WherePredicate) { | |
266 | noop_visit_where_predicate(where_predicate, self); | |
267 | } | |
268 | ||
269 | fn visit_vis(&mut self, vis: &mut Visibility) { | |
270 | noop_visit_vis(vis, self); | |
271 | } | |
272 | ||
273 | fn visit_id(&mut self, _id: &mut NodeId) { | |
274 | // Do nothing. | |
275 | } | |
276 | ||
277 | fn visit_span(&mut self, _sp: &mut Span) { | |
278 | // Do nothing. | |
279 | } | |
e1599b0c | 280 | |
6a06907d XL |
281 | fn flat_map_pat_field(&mut self, fp: PatField) -> SmallVec<[PatField; 1]> { |
282 | noop_flat_map_pat_field(fp, self) | |
e1599b0c | 283 | } |
9fa01778 XL |
284 | } |
285 | ||
286 | /// Use a map-style function (`FnOnce(T) -> T`) to overwrite a `&mut T`. Useful | |
287 | /// when using a `flat_map_*` or `filter_map_*` method within a `visit_` | |
532ac7d7 | 288 | /// method. Abort the program if the closure panics. |
9fa01778 XL |
289 | // |
290 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
dfeec247 XL |
291 | pub fn visit_clobber<T, F>(t: &mut T, f: F) |
292 | where | |
293 | F: FnOnce(T) -> T, | |
294 | { | |
532ac7d7 XL |
295 | unsafe { |
296 | // Safe because `t` is used in a read-only fashion by `read()` before | |
297 | // being overwritten by `write()`. | |
298 | let old_t = ptr::read(t); | |
299 | let new_t = panic::catch_unwind(panic::AssertUnwindSafe(|| f(old_t))) | |
300 | .unwrap_or_else(|_| process::abort()); | |
301 | ptr::write(t, new_t); | |
302 | } | |
9fa01778 XL |
303 | } |
304 | ||
305 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
306 | #[inline] | |
dfeec247 XL |
307 | pub fn visit_vec<T, F>(elems: &mut Vec<T>, mut visit_elem: F) |
308 | where | |
309 | F: FnMut(&mut T), | |
310 | { | |
9fa01778 XL |
311 | for elem in elems { |
312 | visit_elem(elem); | |
313 | } | |
314 | } | |
315 | ||
316 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
317 | #[inline] | |
dfeec247 XL |
318 | pub fn visit_opt<T, F>(opt: &mut Option<T>, mut visit_elem: F) |
319 | where | |
320 | F: FnMut(&mut T), | |
321 | { | |
9fa01778 XL |
322 | if let Some(elem) = opt { |
323 | visit_elem(elem); | |
324 | } | |
325 | } | |
326 | ||
327 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
328 | pub fn visit_attrs<T: MutVisitor>(attrs: &mut Vec<Attribute>, vis: &mut T) { | |
329 | visit_vec(attrs, |attr| vis.visit_attribute(attr)); | |
330 | } | |
331 | ||
332 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
dfeec247 | 333 | pub fn visit_thin_attrs<T: MutVisitor>(attrs: &mut AttrVec, vis: &mut T) { |
9fa01778 XL |
334 | for attr in attrs.iter_mut() { |
335 | vis.visit_attribute(attr); | |
336 | } | |
337 | } | |
338 | ||
339 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
340 | pub fn visit_exprs<T: MutVisitor>(exprs: &mut Vec<P<Expr>>, vis: &mut T) { | |
341 | exprs.flat_map_in_place(|expr| vis.filter_map_expr(expr)) | |
342 | } | |
343 | ||
344 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
345 | pub fn visit_bounds<T: MutVisitor>(bounds: &mut GenericBounds, vis: &mut T) { | |
346 | visit_vec(bounds, |bound| vis.visit_param_bound(bound)); | |
347 | } | |
348 | ||
349 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
3dfed10e | 350 | pub fn visit_fn_sig<T: MutVisitor>(FnSig { header, decl, span }: &mut FnSig, vis: &mut T) { |
9fa01778 XL |
351 | vis.visit_fn_header(header); |
352 | vis.visit_fn_decl(decl); | |
3dfed10e | 353 | vis.visit_span(span); |
9fa01778 XL |
354 | } |
355 | ||
60c5eb7d XL |
356 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. |
357 | pub fn visit_mac_args<T: MutVisitor>(args: &mut MacArgs, vis: &mut T) { | |
358 | match args { | |
359 | MacArgs::Empty => {} | |
360 | MacArgs::Delimited(dspan, _delim, tokens) => { | |
361 | visit_delim_span(dspan, vis); | |
29967ef6 | 362 | visit_tts(tokens, vis); |
60c5eb7d | 363 | } |
5869c6ff | 364 | MacArgs::Eq(eq_span, token) => { |
60c5eb7d | 365 | vis.visit_span(eq_span); |
5869c6ff XL |
366 | if vis.token_visiting_enabled() { |
367 | visit_token(token, vis); | |
368 | } else { | |
369 | // The value in `#[key = VALUE]` must be visited as an expression for backward | |
370 | // compatibility, so that macros can be expanded in that position. | |
371 | match &mut token.kind { | |
372 | token::Interpolated(nt) => match Lrc::make_mut(nt) { | |
373 | token::NtExpr(expr) => vis.visit_expr(expr), | |
fc512014 XL |
374 | t => panic!("unexpected token in key-value attribute: {:?}", t), |
375 | }, | |
376 | t => panic!("unexpected token in key-value attribute: {:?}", t), | |
29967ef6 XL |
377 | } |
378 | } | |
60c5eb7d XL |
379 | } |
380 | } | |
381 | } | |
382 | ||
383 | pub fn visit_delim_span<T: MutVisitor>(dspan: &mut DelimSpan, vis: &mut T) { | |
384 | vis.visit_span(&mut dspan.open); | |
385 | vis.visit_span(&mut dspan.close); | |
386 | } | |
387 | ||
6a06907d XL |
388 | pub fn noop_flat_map_pat_field<T: MutVisitor>( |
389 | mut fp: PatField, | |
e1599b0c | 390 | vis: &mut T, |
6a06907d XL |
391 | ) -> SmallVec<[PatField; 1]> { |
392 | let PatField { attrs, id, ident, is_placeholder: _, is_shorthand: _, pat, span } = &mut fp; | |
e1599b0c XL |
393 | vis.visit_id(id); |
394 | vis.visit_ident(ident); | |
395 | vis.visit_pat(pat); | |
396 | vis.visit_span(span); | |
397 | visit_thin_attrs(attrs, vis); | |
398 | smallvec![fp] | |
399 | } | |
400 | ||
9fa01778 XL |
401 | pub fn noop_visit_use_tree<T: MutVisitor>(use_tree: &mut UseTree, vis: &mut T) { |
402 | let UseTree { prefix, kind, span } = use_tree; | |
403 | vis.visit_path(prefix); | |
404 | match kind { | |
405 | UseTreeKind::Simple(rename, id1, id2) => { | |
406 | visit_opt(rename, |rename| vis.visit_ident(rename)); | |
407 | vis.visit_id(id1); | |
408 | vis.visit_id(id2); | |
409 | } | |
410 | UseTreeKind::Nested(items) => { | |
411 | for (tree, id) in items { | |
412 | vis.visit_use_tree(tree); | |
413 | vis.visit_id(id); | |
414 | } | |
415 | } | |
416 | UseTreeKind::Glob => {} | |
417 | } | |
418 | vis.visit_span(span); | |
419 | } | |
420 | ||
e1599b0c XL |
421 | pub fn noop_flat_map_arm<T: MutVisitor>(mut arm: Arm, vis: &mut T) -> SmallVec<[Arm; 1]> { |
422 | let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = &mut arm; | |
9fa01778 | 423 | visit_attrs(attrs, vis); |
e1599b0c XL |
424 | vis.visit_id(id); |
425 | vis.visit_pat(pat); | |
dc9dc135 | 426 | visit_opt(guard, |guard| vis.visit_expr(guard)); |
9fa01778 | 427 | vis.visit_expr(body); |
dc9dc135 | 428 | vis.visit_span(span); |
e1599b0c | 429 | smallvec![arm] |
9fa01778 XL |
430 | } |
431 | ||
dc9dc135 | 432 | pub fn noop_visit_ty_constraint<T: MutVisitor>( |
fc512014 | 433 | AssocTyConstraint { id, ident, gen_args, kind, span }: &mut AssocTyConstraint, |
dfeec247 | 434 | vis: &mut T, |
dc9dc135 | 435 | ) { |
9fa01778 XL |
436 | vis.visit_id(id); |
437 | vis.visit_ident(ident); | |
fc512014 XL |
438 | if let Some(ref mut gen_args) = gen_args { |
439 | vis.visit_generic_args(gen_args); | |
440 | } | |
dc9dc135 XL |
441 | match kind { |
442 | AssocTyConstraintKind::Equality { ref mut ty } => { | |
443 | vis.visit_ty(ty); | |
444 | } | |
445 | AssocTyConstraintKind::Bound { ref mut bounds } => { | |
446 | visit_bounds(bounds, vis); | |
447 | } | |
448 | } | |
9fa01778 XL |
449 | vis.visit_span(span); |
450 | } | |
451 | ||
452 | pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) { | |
29967ef6 | 453 | let Ty { id, kind, span, tokens } = ty.deref_mut(); |
9fa01778 | 454 | vis.visit_id(id); |
e74abb32 | 455 | match kind { |
dfeec247 | 456 | TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err | TyKind::Never | TyKind::CVarArgs => {} |
9fa01778 XL |
457 | TyKind::Slice(ty) => vis.visit_ty(ty), |
458 | TyKind::Ptr(mt) => vis.visit_mt(mt), | |
459 | TyKind::Rptr(lt, mt) => { | |
460 | visit_opt(lt, |lt| noop_visit_lifetime(lt, vis)); | |
461 | vis.visit_mt(mt); | |
462 | } | |
463 | TyKind::BareFn(bft) => { | |
60c5eb7d | 464 | let BareFnTy { unsafety: _, ext: _, generic_params, decl } = bft.deref_mut(); |
e1599b0c | 465 | generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); |
9fa01778 XL |
466 | vis.visit_fn_decl(decl); |
467 | } | |
468 | TyKind::Tup(tys) => visit_vec(tys, |ty| vis.visit_ty(ty)), | |
469 | TyKind::Paren(ty) => vis.visit_ty(ty), | |
470 | TyKind::Path(qself, path) => { | |
471 | vis.visit_qself(qself); | |
472 | vis.visit_path(path); | |
473 | } | |
474 | TyKind::Array(ty, length) => { | |
475 | vis.visit_ty(ty); | |
476 | vis.visit_anon_const(length); | |
477 | } | |
478 | TyKind::Typeof(expr) => vis.visit_anon_const(expr), | |
dfeec247 XL |
479 | TyKind::TraitObject(bounds, _syntax) => { |
480 | visit_vec(bounds, |bound| vis.visit_param_bound(bound)) | |
481 | } | |
9fa01778 XL |
482 | TyKind::ImplTrait(id, bounds) => { |
483 | vis.visit_id(id); | |
484 | visit_vec(bounds, |bound| vis.visit_param_bound(bound)); | |
485 | } | |
29967ef6 | 486 | TyKind::MacCall(mac) => vis.visit_mac_call(mac), |
9fa01778 XL |
487 | } |
488 | vis.visit_span(span); | |
29967ef6 | 489 | visit_lazy_tts(tokens, vis); |
9fa01778 XL |
490 | } |
491 | ||
492 | pub fn noop_visit_foreign_mod<T: MutVisitor>(foreign_mod: &mut ForeignMod, vis: &mut T) { | |
1b1a35ee | 493 | let ForeignMod { unsafety: _, abi: _, items } = foreign_mod; |
9fa01778 XL |
494 | items.flat_map_in_place(|item| vis.flat_map_foreign_item(item)); |
495 | } | |
496 | ||
dfeec247 XL |
497 | pub fn noop_flat_map_variant<T: MutVisitor>( |
498 | mut variant: Variant, | |
499 | visitor: &mut T, | |
500 | ) -> SmallVec<[Variant; 1]> { | |
60c5eb7d XL |
501 | let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = &mut variant; |
502 | visitor.visit_ident(ident); | |
503 | visitor.visit_vis(vis); | |
504 | visit_attrs(attrs, visitor); | |
505 | visitor.visit_id(id); | |
506 | visitor.visit_variant_data(data); | |
507 | visit_opt(disr_expr, |disr_expr| visitor.visit_anon_const(disr_expr)); | |
508 | visitor.visit_span(span); | |
e1599b0c | 509 | smallvec![variant] |
9fa01778 XL |
510 | } |
511 | ||
512 | pub fn noop_visit_ident<T: MutVisitor>(Ident { name: _, span }: &mut Ident, vis: &mut T) { | |
513 | vis.visit_span(span); | |
514 | } | |
515 | ||
29967ef6 | 516 | pub fn noop_visit_path<T: MutVisitor>(Path { segments, span, tokens }: &mut Path, vis: &mut T) { |
9fa01778 XL |
517 | vis.visit_span(span); |
518 | for PathSegment { ident, id, args } in segments { | |
519 | vis.visit_ident(ident); | |
520 | vis.visit_id(id); | |
521 | visit_opt(args, |args| vis.visit_generic_args(args)); | |
522 | } | |
29967ef6 | 523 | visit_lazy_tts(tokens, vis); |
9fa01778 XL |
524 | } |
525 | ||
526 | pub fn noop_visit_qself<T: MutVisitor>(qself: &mut Option<QSelf>, vis: &mut T) { | |
527 | visit_opt(qself, |QSelf { ty, path_span, position: _ }| { | |
528 | vis.visit_ty(ty); | |
529 | vis.visit_span(path_span); | |
530 | }) | |
531 | } | |
532 | ||
533 | pub fn noop_visit_generic_args<T: MutVisitor>(generic_args: &mut GenericArgs, vis: &mut T) { | |
534 | match generic_args { | |
535 | GenericArgs::AngleBracketed(data) => vis.visit_angle_bracketed_parameter_data(data), | |
536 | GenericArgs::Parenthesized(data) => vis.visit_parenthesized_parameter_data(data), | |
537 | } | |
538 | } | |
539 | ||
540 | pub fn noop_visit_generic_arg<T: MutVisitor>(arg: &mut GenericArg, vis: &mut T) { | |
541 | match arg { | |
542 | GenericArg::Lifetime(lt) => vis.visit_lifetime(lt), | |
543 | GenericArg::Type(ty) => vis.visit_ty(ty), | |
544 | GenericArg::Const(ct) => vis.visit_anon_const(ct), | |
545 | } | |
546 | } | |
547 | ||
dfeec247 XL |
548 | pub fn noop_visit_angle_bracketed_parameter_data<T: MutVisitor>( |
549 | data: &mut AngleBracketedArgs, | |
550 | vis: &mut T, | |
551 | ) { | |
ba9703b0 XL |
552 | let AngleBracketedArgs { args, span } = data; |
553 | visit_vec(args, |arg| match arg { | |
554 | AngleBracketedArg::Arg(arg) => vis.visit_generic_arg(arg), | |
555 | AngleBracketedArg::Constraint(constraint) => vis.visit_ty_constraint(constraint), | |
556 | }); | |
9fa01778 XL |
557 | vis.visit_span(span); |
558 | } | |
559 | ||
dfeec247 XL |
560 | pub fn noop_visit_parenthesized_parameter_data<T: MutVisitor>( |
561 | args: &mut ParenthesizedArgs, | |
562 | vis: &mut T, | |
563 | ) { | |
5869c6ff | 564 | let ParenthesizedArgs { inputs, output, span, .. } = args; |
9fa01778 | 565 | visit_vec(inputs, |input| vis.visit_ty(input)); |
dfeec247 | 566 | noop_visit_fn_ret_ty(output, vis); |
9fa01778 XL |
567 | vis.visit_span(span); |
568 | } | |
569 | ||
570 | pub fn noop_visit_local<T: MutVisitor>(local: &mut P<Local>, vis: &mut T) { | |
fc512014 | 571 | let Local { id, pat, ty, init, span, attrs, tokens } = local.deref_mut(); |
9fa01778 XL |
572 | vis.visit_id(id); |
573 | vis.visit_pat(pat); | |
574 | visit_opt(ty, |ty| vis.visit_ty(ty)); | |
575 | visit_opt(init, |init| vis.visit_expr(init)); | |
576 | vis.visit_span(span); | |
577 | visit_thin_attrs(attrs, vis); | |
fc512014 | 578 | visit_lazy_tts(tokens, vis); |
9fa01778 XL |
579 | } |
580 | ||
581 | pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) { | |
60c5eb7d XL |
582 | let Attribute { kind, id: _, style: _, span } = attr; |
583 | match kind { | |
29967ef6 | 584 | AttrKind::Normal(AttrItem { path, args, tokens }, attr_tokens) => { |
60c5eb7d XL |
585 | vis.visit_path(path); |
586 | visit_mac_args(args, vis); | |
29967ef6 XL |
587 | visit_lazy_tts(tokens, vis); |
588 | visit_lazy_tts(attr_tokens, vis); | |
60c5eb7d | 589 | } |
3dfed10e | 590 | AttrKind::DocComment(..) => {} |
60c5eb7d | 591 | } |
9fa01778 XL |
592 | vis.visit_span(span); |
593 | } | |
594 | ||
ba9703b0 XL |
595 | pub fn noop_visit_mac<T: MutVisitor>(mac: &mut MacCall, vis: &mut T) { |
596 | let MacCall { path, args, prior_type_ascription: _ } = mac; | |
9fa01778 | 597 | vis.visit_path(path); |
60c5eb7d | 598 | visit_mac_args(args, vis); |
9fa01778 XL |
599 | } |
600 | ||
601 | pub fn noop_visit_macro_def<T: MutVisitor>(macro_def: &mut MacroDef, vis: &mut T) { | |
ba9703b0 | 602 | let MacroDef { body, macro_rules: _ } = macro_def; |
60c5eb7d | 603 | visit_mac_args(body, vis); |
9fa01778 XL |
604 | } |
605 | ||
606 | pub fn noop_visit_meta_list_item<T: MutVisitor>(li: &mut NestedMetaItem, vis: &mut T) { | |
532ac7d7 XL |
607 | match li { |
608 | NestedMetaItem::MetaItem(mi) => vis.visit_meta_item(mi), | |
609 | NestedMetaItem::Literal(_lit) => {} | |
9fa01778 | 610 | } |
9fa01778 XL |
611 | } |
612 | ||
613 | pub fn noop_visit_meta_item<T: MutVisitor>(mi: &mut MetaItem, vis: &mut T) { | |
e74abb32 XL |
614 | let MetaItem { path: _, kind, span } = mi; |
615 | match kind { | |
9fa01778 XL |
616 | MetaItemKind::Word => {} |
617 | MetaItemKind::List(mis) => visit_vec(mis, |mi| vis.visit_meta_list_item(mi)), | |
618 | MetaItemKind::NameValue(_s) => {} | |
619 | } | |
620 | vis.visit_span(span); | |
621 | } | |
622 | ||
e1599b0c XL |
623 | pub fn noop_flat_map_param<T: MutVisitor>(mut param: Param, vis: &mut T) -> SmallVec<[Param; 1]> { |
624 | let Param { attrs, id, pat, span, ty, is_placeholder: _ } = &mut param; | |
9fa01778 | 625 | vis.visit_id(id); |
dc9dc135 | 626 | visit_thin_attrs(attrs, vis); |
9fa01778 | 627 | vis.visit_pat(pat); |
416331ca | 628 | vis.visit_span(span); |
9fa01778 | 629 | vis.visit_ty(ty); |
e1599b0c | 630 | smallvec![param] |
9fa01778 XL |
631 | } |
632 | ||
29967ef6 XL |
633 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. |
634 | pub fn visit_tt<T: MutVisitor>(tt: &mut TokenTree, vis: &mut T) { | |
9fa01778 | 635 | match tt { |
dc9dc135 | 636 | TokenTree::Token(token) => { |
29967ef6 | 637 | visit_token(token, vis); |
9fa01778 XL |
638 | } |
639 | TokenTree::Delimited(DelimSpan { open, close }, _delim, tts) => { | |
640 | vis.visit_span(open); | |
641 | vis.visit_span(close); | |
29967ef6 | 642 | visit_tts(tts, vis); |
9fa01778 XL |
643 | } |
644 | } | |
645 | } | |
646 | ||
29967ef6 XL |
647 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. |
648 | pub fn visit_tts<T: MutVisitor>(TokenStream(tts): &mut TokenStream, vis: &mut T) { | |
649 | if vis.token_visiting_enabled() && !tts.is_empty() { | |
650 | let tts = Lrc::make_mut(tts); | |
651 | visit_vec(tts, |(tree, _is_joint)| visit_tt(tree, vis)); | |
652 | } | |
653 | } | |
654 | ||
655 | pub fn visit_lazy_tts<T: MutVisitor>(lazy_tts: &mut Option<LazyTokenStream>, vis: &mut T) { | |
656 | if vis.token_visiting_enabled() { | |
657 | visit_opt(lazy_tts, |lazy_tts| { | |
658 | let mut tts = lazy_tts.create_token_stream(); | |
659 | visit_tts(&mut tts, vis); | |
660 | *lazy_tts = LazyTokenStream::new(tts); | |
661 | }) | |
662 | } | |
9fa01778 XL |
663 | } |
664 | ||
29967ef6 | 665 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. |
e1599b0c | 666 | // Applies ident visitor if it's an ident; applies other visits to interpolated nodes. |
dc9dc135 XL |
667 | // In practice the ident part is not actually used by specific visitors right now, |
668 | // but there's a test below checking that it works. | |
29967ef6 | 669 | pub fn visit_token<T: MutVisitor>(t: &mut Token, vis: &mut T) { |
dc9dc135 XL |
670 | let Token { kind, span } = t; |
671 | match kind { | |
672 | token::Ident(name, _) | token::Lifetime(name) => { | |
673 | let mut ident = Ident::new(*name, *span); | |
674 | vis.visit_ident(&mut ident); | |
675 | *name = ident.name; | |
676 | *span = ident.span; | |
e1599b0c | 677 | return; // Avoid visiting the span for the second time. |
dc9dc135 | 678 | } |
9fa01778 XL |
679 | token::Interpolated(nt) => { |
680 | let mut nt = Lrc::make_mut(nt); | |
29967ef6 | 681 | visit_interpolated(&mut nt, vis); |
9fa01778 XL |
682 | } |
683 | _ => {} | |
684 | } | |
dc9dc135 | 685 | vis.visit_span(span); |
9fa01778 XL |
686 | } |
687 | ||
29967ef6 | 688 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. |
e1599b0c | 689 | /// Applies the visitor to elements of interpolated nodes. |
9fa01778 XL |
690 | // |
691 | // N.B., this can occur only when applying a visitor to partially expanded | |
692 | // code, where parsed pieces have gotten implanted ito *other* macro | |
693 | // invocations. This is relevant for macro hygiene, but possibly not elsewhere. | |
694 | // | |
695 | // One problem here occurs because the types for flat_map_item, flat_map_stmt, | |
e1599b0c | 696 | // etc., allow the visitor to return *multiple* items; this is a problem for the |
9fa01778 XL |
697 | // nodes here, because they insist on having exactly one piece. One solution |
698 | // would be to mangle the MutVisitor trait to include one-to-many and | |
699 | // one-to-one versions of these entry points, but that would probably confuse a | |
700 | // lot of people and help very few. Instead, I'm just going to put in dynamic | |
701 | // checks. I think the performance impact of this will be pretty much | |
e1599b0c | 702 | // nonexistent. The danger is that someone will apply a `MutVisitor` to a |
9fa01778 | 703 | // partially expanded node, and will be confused by the fact that their |
e1599b0c | 704 | // `flat_map_item` or `flat_map_stmt` isn't getting called on `NtItem` or `NtStmt` |
9fa01778 XL |
705 | // nodes. Hopefully they'll wind up reading this comment, and doing something |
706 | // appropriate. | |
707 | // | |
e1599b0c | 708 | // BTW, design choice: I considered just changing the type of, e.g., `NtItem` to |
9fa01778 | 709 | // contain multiple items, but decided against it when I looked at |
e1599b0c | 710 | // `parse_item_or_view_item` and tried to figure out what I would do with |
9fa01778 | 711 | // multiple items there.... |
29967ef6 | 712 | pub fn visit_interpolated<T: MutVisitor>(nt: &mut token::Nonterminal, vis: &mut T) { |
9fa01778 | 713 | match nt { |
dfeec247 XL |
714 | token::NtItem(item) => visit_clobber(item, |item| { |
715 | // This is probably okay, because the only visitors likely to | |
716 | // peek inside interpolated nodes will be renamings/markings, | |
717 | // which map single items to single items. | |
718 | vis.flat_map_item(item).expect_one("expected visitor to produce exactly one item") | |
719 | }), | |
9fa01778 | 720 | token::NtBlock(block) => vis.visit_block(block), |
dfeec247 XL |
721 | token::NtStmt(stmt) => visit_clobber(stmt, |stmt| { |
722 | // See reasoning above. | |
723 | vis.flat_map_stmt(stmt).expect_one("expected visitor to produce exactly one item") | |
724 | }), | |
9fa01778 XL |
725 | token::NtPat(pat) => vis.visit_pat(pat), |
726 | token::NtExpr(expr) => vis.visit_expr(expr), | |
727 | token::NtTy(ty) => vis.visit_ty(ty), | |
728 | token::NtIdent(ident, _is_raw) => vis.visit_ident(ident), | |
729 | token::NtLifetime(ident) => vis.visit_ident(ident), | |
730 | token::NtLiteral(expr) => vis.visit_expr(expr), | |
74b04a01 | 731 | token::NtMeta(item) => { |
29967ef6 | 732 | let AttrItem { path, args, tokens } = item.deref_mut(); |
e74abb32 | 733 | vis.visit_path(path); |
60c5eb7d | 734 | visit_mac_args(args, vis); |
29967ef6 | 735 | visit_lazy_tts(tokens, vis); |
e74abb32 | 736 | } |
9fa01778 | 737 | token::NtPath(path) => vis.visit_path(path), |
29967ef6 | 738 | token::NtTT(tt) => visit_tt(tt, vis), |
9fa01778 | 739 | token::NtVis(visib) => vis.visit_vis(visib), |
9fa01778 XL |
740 | } |
741 | } | |
742 | ||
74b04a01 | 743 | pub fn noop_visit_asyncness<T: MutVisitor>(asyncness: &mut Async, vis: &mut T) { |
9fa01778 | 744 | match asyncness { |
74b04a01 | 745 | Async::Yes { span: _, closure_id, return_impl_trait_id } => { |
9fa01778 XL |
746 | vis.visit_id(closure_id); |
747 | vis.visit_id(return_impl_trait_id); | |
748 | } | |
74b04a01 | 749 | Async::No => {} |
9fa01778 XL |
750 | } |
751 | } | |
752 | ||
753 | pub fn noop_visit_fn_decl<T: MutVisitor>(decl: &mut P<FnDecl>, vis: &mut T) { | |
e74abb32 | 754 | let FnDecl { inputs, output } = decl.deref_mut(); |
e1599b0c | 755 | inputs.flat_map_in_place(|param| vis.flat_map_param(param)); |
dfeec247 XL |
756 | noop_visit_fn_ret_ty(output, vis); |
757 | } | |
758 | ||
74b04a01 | 759 | pub fn noop_visit_fn_ret_ty<T: MutVisitor>(fn_ret_ty: &mut FnRetTy, vis: &mut T) { |
dfeec247 | 760 | match fn_ret_ty { |
74b04a01 XL |
761 | FnRetTy::Default(span) => vis.visit_span(span), |
762 | FnRetTy::Ty(ty) => vis.visit_ty(ty), | |
9fa01778 XL |
763 | } |
764 | } | |
765 | ||
766 | pub fn noop_visit_param_bound<T: MutVisitor>(pb: &mut GenericBound, vis: &mut T) { | |
767 | match pb { | |
768 | GenericBound::Trait(ty, _modifier) => vis.visit_poly_trait_ref(ty), | |
769 | GenericBound::Outlives(lifetime) => noop_visit_lifetime(lifetime, vis), | |
770 | } | |
771 | } | |
772 | ||
e1599b0c XL |
773 | pub fn noop_flat_map_generic_param<T: MutVisitor>( |
774 | mut param: GenericParam, | |
dfeec247 XL |
775 | vis: &mut T, |
776 | ) -> SmallVec<[GenericParam; 1]> { | |
e1599b0c | 777 | let GenericParam { id, ident, attrs, bounds, kind, is_placeholder: _ } = &mut param; |
9fa01778 XL |
778 | vis.visit_id(id); |
779 | vis.visit_ident(ident); | |
780 | visit_thin_attrs(attrs, vis); | |
781 | visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis)); | |
782 | match kind { | |
783 | GenericParamKind::Lifetime => {} | |
784 | GenericParamKind::Type { default } => { | |
785 | visit_opt(default, |default| vis.visit_ty(default)); | |
786 | } | |
5869c6ff | 787 | GenericParamKind::Const { ty, kw_span: _, default } => { |
9fa01778 | 788 | vis.visit_ty(ty); |
5869c6ff | 789 | visit_opt(default, |default| vis.visit_anon_const(default)); |
9fa01778 XL |
790 | } |
791 | } | |
e1599b0c | 792 | smallvec![param] |
9fa01778 XL |
793 | } |
794 | ||
795 | pub fn noop_visit_label<T: MutVisitor>(Label { ident }: &mut Label, vis: &mut T) { | |
796 | vis.visit_ident(ident); | |
797 | } | |
798 | ||
799 | fn noop_visit_lifetime<T: MutVisitor>(Lifetime { id, ident }: &mut Lifetime, vis: &mut T) { | |
800 | vis.visit_id(id); | |
801 | vis.visit_ident(ident); | |
802 | } | |
803 | ||
804 | pub fn noop_visit_generics<T: MutVisitor>(generics: &mut Generics, vis: &mut T) { | |
805 | let Generics { params, where_clause, span } = generics; | |
e1599b0c | 806 | params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); |
9fa01778 XL |
807 | vis.visit_where_clause(where_clause); |
808 | vis.visit_span(span); | |
809 | } | |
810 | ||
811 | pub fn noop_visit_where_clause<T: MutVisitor>(wc: &mut WhereClause, vis: &mut T) { | |
f035d41b | 812 | let WhereClause { has_where_token: _, predicates, span } = wc; |
9fa01778 XL |
813 | visit_vec(predicates, |predicate| vis.visit_where_predicate(predicate)); |
814 | vis.visit_span(span); | |
815 | } | |
816 | ||
817 | pub fn noop_visit_where_predicate<T: MutVisitor>(pred: &mut WherePredicate, vis: &mut T) { | |
818 | match pred { | |
819 | WherePredicate::BoundPredicate(bp) => { | |
820 | let WhereBoundPredicate { span, bound_generic_params, bounded_ty, bounds } = bp; | |
821 | vis.visit_span(span); | |
e1599b0c | 822 | bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); |
9fa01778 XL |
823 | vis.visit_ty(bounded_ty); |
824 | visit_vec(bounds, |bound| vis.visit_param_bound(bound)); | |
825 | } | |
826 | WherePredicate::RegionPredicate(rp) => { | |
827 | let WhereRegionPredicate { span, lifetime, bounds } = rp; | |
828 | vis.visit_span(span); | |
829 | noop_visit_lifetime(lifetime, vis); | |
830 | visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis)); | |
831 | } | |
832 | WherePredicate::EqPredicate(ep) => { | |
833 | let WhereEqPredicate { id, span, lhs_ty, rhs_ty } = ep; | |
834 | vis.visit_id(id); | |
835 | vis.visit_span(span); | |
836 | vis.visit_ty(lhs_ty); | |
837 | vis.visit_ty(rhs_ty); | |
838 | } | |
839 | } | |
840 | } | |
841 | ||
842 | pub fn noop_visit_variant_data<T: MutVisitor>(vdata: &mut VariantData, vis: &mut T) { | |
843 | match vdata { | |
e1599b0c | 844 | VariantData::Struct(fields, ..) => { |
6a06907d | 845 | fields.flat_map_in_place(|field| vis.flat_map_field_def(field)); |
dfeec247 | 846 | } |
9fa01778 | 847 | VariantData::Tuple(fields, id) => { |
6a06907d | 848 | fields.flat_map_in_place(|field| vis.flat_map_field_def(field)); |
9fa01778 | 849 | vis.visit_id(id); |
dfeec247 | 850 | } |
9fa01778 XL |
851 | VariantData::Unit(id) => vis.visit_id(id), |
852 | } | |
853 | } | |
854 | ||
855 | pub fn noop_visit_trait_ref<T: MutVisitor>(TraitRef { path, ref_id }: &mut TraitRef, vis: &mut T) { | |
856 | vis.visit_path(path); | |
857 | vis.visit_id(ref_id); | |
858 | } | |
859 | ||
860 | pub fn noop_visit_poly_trait_ref<T: MutVisitor>(p: &mut PolyTraitRef, vis: &mut T) { | |
861 | let PolyTraitRef { bound_generic_params, trait_ref, span } = p; | |
e1599b0c | 862 | bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); |
9fa01778 XL |
863 | vis.visit_trait_ref(trait_ref); |
864 | vis.visit_span(span); | |
865 | } | |
866 | ||
6a06907d XL |
867 | pub fn noop_flat_map_field_def<T: MutVisitor>( |
868 | mut fd: FieldDef, | |
dfeec247 | 869 | visitor: &mut T, |
6a06907d XL |
870 | ) -> SmallVec<[FieldDef; 1]> { |
871 | let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _ } = &mut fd; | |
9fa01778 XL |
872 | visitor.visit_span(span); |
873 | visit_opt(ident, |ident| visitor.visit_ident(ident)); | |
874 | visitor.visit_vis(vis); | |
875 | visitor.visit_id(id); | |
876 | visitor.visit_ty(ty); | |
877 | visit_attrs(attrs, visitor); | |
6a06907d | 878 | smallvec![fd] |
9fa01778 XL |
879 | } |
880 | ||
6a06907d XL |
881 | pub fn noop_flat_map_expr_field<T: MutVisitor>( |
882 | mut f: ExprField, | |
883 | vis: &mut T, | |
884 | ) -> SmallVec<[ExprField; 1]> { | |
885 | let ExprField { ident, expr, span, is_shorthand: _, attrs, id, is_placeholder: _ } = &mut f; | |
9fa01778 XL |
886 | vis.visit_ident(ident); |
887 | vis.visit_expr(expr); | |
e1599b0c | 888 | vis.visit_id(id); |
9fa01778 XL |
889 | vis.visit_span(span); |
890 | visit_thin_attrs(attrs, vis); | |
e1599b0c | 891 | smallvec![f] |
9fa01778 XL |
892 | } |
893 | ||
894 | pub fn noop_visit_mt<T: MutVisitor>(MutTy { ty, mutbl: _ }: &mut MutTy, vis: &mut T) { | |
895 | vis.visit_ty(ty); | |
896 | } | |
897 | ||
898 | pub fn noop_visit_block<T: MutVisitor>(block: &mut P<Block>, vis: &mut T) { | |
29967ef6 | 899 | let Block { id, stmts, rules: _, span, tokens } = block.deref_mut(); |
9fa01778 XL |
900 | vis.visit_id(id); |
901 | stmts.flat_map_in_place(|stmt| vis.flat_map_stmt(stmt)); | |
902 | vis.visit_span(span); | |
29967ef6 | 903 | visit_lazy_tts(tokens, vis); |
9fa01778 XL |
904 | } |
905 | ||
906 | pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) { | |
907 | match kind { | |
908 | ItemKind::ExternCrate(_orig_name) => {} | |
909 | ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree), | |
74b04a01 | 910 | ItemKind::Static(ty, _, expr) | ItemKind::Const(_, ty, expr) => { |
9fa01778 | 911 | vis.visit_ty(ty); |
74b04a01 | 912 | visit_opt(expr, |expr| vis.visit_expr(expr)); |
9fa01778 | 913 | } |
5869c6ff | 914 | ItemKind::Fn(box FnKind(_, sig, generics, body)) => { |
60c5eb7d | 915 | visit_fn_sig(sig, vis); |
9fa01778 | 916 | vis.visit_generics(generics); |
74b04a01 | 917 | visit_opt(body, |body| vis.visit_block(body)); |
9fa01778 | 918 | } |
6a06907d XL |
919 | ItemKind::Mod(_unsafety, mod_kind) => match mod_kind { |
920 | ModKind::Loaded(items, _inline, inner_span) => { | |
921 | vis.visit_span(inner_span); | |
922 | items.flat_map_in_place(|item| vis.flat_map_item(item)); | |
923 | } | |
924 | ModKind::Unloaded => {} | |
925 | }, | |
9fa01778 XL |
926 | ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm), |
927 | ItemKind::GlobalAsm(_ga) => {} | |
5869c6ff | 928 | ItemKind::TyAlias(box TyAliasKind(_, generics, bounds, ty)) => { |
9fa01778 | 929 | vis.visit_generics(generics); |
74b04a01 XL |
930 | visit_bounds(bounds, vis); |
931 | visit_opt(ty, |ty| vis.visit_ty(ty)); | |
9fa01778 | 932 | } |
9fa01778 | 933 | ItemKind::Enum(EnumDef { variants }, generics) => { |
e1599b0c | 934 | variants.flat_map_in_place(|variant| vis.flat_map_variant(variant)); |
9fa01778 XL |
935 | vis.visit_generics(generics); |
936 | } | |
dfeec247 | 937 | ItemKind::Struct(variant_data, generics) | ItemKind::Union(variant_data, generics) => { |
9fa01778 XL |
938 | vis.visit_variant_data(variant_data); |
939 | vis.visit_generics(generics); | |
940 | } | |
5869c6ff | 941 | ItemKind::Impl(box ImplKind { |
dfeec247 XL |
942 | unsafety: _, |
943 | polarity: _, | |
944 | defaultness: _, | |
945 | constness: _, | |
946 | generics, | |
947 | of_trait, | |
948 | self_ty, | |
949 | items, | |
5869c6ff | 950 | }) => { |
9fa01778 | 951 | vis.visit_generics(generics); |
dfeec247 XL |
952 | visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref)); |
953 | vis.visit_ty(self_ty); | |
9fa01778 XL |
954 | items.flat_map_in_place(|item| vis.flat_map_impl_item(item)); |
955 | } | |
5869c6ff | 956 | ItemKind::Trait(box TraitKind(.., generics, bounds, items)) => { |
9fa01778 XL |
957 | vis.visit_generics(generics); |
958 | visit_bounds(bounds, vis); | |
959 | items.flat_map_in_place(|item| vis.flat_map_trait_item(item)); | |
960 | } | |
961 | ItemKind::TraitAlias(generics, bounds) => { | |
962 | vis.visit_generics(generics); | |
963 | visit_bounds(bounds, vis); | |
964 | } | |
29967ef6 | 965 | ItemKind::MacCall(m) => vis.visit_mac_call(m), |
9fa01778 XL |
966 | ItemKind::MacroDef(def) => vis.visit_macro_def(def), |
967 | } | |
968 | } | |
969 | ||
dfeec247 | 970 | pub fn noop_flat_map_assoc_item<T: MutVisitor>( |
74b04a01 | 971 | mut item: P<AssocItem>, |
dfeec247 | 972 | visitor: &mut T, |
74b04a01 | 973 | ) -> SmallVec<[P<AssocItem>; 1]> { |
29967ef6 | 974 | let Item { id, ident, vis, attrs, kind, span, tokens } = item.deref_mut(); |
60c5eb7d XL |
975 | visitor.visit_id(id); |
976 | visitor.visit_ident(ident); | |
977 | visitor.visit_vis(vis); | |
978 | visit_attrs(attrs, visitor); | |
e74abb32 | 979 | match kind { |
74b04a01 | 980 | AssocItemKind::Const(_, ty, expr) => { |
60c5eb7d | 981 | visitor.visit_ty(ty); |
dfeec247 | 982 | visit_opt(expr, |expr| visitor.visit_expr(expr)); |
9fa01778 | 983 | } |
5869c6ff | 984 | AssocItemKind::Fn(box FnKind(_, sig, generics, body)) => { |
74b04a01 | 985 | visitor.visit_generics(generics); |
60c5eb7d XL |
986 | visit_fn_sig(sig, visitor); |
987 | visit_opt(body, |body| visitor.visit_block(body)); | |
9fa01778 | 988 | } |
5869c6ff | 989 | AssocItemKind::TyAlias(box TyAliasKind(_, generics, bounds, ty)) => { |
74b04a01 | 990 | visitor.visit_generics(generics); |
60c5eb7d | 991 | visit_bounds(bounds, visitor); |
dfeec247 | 992 | visit_opt(ty, |ty| visitor.visit_ty(ty)); |
9fa01778 | 993 | } |
29967ef6 | 994 | AssocItemKind::MacCall(mac) => visitor.visit_mac_call(mac), |
9fa01778 XL |
995 | } |
996 | visitor.visit_span(span); | |
29967ef6 | 997 | visit_lazy_tts(tokens, visitor); |
9fa01778 XL |
998 | smallvec![item] |
999 | } | |
1000 | ||
1001 | pub fn noop_visit_fn_header<T: MutVisitor>(header: &mut FnHeader, vis: &mut T) { | |
60c5eb7d | 1002 | let FnHeader { unsafety: _, asyncness, constness: _, ext: _ } = header; |
74b04a01 | 1003 | vis.visit_asyncness(asyncness); |
9fa01778 XL |
1004 | } |
1005 | ||
6a06907d XL |
1006 | // FIXME: Avoid visiting the crate as a `Mod` item, flat map only the inner items if possible, |
1007 | // or make crate visiting first class if necessary. | |
9fa01778 | 1008 | pub fn noop_visit_crate<T: MutVisitor>(krate: &mut Crate, vis: &mut T) { |
6a06907d | 1009 | visit_clobber(krate, |Crate { attrs, items, span, proc_macros }| { |
1b1a35ee XL |
1010 | let item_vis = |
1011 | Visibility { kind: VisibilityKind::Public, span: span.shrink_to_lo(), tokens: None }; | |
9fa01778 | 1012 | let item = P(Item { |
dc9dc135 | 1013 | ident: Ident::invalid(), |
9fa01778 XL |
1014 | attrs, |
1015 | id: DUMMY_NODE_ID, | |
1b1a35ee | 1016 | vis: item_vis, |
9fa01778 | 1017 | span, |
6a06907d | 1018 | kind: ItemKind::Mod(Unsafe::No, ModKind::Loaded(items, Inline::Yes, span)), |
9fa01778 XL |
1019 | tokens: None, |
1020 | }); | |
1021 | let items = vis.flat_map_item(item); | |
1022 | ||
1023 | let len = items.len(); | |
1024 | if len == 0 { | |
6a06907d | 1025 | Crate { attrs: vec![], items: vec![], span, proc_macros } |
9fa01778 | 1026 | } else if len == 1 { |
e74abb32 XL |
1027 | let Item { attrs, span, kind, .. } = items.into_iter().next().unwrap().into_inner(); |
1028 | match kind { | |
6a06907d XL |
1029 | ItemKind::Mod(_, ModKind::Loaded(items, ..)) => { |
1030 | Crate { attrs, items, span, proc_macros } | |
1031 | } | |
9fa01778 XL |
1032 | _ => panic!("visitor converted a module to not a module"), |
1033 | } | |
1034 | } else { | |
1035 | panic!("a crate cannot expand to more than one item"); | |
1036 | } | |
1037 | }); | |
1038 | } | |
1039 | ||
e1599b0c | 1040 | // Mutates one item into possibly many items. |
dfeec247 XL |
1041 | pub fn noop_flat_map_item<T: MutVisitor>( |
1042 | mut item: P<Item>, | |
1043 | visitor: &mut T, | |
1044 | ) -> SmallVec<[P<Item>; 1]> { | |
29967ef6 | 1045 | let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut(); |
9fa01778 XL |
1046 | visitor.visit_ident(ident); |
1047 | visit_attrs(attrs, visitor); | |
1048 | visitor.visit_id(id); | |
e74abb32 | 1049 | visitor.visit_item_kind(kind); |
9fa01778 XL |
1050 | visitor.visit_vis(vis); |
1051 | visitor.visit_span(span); | |
29967ef6 | 1052 | visit_lazy_tts(tokens, visitor); |
9fa01778 XL |
1053 | |
1054 | smallvec![item] | |
1055 | } | |
1056 | ||
dfeec247 | 1057 | pub fn noop_flat_map_foreign_item<T: MutVisitor>( |
74b04a01 | 1058 | mut item: P<ForeignItem>, |
dfeec247 | 1059 | visitor: &mut T, |
74b04a01 | 1060 | ) -> SmallVec<[P<ForeignItem>; 1]> { |
29967ef6 | 1061 | let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut(); |
74b04a01 | 1062 | visitor.visit_id(id); |
9fa01778 | 1063 | visitor.visit_ident(ident); |
74b04a01 | 1064 | visitor.visit_vis(vis); |
9fa01778 | 1065 | visit_attrs(attrs, visitor); |
e74abb32 | 1066 | match kind { |
74b04a01 XL |
1067 | ForeignItemKind::Static(ty, _, expr) => { |
1068 | visitor.visit_ty(ty); | |
1069 | visit_opt(expr, |expr| visitor.visit_expr(expr)); | |
1070 | } | |
5869c6ff | 1071 | ForeignItemKind::Fn(box FnKind(_, sig, generics, body)) => { |
74b04a01 XL |
1072 | visitor.visit_generics(generics); |
1073 | visit_fn_sig(sig, visitor); | |
1074 | visit_opt(body, |body| visitor.visit_block(body)); | |
1075 | } | |
5869c6ff | 1076 | ForeignItemKind::TyAlias(box TyAliasKind(_, generics, bounds, ty)) => { |
9fa01778 | 1077 | visitor.visit_generics(generics); |
74b04a01 XL |
1078 | visit_bounds(bounds, visitor); |
1079 | visit_opt(ty, |ty| visitor.visit_ty(ty)); | |
9fa01778 | 1080 | } |
29967ef6 | 1081 | ForeignItemKind::MacCall(mac) => visitor.visit_mac_call(mac), |
9fa01778 | 1082 | } |
9fa01778 | 1083 | visitor.visit_span(span); |
29967ef6 | 1084 | visit_lazy_tts(tokens, visitor); |
9fa01778 XL |
1085 | smallvec![item] |
1086 | } | |
1087 | ||
1088 | pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) { | |
29967ef6 | 1089 | let Pat { id, kind, span, tokens } = pat.deref_mut(); |
9fa01778 | 1090 | vis.visit_id(id); |
e74abb32 | 1091 | match kind { |
416331ca | 1092 | PatKind::Wild | PatKind::Rest => {} |
9fa01778 XL |
1093 | PatKind::Ident(_binding_mode, ident, sub) => { |
1094 | vis.visit_ident(ident); | |
1095 | visit_opt(sub, |sub| vis.visit_pat(sub)); | |
1096 | } | |
1097 | PatKind::Lit(e) => vis.visit_expr(e), | |
416331ca | 1098 | PatKind::TupleStruct(path, elems) => { |
9fa01778 | 1099 | vis.visit_path(path); |
416331ca | 1100 | visit_vec(elems, |elem| vis.visit_pat(elem)); |
9fa01778 XL |
1101 | } |
1102 | PatKind::Path(qself, path) => { | |
1103 | vis.visit_qself(qself); | |
1104 | vis.visit_path(path); | |
1105 | } | |
1106 | PatKind::Struct(path, fields, _etc) => { | |
1107 | vis.visit_path(path); | |
6a06907d | 1108 | fields.flat_map_in_place(|field| vis.flat_map_pat_field(field)); |
e1599b0c | 1109 | } |
9fa01778 XL |
1110 | PatKind::Box(inner) => vis.visit_pat(inner), |
1111 | PatKind::Ref(inner, _mutbl) => vis.visit_pat(inner), | |
1112 | PatKind::Range(e1, e2, Spanned { span: _, node: _ }) => { | |
dfeec247 XL |
1113 | visit_opt(e1, |e| vis.visit_expr(e)); |
1114 | visit_opt(e2, |e| vis.visit_expr(e)); | |
9fa01778 XL |
1115 | vis.visit_span(span); |
1116 | } | |
dfeec247 XL |
1117 | PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => { |
1118 | visit_vec(elems, |elem| vis.visit_pat(elem)) | |
1119 | } | |
9fa01778 | 1120 | PatKind::Paren(inner) => vis.visit_pat(inner), |
29967ef6 | 1121 | PatKind::MacCall(mac) => vis.visit_mac_call(mac), |
9fa01778 XL |
1122 | } |
1123 | vis.visit_span(span); | |
29967ef6 | 1124 | visit_lazy_tts(tokens, vis); |
9fa01778 XL |
1125 | } |
1126 | ||
1127 | pub fn noop_visit_anon_const<T: MutVisitor>(AnonConst { id, value }: &mut AnonConst, vis: &mut T) { | |
1128 | vis.visit_id(id); | |
1129 | vis.visit_expr(value); | |
1130 | } | |
1131 | ||
f9f354fc | 1132 | pub fn noop_visit_expr<T: MutVisitor>( |
29967ef6 | 1133 | Expr { kind, id, span, attrs, tokens }: &mut Expr, |
f9f354fc XL |
1134 | vis: &mut T, |
1135 | ) { | |
e74abb32 | 1136 | match kind { |
9fa01778 | 1137 | ExprKind::Box(expr) => vis.visit_expr(expr), |
9fa01778 | 1138 | ExprKind::Array(exprs) => visit_exprs(exprs, vis), |
29967ef6 XL |
1139 | ExprKind::ConstBlock(anon_const) => { |
1140 | vis.visit_anon_const(anon_const); | |
1141 | } | |
9fa01778 XL |
1142 | ExprKind::Repeat(expr, count) => { |
1143 | vis.visit_expr(expr); | |
1144 | vis.visit_anon_const(count); | |
1145 | } | |
1146 | ExprKind::Tup(exprs) => visit_exprs(exprs, vis), | |
1147 | ExprKind::Call(f, args) => { | |
1148 | vis.visit_expr(f); | |
1149 | visit_exprs(args, vis); | |
1150 | } | |
f035d41b | 1151 | ExprKind::MethodCall(PathSegment { ident, id, args }, exprs, span) => { |
9fa01778 XL |
1152 | vis.visit_ident(ident); |
1153 | vis.visit_id(id); | |
1154 | visit_opt(args, |args| vis.visit_generic_args(args)); | |
1155 | visit_exprs(exprs, vis); | |
f035d41b | 1156 | vis.visit_span(span); |
9fa01778 XL |
1157 | } |
1158 | ExprKind::Binary(_binop, lhs, rhs) => { | |
1159 | vis.visit_expr(lhs); | |
1160 | vis.visit_expr(rhs); | |
1161 | } | |
1162 | ExprKind::Unary(_unop, ohs) => vis.visit_expr(ohs), | |
9fa01778 XL |
1163 | ExprKind::Cast(expr, ty) => { |
1164 | vis.visit_expr(expr); | |
1165 | vis.visit_ty(ty); | |
1166 | } | |
1167 | ExprKind::Type(expr, ty) => { | |
1168 | vis.visit_expr(expr); | |
1169 | vis.visit_ty(ty); | |
1170 | } | |
60c5eb7d | 1171 | ExprKind::AddrOf(_, _, ohs) => vis.visit_expr(ohs), |
e1599b0c XL |
1172 | ExprKind::Let(pat, scrutinee) => { |
1173 | vis.visit_pat(pat); | |
dc9dc135 XL |
1174 | vis.visit_expr(scrutinee); |
1175 | } | |
9fa01778 XL |
1176 | ExprKind::If(cond, tr, fl) => { |
1177 | vis.visit_expr(cond); | |
1178 | vis.visit_block(tr); | |
1179 | visit_opt(fl, |fl| vis.visit_expr(fl)); | |
1180 | } | |
9fa01778 XL |
1181 | ExprKind::While(cond, body, label) => { |
1182 | vis.visit_expr(cond); | |
1183 | vis.visit_block(body); | |
1184 | visit_opt(label, |label| vis.visit_label(label)); | |
1185 | } | |
9fa01778 XL |
1186 | ExprKind::ForLoop(pat, iter, body, label) => { |
1187 | vis.visit_pat(pat); | |
1188 | vis.visit_expr(iter); | |
1189 | vis.visit_block(body); | |
1190 | visit_opt(label, |label| vis.visit_label(label)); | |
1191 | } | |
1192 | ExprKind::Loop(body, label) => { | |
1193 | vis.visit_block(body); | |
1194 | visit_opt(label, |label| vis.visit_label(label)); | |
1195 | } | |
1196 | ExprKind::Match(expr, arms) => { | |
1197 | vis.visit_expr(expr); | |
e1599b0c | 1198 | arms.flat_map_in_place(|arm| vis.flat_map_arm(arm)); |
9fa01778 XL |
1199 | } |
1200 | ExprKind::Closure(_capture_by, asyncness, _movability, decl, body, span) => { | |
1201 | vis.visit_asyncness(asyncness); | |
1202 | vis.visit_fn_decl(decl); | |
1203 | vis.visit_expr(body); | |
1204 | vis.visit_span(span); | |
1205 | } | |
1206 | ExprKind::Block(blk, label) => { | |
1207 | vis.visit_block(blk); | |
1208 | visit_opt(label, |label| vis.visit_label(label)); | |
1209 | } | |
1210 | ExprKind::Async(_capture_by, node_id, body) => { | |
1211 | vis.visit_id(node_id); | |
1212 | vis.visit_block(body); | |
1213 | } | |
416331ca | 1214 | ExprKind::Await(expr) => vis.visit_expr(expr), |
dfeec247 | 1215 | ExprKind::Assign(el, er, _) => { |
9fa01778 XL |
1216 | vis.visit_expr(el); |
1217 | vis.visit_expr(er); | |
1218 | } | |
1219 | ExprKind::AssignOp(_op, el, er) => { | |
1220 | vis.visit_expr(el); | |
1221 | vis.visit_expr(er); | |
1222 | } | |
1223 | ExprKind::Field(el, ident) => { | |
1224 | vis.visit_expr(el); | |
1225 | vis.visit_ident(ident); | |
1226 | } | |
1227 | ExprKind::Index(el, er) => { | |
1228 | vis.visit_expr(el); | |
1229 | vis.visit_expr(er); | |
1230 | } | |
1231 | ExprKind::Range(e1, e2, _lim) => { | |
1232 | visit_opt(e1, |e1| vis.visit_expr(e1)); | |
1233 | visit_opt(e2, |e2| vis.visit_expr(e2)); | |
1234 | } | |
fc512014 | 1235 | ExprKind::Underscore => {} |
9fa01778 XL |
1236 | ExprKind::Path(qself, path) => { |
1237 | vis.visit_qself(qself); | |
1238 | vis.visit_path(path); | |
1239 | } | |
1240 | ExprKind::Break(label, expr) => { | |
1241 | visit_opt(label, |label| vis.visit_label(label)); | |
1242 | visit_opt(expr, |expr| vis.visit_expr(expr)); | |
1243 | } | |
1244 | ExprKind::Continue(label) => { | |
1245 | visit_opt(label, |label| vis.visit_label(label)); | |
1246 | } | |
1247 | ExprKind::Ret(expr) => { | |
1248 | visit_opt(expr, |expr| vis.visit_expr(expr)); | |
1249 | } | |
f9f354fc XL |
1250 | ExprKind::InlineAsm(asm) => { |
1251 | for (op, _) in &mut asm.operands { | |
1252 | match op { | |
1253 | InlineAsmOperand::In { expr, .. } | |
1254 | | InlineAsmOperand::InOut { expr, .. } | |
1255 | | InlineAsmOperand::Const { expr, .. } | |
1256 | | InlineAsmOperand::Sym { expr, .. } => vis.visit_expr(expr), | |
1257 | InlineAsmOperand::Out { expr, .. } => { | |
1258 | if let Some(expr) = expr { | |
1259 | vis.visit_expr(expr); | |
1260 | } | |
1261 | } | |
1262 | InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => { | |
1263 | vis.visit_expr(in_expr); | |
1264 | if let Some(out_expr) = out_expr { | |
1265 | vis.visit_expr(out_expr); | |
1266 | } | |
1267 | } | |
1268 | } | |
1269 | } | |
1270 | } | |
ba9703b0 XL |
1271 | ExprKind::LlvmInlineAsm(asm) => { |
1272 | let LlvmInlineAsm { | |
dfeec247 XL |
1273 | asm: _, |
1274 | asm_str_style: _, | |
1275 | outputs, | |
1276 | inputs, | |
1277 | clobbers: _, | |
1278 | volatile: _, | |
1279 | alignstack: _, | |
1280 | dialect: _, | |
1281 | } = asm.deref_mut(); | |
9fa01778 | 1282 | for out in outputs { |
ba9703b0 | 1283 | let LlvmInlineAsmOutput { constraint: _, expr, is_rw: _, is_indirect: _ } = out; |
9fa01778 XL |
1284 | vis.visit_expr(expr); |
1285 | } | |
1286 | visit_vec(inputs, |(_c, expr)| vis.visit_expr(expr)); | |
1287 | } | |
29967ef6 | 1288 | ExprKind::MacCall(mac) => vis.visit_mac_call(mac), |
6a06907d XL |
1289 | ExprKind::Struct(se) => { |
1290 | let StructExpr { path, fields, rest } = se.deref_mut(); | |
9fa01778 | 1291 | vis.visit_path(path); |
6a06907d XL |
1292 | fields.flat_map_in_place(|field| vis.flat_map_expr_field(field)); |
1293 | match rest { | |
29967ef6 XL |
1294 | StructRest::Base(expr) => vis.visit_expr(expr), |
1295 | StructRest::Rest(_span) => {} | |
1296 | StructRest::None => {} | |
1297 | } | |
dfeec247 | 1298 | } |
9fa01778 XL |
1299 | ExprKind::Paren(expr) => { |
1300 | vis.visit_expr(expr); | |
1301 | ||
e1599b0c | 1302 | // Nodes that are equal modulo `Paren` sugar no-ops should have the same IDs. |
9fa01778 XL |
1303 | *id = expr.id; |
1304 | vis.visit_span(span); | |
1305 | visit_thin_attrs(attrs, vis); | |
1306 | return; | |
1307 | } | |
1308 | ExprKind::Yield(expr) => { | |
1309 | visit_opt(expr, |expr| vis.visit_expr(expr)); | |
1310 | } | |
1311 | ExprKind::Try(expr) => vis.visit_expr(expr), | |
1312 | ExprKind::TryBlock(body) => vis.visit_block(body), | |
dc9dc135 | 1313 | ExprKind::Lit(_) | ExprKind::Err => {} |
9fa01778 XL |
1314 | } |
1315 | vis.visit_id(id); | |
1316 | vis.visit_span(span); | |
1317 | visit_thin_attrs(attrs, vis); | |
29967ef6 | 1318 | visit_lazy_tts(tokens, vis); |
9fa01778 XL |
1319 | } |
1320 | ||
1321 | pub fn noop_filter_map_expr<T: MutVisitor>(mut e: P<Expr>, vis: &mut T) -> Option<P<Expr>> { | |
dfeec247 XL |
1322 | Some({ |
1323 | vis.visit_expr(&mut e); | |
1324 | e | |
1325 | }) | |
9fa01778 XL |
1326 | } |
1327 | ||
dfeec247 | 1328 | pub fn noop_flat_map_stmt<T: MutVisitor>( |
fc512014 | 1329 | Stmt { kind, mut span, mut id }: Stmt, |
dfeec247 XL |
1330 | vis: &mut T, |
1331 | ) -> SmallVec<[Stmt; 1]> { | |
9fa01778 XL |
1332 | vis.visit_id(&mut id); |
1333 | vis.visit_span(&mut span); | |
fc512014 | 1334 | noop_flat_map_stmt_kind(kind, vis).into_iter().map(|kind| Stmt { id, kind, span }).collect() |
9fa01778 XL |
1335 | } |
1336 | ||
dfeec247 XL |
1337 | pub fn noop_flat_map_stmt_kind<T: MutVisitor>( |
1338 | kind: StmtKind, | |
1339 | vis: &mut T, | |
1340 | ) -> SmallVec<[StmtKind; 1]> { | |
e74abb32 | 1341 | match kind { |
dfeec247 XL |
1342 | StmtKind::Local(mut local) => smallvec![StmtKind::Local({ |
1343 | vis.visit_local(&mut local); | |
1344 | local | |
1345 | })], | |
9fa01778 | 1346 | StmtKind::Item(item) => vis.flat_map_item(item).into_iter().map(StmtKind::Item).collect(), |
dfeec247 XL |
1347 | StmtKind::Expr(expr) => vis.filter_map_expr(expr).into_iter().map(StmtKind::Expr).collect(), |
1348 | StmtKind::Semi(expr) => vis.filter_map_expr(expr).into_iter().map(StmtKind::Semi).collect(), | |
74b04a01 | 1349 | StmtKind::Empty => smallvec![StmtKind::Empty], |
ba9703b0 | 1350 | StmtKind::MacCall(mut mac) => { |
fc512014 | 1351 | let MacCallStmt { mac: mac_, style: _, attrs, tokens } = mac.deref_mut(); |
29967ef6 | 1352 | vis.visit_mac_call(mac_); |
9fa01778 | 1353 | visit_thin_attrs(attrs, vis); |
fc512014 | 1354 | visit_lazy_tts(tokens, vis); |
ba9703b0 | 1355 | smallvec![StmtKind::MacCall(mac)] |
9fa01778 XL |
1356 | } |
1357 | } | |
1358 | } | |
1359 | ||
1b1a35ee XL |
1360 | pub fn noop_visit_vis<T: MutVisitor>(visibility: &mut Visibility, vis: &mut T) { |
1361 | match &mut visibility.kind { | |
9fa01778 XL |
1362 | VisibilityKind::Public | VisibilityKind::Crate(_) | VisibilityKind::Inherited => {} |
1363 | VisibilityKind::Restricted { path, id } => { | |
1364 | vis.visit_path(path); | |
1365 | vis.visit_id(id); | |
1366 | } | |
1367 | } | |
1b1a35ee | 1368 | vis.visit_span(&mut visibility.span); |
9fa01778 | 1369 | } |