]>
Commit | Line | Data |
---|---|---|
e1599b0c | 1 | //! A `MutVisitor` represents an AST modification; it accepts an AST piece and |
a2a8927a | 2 | //! 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 | ||
9fa01778 | 10 | use crate::ptr::P; |
dfeec247 | 11 | use crate::token::{self, Token}; |
9fa01778 | 12 | use crate::tokenstream::*; |
353b0b11 | 13 | use crate::{ast::*, StaticItem}; |
9fa01778 | 14 | |
353b0b11 | 15 | use rustc_data_structures::flat_map_in_place::FlatMapInPlace; |
9fa01778 | 16 | use rustc_data_structures::sync::Lrc; |
1b1a35ee | 17 | use rustc_span::source_map::Spanned; |
f9f354fc | 18 | use rustc_span::symbol::Ident; |
dfeec247 | 19 | use rustc_span::Span; |
dfeec247 | 20 | use smallvec::{smallvec, Array, SmallVec}; |
9fa01778 | 21 | use std::ops::DerefMut; |
a2a8927a | 22 | use std::{panic, ptr}; |
9ffffee4 | 23 | use thin_vec::ThinVec; |
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. | |
3c0e092e | 40 | const VISIT_TOKENS: bool = false; |
29967ef6 | 41 | |
9fa01778 XL |
42 | // Methods in this trait have one of three forms: |
43 | // | |
44 | // fn visit_t(&mut self, t: &mut T); // common | |
45 | // fn flat_map_t(&mut self, t: T) -> SmallVec<[T; 1]>; // rare | |
46 | // fn filter_map_t(&mut self, t: T) -> Option<T>; // rarest | |
47 | // | |
48 | // Any additions to this trait should happen in form of a call to a public | |
49 | // `noop_*` function that only calls out to the visitor again, not other | |
50 | // `noop_*` functions. This is a necessary API workaround to the problem of | |
51 | // not being able to call out to the super default method in an overridden | |
52 | // default method. | |
53 | // | |
54 | // When writing these methods, it is better to use destructuring like this: | |
55 | // | |
56 | // fn visit_abc(&mut self, ABC { a, b, c: _ }: &mut ABC) { | |
57 | // visit_a(a); | |
58 | // visit_b(b); | |
59 | // } | |
60 | // | |
61 | // than to use field access like this: | |
62 | // | |
63 | // fn visit_abc(&mut self, abc: &mut ABC) { | |
64 | // visit_a(&mut abc.a); | |
65 | // visit_b(&mut abc.b); | |
66 | // // ignore abc.c | |
67 | // } | |
68 | // | |
69 | // As well as being more concise, the former is explicit about which fields | |
70 | // are skipped. Furthermore, if a new field is added, the destructuring | |
71 | // version will cause a compile error, which is good. In comparison, the | |
72 | // field access version will continue working and it would be easy to | |
73 | // forget to add handling for it. | |
74 | ||
75 | fn visit_crate(&mut self, c: &mut Crate) { | |
76 | noop_visit_crate(c, self) | |
77 | } | |
78 | ||
79 | fn visit_meta_list_item(&mut self, list_item: &mut NestedMetaItem) { | |
80 | noop_visit_meta_list_item(list_item, self); | |
81 | } | |
82 | ||
83 | fn visit_meta_item(&mut self, meta_item: &mut MetaItem) { | |
84 | noop_visit_meta_item(meta_item, self); | |
85 | } | |
86 | ||
87 | fn visit_use_tree(&mut self, use_tree: &mut UseTree) { | |
88 | noop_visit_use_tree(use_tree, self); | |
89 | } | |
90 | ||
74b04a01 | 91 | fn flat_map_foreign_item(&mut self, ni: P<ForeignItem>) -> SmallVec<[P<ForeignItem>; 1]> { |
9fa01778 XL |
92 | noop_flat_map_foreign_item(ni, self) |
93 | } | |
94 | ||
95 | fn flat_map_item(&mut self, i: P<Item>) -> SmallVec<[P<Item>; 1]> { | |
96 | noop_flat_map_item(i, self) | |
97 | } | |
98 | ||
99 | fn visit_fn_header(&mut self, header: &mut FnHeader) { | |
100 | noop_visit_fn_header(header, self); | |
101 | } | |
102 | ||
6a06907d XL |
103 | fn flat_map_field_def(&mut self, fd: FieldDef) -> SmallVec<[FieldDef; 1]> { |
104 | noop_flat_map_field_def(fd, self) | |
9fa01778 XL |
105 | } |
106 | ||
107 | fn visit_item_kind(&mut self, i: &mut ItemKind) { | |
108 | noop_visit_item_kind(i, self); | |
109 | } | |
110 | ||
74b04a01 | 111 | fn flat_map_trait_item(&mut self, i: P<AssocItem>) -> SmallVec<[P<AssocItem>; 1]> { |
dfeec247 | 112 | noop_flat_map_assoc_item(i, self) |
9fa01778 XL |
113 | } |
114 | ||
74b04a01 | 115 | fn flat_map_impl_item(&mut self, i: P<AssocItem>) -> SmallVec<[P<AssocItem>; 1]> { |
dfeec247 | 116 | noop_flat_map_assoc_item(i, self) |
9fa01778 XL |
117 | } |
118 | ||
119 | fn visit_fn_decl(&mut self, d: &mut P<FnDecl>) { | |
120 | noop_visit_fn_decl(d, self); | |
121 | } | |
122 | ||
74b04a01 | 123 | fn visit_asyncness(&mut self, a: &mut Async) { |
9fa01778 XL |
124 | noop_visit_asyncness(a, self); |
125 | } | |
126 | ||
064997fb FG |
127 | fn visit_closure_binder(&mut self, b: &mut ClosureBinder) { |
128 | noop_visit_closure_binder(b, self); | |
129 | } | |
130 | ||
9fa01778 XL |
131 | fn visit_block(&mut self, b: &mut P<Block>) { |
132 | noop_visit_block(b, self); | |
133 | } | |
134 | ||
135 | fn flat_map_stmt(&mut self, s: Stmt) -> SmallVec<[Stmt; 1]> { | |
136 | noop_flat_map_stmt(s, self) | |
137 | } | |
138 | ||
e1599b0c XL |
139 | fn flat_map_arm(&mut self, arm: Arm) -> SmallVec<[Arm; 1]> { |
140 | noop_flat_map_arm(arm, self) | |
9fa01778 XL |
141 | } |
142 | ||
9fa01778 XL |
143 | fn visit_pat(&mut self, p: &mut P<Pat>) { |
144 | noop_visit_pat(p, self); | |
145 | } | |
146 | ||
147 | fn visit_anon_const(&mut self, c: &mut AnonConst) { | |
148 | noop_visit_anon_const(c, self); | |
149 | } | |
150 | ||
151 | fn visit_expr(&mut self, e: &mut P<Expr>) { | |
152 | noop_visit_expr(e, self); | |
153 | } | |
154 | ||
2b03887a FG |
155 | /// This method is a hack to workaround unstable of `stmt_expr_attributes`. |
156 | /// It can be removed once that feature is stabilized. | |
157 | fn visit_method_receiver_expr(&mut self, ex: &mut P<Expr>) { | |
158 | self.visit_expr(ex) | |
159 | } | |
160 | ||
9fa01778 XL |
161 | fn filter_map_expr(&mut self, e: P<Expr>) -> Option<P<Expr>> { |
162 | noop_filter_map_expr(e, self) | |
163 | } | |
164 | ||
165 | fn visit_generic_arg(&mut self, arg: &mut GenericArg) { | |
166 | noop_visit_generic_arg(arg, self); | |
167 | } | |
168 | ||
169 | fn visit_ty(&mut self, t: &mut P<Ty>) { | |
170 | noop_visit_ty(t, self); | |
171 | } | |
172 | ||
173 | fn visit_lifetime(&mut self, l: &mut Lifetime) { | |
174 | noop_visit_lifetime(l, self); | |
175 | } | |
176 | ||
5099ac24 FG |
177 | fn visit_constraint(&mut self, t: &mut AssocConstraint) { |
178 | noop_visit_constraint(t, self); | |
9fa01778 XL |
179 | } |
180 | ||
9fa01778 XL |
181 | fn visit_foreign_mod(&mut self, nm: &mut ForeignMod) { |
182 | noop_visit_foreign_mod(nm, self); | |
183 | } | |
184 | ||
dfeec247 | 185 | fn flat_map_variant(&mut self, v: Variant) -> SmallVec<[Variant; 1]> { |
e1599b0c | 186 | noop_flat_map_variant(v, self) |
9fa01778 XL |
187 | } |
188 | ||
189 | fn visit_ident(&mut self, i: &mut Ident) { | |
190 | noop_visit_ident(i, self); | |
191 | } | |
192 | ||
193 | fn visit_path(&mut self, p: &mut Path) { | |
194 | noop_visit_path(p, self); | |
195 | } | |
196 | ||
487cf647 | 197 | fn visit_qself(&mut self, qs: &mut Option<P<QSelf>>) { |
9fa01778 XL |
198 | noop_visit_qself(qs, self); |
199 | } | |
200 | ||
201 | fn visit_generic_args(&mut self, p: &mut GenericArgs) { | |
202 | noop_visit_generic_args(p, self); | |
203 | } | |
204 | ||
205 | fn visit_angle_bracketed_parameter_data(&mut self, p: &mut AngleBracketedArgs) { | |
206 | noop_visit_angle_bracketed_parameter_data(p, self); | |
207 | } | |
208 | ||
209 | fn visit_parenthesized_parameter_data(&mut self, p: &mut ParenthesizedArgs) { | |
210 | noop_visit_parenthesized_parameter_data(p, self); | |
211 | } | |
212 | ||
213 | fn visit_local(&mut self, l: &mut P<Local>) { | |
214 | noop_visit_local(l, self); | |
215 | } | |
216 | ||
29967ef6 XL |
217 | fn visit_mac_call(&mut self, mac: &mut MacCall) { |
218 | noop_visit_mac(mac, self); | |
9fa01778 XL |
219 | } |
220 | ||
221 | fn visit_macro_def(&mut self, def: &mut MacroDef) { | |
222 | noop_visit_macro_def(def, self); | |
223 | } | |
224 | ||
225 | fn visit_label(&mut self, label: &mut Label) { | |
226 | noop_visit_label(label, self); | |
227 | } | |
228 | ||
229 | fn visit_attribute(&mut self, at: &mut Attribute) { | |
230 | noop_visit_attribute(at, self); | |
231 | } | |
232 | ||
e1599b0c XL |
233 | fn flat_map_param(&mut self, param: Param) -> SmallVec<[Param; 1]> { |
234 | noop_flat_map_param(param, self) | |
9fa01778 XL |
235 | } |
236 | ||
237 | fn visit_generics(&mut self, generics: &mut Generics) { | |
238 | noop_visit_generics(generics, self); | |
239 | } | |
240 | ||
241 | fn visit_trait_ref(&mut self, tr: &mut TraitRef) { | |
242 | noop_visit_trait_ref(tr, self); | |
243 | } | |
244 | ||
245 | fn visit_poly_trait_ref(&mut self, p: &mut PolyTraitRef) { | |
246 | noop_visit_poly_trait_ref(p, self); | |
247 | } | |
248 | ||
249 | fn visit_variant_data(&mut self, vdata: &mut VariantData) { | |
250 | noop_visit_variant_data(vdata, self); | |
251 | } | |
252 | ||
e1599b0c XL |
253 | fn flat_map_generic_param(&mut self, param: GenericParam) -> SmallVec<[GenericParam; 1]> { |
254 | noop_flat_map_generic_param(param, self) | |
9fa01778 XL |
255 | } |
256 | ||
9fa01778 XL |
257 | fn visit_param_bound(&mut self, tpb: &mut GenericBound) { |
258 | noop_visit_param_bound(tpb, self); | |
259 | } | |
260 | ||
261 | fn visit_mt(&mut self, mt: &mut MutTy) { | |
262 | noop_visit_mt(mt, self); | |
263 | } | |
264 | ||
6a06907d XL |
265 | fn flat_map_expr_field(&mut self, f: ExprField) -> SmallVec<[ExprField; 1]> { |
266 | noop_flat_map_expr_field(f, self) | |
9fa01778 XL |
267 | } |
268 | ||
269 | fn visit_where_clause(&mut self, where_clause: &mut WhereClause) { | |
270 | noop_visit_where_clause(where_clause, self); | |
271 | } | |
272 | ||
273 | fn visit_where_predicate(&mut self, where_predicate: &mut WherePredicate) { | |
274 | noop_visit_where_predicate(where_predicate, self); | |
275 | } | |
276 | ||
277 | fn visit_vis(&mut self, vis: &mut Visibility) { | |
278 | noop_visit_vis(vis, self); | |
279 | } | |
280 | ||
281 | fn visit_id(&mut self, _id: &mut NodeId) { | |
282 | // Do nothing. | |
283 | } | |
284 | ||
285 | fn visit_span(&mut self, _sp: &mut Span) { | |
286 | // Do nothing. | |
287 | } | |
e1599b0c | 288 | |
6a06907d XL |
289 | fn flat_map_pat_field(&mut self, fp: PatField) -> SmallVec<[PatField; 1]> { |
290 | noop_flat_map_pat_field(fp, self) | |
e1599b0c | 291 | } |
04454e1e FG |
292 | |
293 | fn visit_inline_asm(&mut self, asm: &mut InlineAsm) { | |
294 | noop_visit_inline_asm(asm, self) | |
295 | } | |
296 | ||
297 | fn visit_inline_asm_sym(&mut self, sym: &mut InlineAsmSym) { | |
298 | noop_visit_inline_asm_sym(sym, self) | |
299 | } | |
9ffffee4 FG |
300 | |
301 | fn visit_format_args(&mut self, fmt: &mut FormatArgs) { | |
302 | noop_visit_format_args(fmt, self) | |
303 | } | |
9fa01778 XL |
304 | } |
305 | ||
306 | /// Use a map-style function (`FnOnce(T) -> T`) to overwrite a `&mut T`. Useful | |
307 | /// when using a `flat_map_*` or `filter_map_*` method within a `visit_` | |
a2a8927a | 308 | /// method. |
9fa01778 XL |
309 | // |
310 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
a2a8927a | 311 | pub fn visit_clobber<T: DummyAstNode>(t: &mut T, f: impl FnOnce(T) -> T) { |
532ac7d7 XL |
312 | unsafe { |
313 | // Safe because `t` is used in a read-only fashion by `read()` before | |
314 | // being overwritten by `write()`. | |
315 | let old_t = ptr::read(t); | |
a2a8927a XL |
316 | let new_t = |
317 | panic::catch_unwind(panic::AssertUnwindSafe(|| f(old_t))).unwrap_or_else(|err| { | |
318 | // Set `t` to some valid but possible meaningless value, | |
319 | // and pass the fatal error further. | |
320 | ptr::write(t, T::dummy()); | |
321 | panic::resume_unwind(err); | |
322 | }); | |
532ac7d7 XL |
323 | ptr::write(t, new_t); |
324 | } | |
9fa01778 XL |
325 | } |
326 | ||
327 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
328 | #[inline] | |
dfeec247 XL |
329 | pub fn visit_vec<T, F>(elems: &mut Vec<T>, mut visit_elem: F) |
330 | where | |
331 | F: FnMut(&mut T), | |
332 | { | |
9fa01778 XL |
333 | for elem in elems { |
334 | visit_elem(elem); | |
335 | } | |
336 | } | |
337 | ||
9ffffee4 FG |
338 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. |
339 | #[inline] | |
340 | pub fn visit_thin_vec<T, F>(elems: &mut ThinVec<T>, mut visit_elem: F) | |
341 | where | |
342 | F: FnMut(&mut T), | |
343 | { | |
344 | for elem in elems { | |
345 | visit_elem(elem); | |
346 | } | |
347 | } | |
348 | ||
9fa01778 XL |
349 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. |
350 | #[inline] | |
dfeec247 XL |
351 | pub fn visit_opt<T, F>(opt: &mut Option<T>, mut visit_elem: F) |
352 | where | |
353 | F: FnMut(&mut T), | |
354 | { | |
9fa01778 XL |
355 | if let Some(elem) = opt { |
356 | visit_elem(elem); | |
357 | } | |
358 | } | |
359 | ||
360 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
f2b60f7d | 361 | pub fn visit_attrs<T: MutVisitor>(attrs: &mut AttrVec, vis: &mut T) { |
9fa01778 XL |
362 | for attr in attrs.iter_mut() { |
363 | vis.visit_attribute(attr); | |
364 | } | |
365 | } | |
366 | ||
367 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
368 | pub fn visit_exprs<T: MutVisitor>(exprs: &mut Vec<P<Expr>>, vis: &mut T) { | |
369 | exprs.flat_map_in_place(|expr| vis.filter_map_expr(expr)) | |
370 | } | |
371 | ||
9ffffee4 FG |
372 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. |
373 | pub fn visit_thin_exprs<T: MutVisitor>(exprs: &mut ThinVec<P<Expr>>, vis: &mut T) { | |
374 | exprs.flat_map_in_place(|expr| vis.filter_map_expr(expr)) | |
375 | } | |
376 | ||
9fa01778 XL |
377 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. |
378 | pub fn visit_bounds<T: MutVisitor>(bounds: &mut GenericBounds, vis: &mut T) { | |
379 | visit_vec(bounds, |bound| vis.visit_param_bound(bound)); | |
380 | } | |
381 | ||
382 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
3dfed10e | 383 | pub fn visit_fn_sig<T: MutVisitor>(FnSig { header, decl, span }: &mut FnSig, vis: &mut T) { |
9fa01778 XL |
384 | vis.visit_fn_header(header); |
385 | vis.visit_fn_decl(decl); | |
3dfed10e | 386 | vis.visit_span(span); |
9fa01778 XL |
387 | } |
388 | ||
60c5eb7d | 389 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. |
487cf647 | 390 | pub fn visit_attr_args<T: MutVisitor>(args: &mut AttrArgs, vis: &mut T) { |
60c5eb7d | 391 | match args { |
487cf647 FG |
392 | AttrArgs::Empty => {} |
393 | AttrArgs::Delimited(args) => visit_delim_args(args, vis), | |
394 | AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => { | |
60c5eb7d | 395 | vis.visit_span(eq_span); |
04454e1e FG |
396 | vis.visit_expr(expr); |
397 | } | |
487cf647 | 398 | AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => { |
04454e1e | 399 | unreachable!("in literal form when visiting mac args eq: {:?}", lit) |
60c5eb7d XL |
400 | } |
401 | } | |
402 | } | |
403 | ||
487cf647 FG |
404 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. |
405 | pub fn visit_delim_args<T: MutVisitor>(args: &mut DelimArgs, vis: &mut T) { | |
406 | let DelimArgs { dspan, delim: _, tokens } = args; | |
407 | visit_delim_span(dspan, vis); | |
408 | visit_tts(tokens, vis); | |
409 | } | |
410 | ||
60c5eb7d XL |
411 | pub fn visit_delim_span<T: MutVisitor>(dspan: &mut DelimSpan, vis: &mut T) { |
412 | vis.visit_span(&mut dspan.open); | |
413 | vis.visit_span(&mut dspan.close); | |
414 | } | |
415 | ||
6a06907d XL |
416 | pub fn noop_flat_map_pat_field<T: MutVisitor>( |
417 | mut fp: PatField, | |
e1599b0c | 418 | vis: &mut T, |
6a06907d XL |
419 | ) -> SmallVec<[PatField; 1]> { |
420 | let PatField { attrs, id, ident, is_placeholder: _, is_shorthand: _, pat, span } = &mut fp; | |
e1599b0c XL |
421 | vis.visit_id(id); |
422 | vis.visit_ident(ident); | |
423 | vis.visit_pat(pat); | |
424 | vis.visit_span(span); | |
f2b60f7d | 425 | visit_attrs(attrs, vis); |
e1599b0c XL |
426 | smallvec![fp] |
427 | } | |
428 | ||
9fa01778 XL |
429 | pub fn noop_visit_use_tree<T: MutVisitor>(use_tree: &mut UseTree, vis: &mut T) { |
430 | let UseTree { prefix, kind, span } = use_tree; | |
431 | vis.visit_path(prefix); | |
432 | match kind { | |
487cf647 | 433 | UseTreeKind::Simple(rename) => visit_opt(rename, |rename| vis.visit_ident(rename)), |
9fa01778 XL |
434 | UseTreeKind::Nested(items) => { |
435 | for (tree, id) in items { | |
436 | vis.visit_use_tree(tree); | |
437 | vis.visit_id(id); | |
438 | } | |
439 | } | |
440 | UseTreeKind::Glob => {} | |
441 | } | |
442 | vis.visit_span(span); | |
443 | } | |
444 | ||
e1599b0c XL |
445 | pub fn noop_flat_map_arm<T: MutVisitor>(mut arm: Arm, vis: &mut T) -> SmallVec<[Arm; 1]> { |
446 | let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = &mut arm; | |
f2b60f7d | 447 | visit_attrs(attrs, vis); |
e1599b0c XL |
448 | vis.visit_id(id); |
449 | vis.visit_pat(pat); | |
dc9dc135 | 450 | visit_opt(guard, |guard| vis.visit_expr(guard)); |
9fa01778 | 451 | vis.visit_expr(body); |
dc9dc135 | 452 | vis.visit_span(span); |
e1599b0c | 453 | smallvec![arm] |
9fa01778 XL |
454 | } |
455 | ||
5099ac24 FG |
456 | pub fn noop_visit_constraint<T: MutVisitor>( |
457 | AssocConstraint { id, ident, gen_args, kind, span }: &mut AssocConstraint, | |
dfeec247 | 458 | vis: &mut T, |
dc9dc135 | 459 | ) { |
9fa01778 XL |
460 | vis.visit_id(id); |
461 | vis.visit_ident(ident); | |
487cf647 | 462 | if let Some(gen_args) = gen_args { |
fc512014 XL |
463 | vis.visit_generic_args(gen_args); |
464 | } | |
dc9dc135 | 465 | match kind { |
487cf647 | 466 | AssocConstraintKind::Equality { term } => match term { |
5099ac24 FG |
467 | Term::Ty(ty) => vis.visit_ty(ty), |
468 | Term::Const(c) => vis.visit_anon_const(c), | |
469 | }, | |
487cf647 | 470 | AssocConstraintKind::Bound { bounds } => visit_bounds(bounds, vis), |
dc9dc135 | 471 | } |
9fa01778 XL |
472 | vis.visit_span(span); |
473 | } | |
474 | ||
475 | pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) { | |
29967ef6 | 476 | let Ty { id, kind, span, tokens } = ty.deref_mut(); |
9fa01778 | 477 | vis.visit_id(id); |
e74abb32 | 478 | match kind { |
dfeec247 | 479 | TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err | TyKind::Never | TyKind::CVarArgs => {} |
9fa01778 XL |
480 | TyKind::Slice(ty) => vis.visit_ty(ty), |
481 | TyKind::Ptr(mt) => vis.visit_mt(mt), | |
9c376795 | 482 | TyKind::Ref(lt, mt) => { |
9fa01778 XL |
483 | visit_opt(lt, |lt| noop_visit_lifetime(lt, vis)); |
484 | vis.visit_mt(mt); | |
485 | } | |
486 | TyKind::BareFn(bft) => { | |
923072b8 | 487 | let BareFnTy { unsafety, ext: _, generic_params, decl, decl_span } = bft.deref_mut(); |
3c0e092e | 488 | visit_unsafety(unsafety, vis); |
e1599b0c | 489 | generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); |
9fa01778 | 490 | vis.visit_fn_decl(decl); |
923072b8 | 491 | vis.visit_span(decl_span); |
9fa01778 | 492 | } |
9ffffee4 | 493 | TyKind::Tup(tys) => visit_thin_vec(tys, |ty| vis.visit_ty(ty)), |
9fa01778 XL |
494 | TyKind::Paren(ty) => vis.visit_ty(ty), |
495 | TyKind::Path(qself, path) => { | |
496 | vis.visit_qself(qself); | |
497 | vis.visit_path(path); | |
498 | } | |
499 | TyKind::Array(ty, length) => { | |
500 | vis.visit_ty(ty); | |
501 | vis.visit_anon_const(length); | |
502 | } | |
503 | TyKind::Typeof(expr) => vis.visit_anon_const(expr), | |
dfeec247 XL |
504 | TyKind::TraitObject(bounds, _syntax) => { |
505 | visit_vec(bounds, |bound| vis.visit_param_bound(bound)) | |
506 | } | |
9fa01778 XL |
507 | TyKind::ImplTrait(id, bounds) => { |
508 | vis.visit_id(id); | |
509 | visit_vec(bounds, |bound| vis.visit_param_bound(bound)); | |
510 | } | |
29967ef6 | 511 | TyKind::MacCall(mac) => vis.visit_mac_call(mac), |
9fa01778 XL |
512 | } |
513 | vis.visit_span(span); | |
29967ef6 | 514 | visit_lazy_tts(tokens, vis); |
9fa01778 XL |
515 | } |
516 | ||
517 | pub fn noop_visit_foreign_mod<T: MutVisitor>(foreign_mod: &mut ForeignMod, vis: &mut T) { | |
3c0e092e XL |
518 | let ForeignMod { unsafety, abi: _, items } = foreign_mod; |
519 | visit_unsafety(unsafety, vis); | |
9fa01778 XL |
520 | items.flat_map_in_place(|item| vis.flat_map_foreign_item(item)); |
521 | } | |
522 | ||
dfeec247 XL |
523 | pub fn noop_flat_map_variant<T: MutVisitor>( |
524 | mut variant: Variant, | |
525 | visitor: &mut T, | |
526 | ) -> SmallVec<[Variant; 1]> { | |
60c5eb7d XL |
527 | let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = &mut variant; |
528 | visitor.visit_ident(ident); | |
529 | visitor.visit_vis(vis); | |
f2b60f7d | 530 | visit_attrs(attrs, visitor); |
60c5eb7d XL |
531 | visitor.visit_id(id); |
532 | visitor.visit_variant_data(data); | |
533 | visit_opt(disr_expr, |disr_expr| visitor.visit_anon_const(disr_expr)); | |
534 | visitor.visit_span(span); | |
e1599b0c | 535 | smallvec![variant] |
9fa01778 XL |
536 | } |
537 | ||
538 | pub fn noop_visit_ident<T: MutVisitor>(Ident { name: _, span }: &mut Ident, vis: &mut T) { | |
539 | vis.visit_span(span); | |
540 | } | |
541 | ||
29967ef6 | 542 | pub fn noop_visit_path<T: MutVisitor>(Path { segments, span, tokens }: &mut Path, vis: &mut T) { |
9fa01778 XL |
543 | vis.visit_span(span); |
544 | for PathSegment { ident, id, args } in segments { | |
545 | vis.visit_ident(ident); | |
546 | vis.visit_id(id); | |
547 | visit_opt(args, |args| vis.visit_generic_args(args)); | |
548 | } | |
29967ef6 | 549 | visit_lazy_tts(tokens, vis); |
9fa01778 XL |
550 | } |
551 | ||
487cf647 FG |
552 | pub fn noop_visit_qself<T: MutVisitor>(qself: &mut Option<P<QSelf>>, vis: &mut T) { |
553 | visit_opt(qself, |qself| { | |
554 | let QSelf { ty, path_span, position: _ } = &mut **qself; | |
9fa01778 XL |
555 | vis.visit_ty(ty); |
556 | vis.visit_span(path_span); | |
557 | }) | |
558 | } | |
559 | ||
560 | pub fn noop_visit_generic_args<T: MutVisitor>(generic_args: &mut GenericArgs, vis: &mut T) { | |
561 | match generic_args { | |
562 | GenericArgs::AngleBracketed(data) => vis.visit_angle_bracketed_parameter_data(data), | |
563 | GenericArgs::Parenthesized(data) => vis.visit_parenthesized_parameter_data(data), | |
564 | } | |
565 | } | |
566 | ||
567 | pub fn noop_visit_generic_arg<T: MutVisitor>(arg: &mut GenericArg, vis: &mut T) { | |
568 | match arg { | |
569 | GenericArg::Lifetime(lt) => vis.visit_lifetime(lt), | |
570 | GenericArg::Type(ty) => vis.visit_ty(ty), | |
571 | GenericArg::Const(ct) => vis.visit_anon_const(ct), | |
572 | } | |
573 | } | |
574 | ||
dfeec247 XL |
575 | pub fn noop_visit_angle_bracketed_parameter_data<T: MutVisitor>( |
576 | data: &mut AngleBracketedArgs, | |
577 | vis: &mut T, | |
578 | ) { | |
ba9703b0 | 579 | let AngleBracketedArgs { args, span } = data; |
9ffffee4 | 580 | visit_thin_vec(args, |arg| match arg { |
ba9703b0 | 581 | AngleBracketedArg::Arg(arg) => vis.visit_generic_arg(arg), |
5099ac24 | 582 | AngleBracketedArg::Constraint(constraint) => vis.visit_constraint(constraint), |
ba9703b0 | 583 | }); |
9fa01778 XL |
584 | vis.visit_span(span); |
585 | } | |
586 | ||
dfeec247 XL |
587 | pub fn noop_visit_parenthesized_parameter_data<T: MutVisitor>( |
588 | args: &mut ParenthesizedArgs, | |
589 | vis: &mut T, | |
590 | ) { | |
5869c6ff | 591 | let ParenthesizedArgs { inputs, output, span, .. } = args; |
9ffffee4 | 592 | visit_thin_vec(inputs, |input| vis.visit_ty(input)); |
dfeec247 | 593 | noop_visit_fn_ret_ty(output, vis); |
9fa01778 XL |
594 | vis.visit_span(span); |
595 | } | |
596 | ||
597 | pub fn noop_visit_local<T: MutVisitor>(local: &mut P<Local>, vis: &mut T) { | |
94222f64 | 598 | let Local { id, pat, ty, kind, span, attrs, tokens } = local.deref_mut(); |
9fa01778 XL |
599 | vis.visit_id(id); |
600 | vis.visit_pat(pat); | |
601 | visit_opt(ty, |ty| vis.visit_ty(ty)); | |
94222f64 XL |
602 | match kind { |
603 | LocalKind::Decl => {} | |
604 | LocalKind::Init(init) => { | |
605 | vis.visit_expr(init); | |
606 | } | |
607 | LocalKind::InitElse(init, els) => { | |
608 | vis.visit_expr(init); | |
609 | vis.visit_block(els); | |
610 | } | |
611 | } | |
9fa01778 | 612 | vis.visit_span(span); |
f2b60f7d | 613 | visit_attrs(attrs, vis); |
fc512014 | 614 | visit_lazy_tts(tokens, vis); |
9fa01778 XL |
615 | } |
616 | ||
617 | pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) { | |
60c5eb7d XL |
618 | let Attribute { kind, id: _, style: _, span } = attr; |
619 | match kind { | |
f2b60f7d FG |
620 | AttrKind::Normal(normal) => { |
621 | let NormalAttr { item: AttrItem { path, args, tokens }, tokens: attr_tokens } = | |
622 | &mut **normal; | |
60c5eb7d | 623 | vis.visit_path(path); |
487cf647 | 624 | visit_attr_args(args, vis); |
29967ef6 XL |
625 | visit_lazy_tts(tokens, vis); |
626 | visit_lazy_tts(attr_tokens, vis); | |
60c5eb7d | 627 | } |
3dfed10e | 628 | AttrKind::DocComment(..) => {} |
60c5eb7d | 629 | } |
9fa01778 XL |
630 | vis.visit_span(span); |
631 | } | |
632 | ||
ba9703b0 XL |
633 | pub fn noop_visit_mac<T: MutVisitor>(mac: &mut MacCall, vis: &mut T) { |
634 | let MacCall { path, args, prior_type_ascription: _ } = mac; | |
9fa01778 | 635 | vis.visit_path(path); |
487cf647 | 636 | visit_delim_args(args, vis); |
9fa01778 XL |
637 | } |
638 | ||
639 | pub fn noop_visit_macro_def<T: MutVisitor>(macro_def: &mut MacroDef, vis: &mut T) { | |
ba9703b0 | 640 | let MacroDef { body, macro_rules: _ } = macro_def; |
487cf647 | 641 | visit_delim_args(body, vis); |
9fa01778 XL |
642 | } |
643 | ||
644 | pub fn noop_visit_meta_list_item<T: MutVisitor>(li: &mut NestedMetaItem, vis: &mut T) { | |
532ac7d7 XL |
645 | match li { |
646 | NestedMetaItem::MetaItem(mi) => vis.visit_meta_item(mi), | |
487cf647 | 647 | NestedMetaItem::Lit(_lit) => {} |
9fa01778 | 648 | } |
9fa01778 XL |
649 | } |
650 | ||
651 | pub fn noop_visit_meta_item<T: MutVisitor>(mi: &mut MetaItem, vis: &mut T) { | |
e74abb32 XL |
652 | let MetaItem { path: _, kind, span } = mi; |
653 | match kind { | |
9fa01778 | 654 | MetaItemKind::Word => {} |
9ffffee4 | 655 | MetaItemKind::List(mis) => visit_thin_vec(mis, |mi| vis.visit_meta_list_item(mi)), |
9fa01778 XL |
656 | MetaItemKind::NameValue(_s) => {} |
657 | } | |
658 | vis.visit_span(span); | |
659 | } | |
660 | ||
e1599b0c XL |
661 | pub fn noop_flat_map_param<T: MutVisitor>(mut param: Param, vis: &mut T) -> SmallVec<[Param; 1]> { |
662 | let Param { attrs, id, pat, span, ty, is_placeholder: _ } = &mut param; | |
9fa01778 | 663 | vis.visit_id(id); |
f2b60f7d | 664 | visit_attrs(attrs, vis); |
9fa01778 | 665 | vis.visit_pat(pat); |
416331ca | 666 | vis.visit_span(span); |
9fa01778 | 667 | vis.visit_ty(ty); |
e1599b0c | 668 | smallvec![param] |
9fa01778 XL |
669 | } |
670 | ||
cdc7bbd5 | 671 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. |
f2b60f7d | 672 | pub fn visit_attr_tt<T: MutVisitor>(tt: &mut AttrTokenTree, vis: &mut T) { |
cdc7bbd5 | 673 | match tt { |
f2b60f7d | 674 | AttrTokenTree::Token(token, _) => { |
cdc7bbd5 XL |
675 | visit_token(token, vis); |
676 | } | |
f2b60f7d | 677 | AttrTokenTree::Delimited(DelimSpan { open, close }, _delim, tts) => { |
cdc7bbd5 XL |
678 | vis.visit_span(open); |
679 | vis.visit_span(close); | |
f2b60f7d | 680 | visit_attr_tts(tts, vis); |
cdc7bbd5 | 681 | } |
f2b60f7d | 682 | AttrTokenTree::Attributes(data) => { |
cdc7bbd5 XL |
683 | for attr in &mut *data.attrs { |
684 | match &mut attr.kind { | |
f2b60f7d FG |
685 | AttrKind::Normal(normal) => { |
686 | visit_lazy_tts(&mut normal.tokens, vis); | |
cdc7bbd5 XL |
687 | } |
688 | AttrKind::DocComment(..) => { | |
689 | vis.visit_span(&mut attr.span); | |
690 | } | |
691 | } | |
692 | } | |
693 | visit_lazy_tts_opt_mut(Some(&mut data.tokens), vis); | |
694 | } | |
695 | } | |
696 | } | |
697 | ||
29967ef6 XL |
698 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. |
699 | pub fn visit_tt<T: MutVisitor>(tt: &mut TokenTree, vis: &mut T) { | |
9fa01778 | 700 | match tt { |
064997fb | 701 | TokenTree::Token(token, _) => { |
29967ef6 | 702 | visit_token(token, vis); |
9fa01778 XL |
703 | } |
704 | TokenTree::Delimited(DelimSpan { open, close }, _delim, tts) => { | |
705 | vis.visit_span(open); | |
706 | vis.visit_span(close); | |
29967ef6 | 707 | visit_tts(tts, vis); |
9fa01778 XL |
708 | } |
709 | } | |
710 | } | |
711 | ||
29967ef6 XL |
712 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. |
713 | pub fn visit_tts<T: MutVisitor>(TokenStream(tts): &mut TokenStream, vis: &mut T) { | |
3c0e092e | 714 | if T::VISIT_TOKENS && !tts.is_empty() { |
29967ef6 | 715 | let tts = Lrc::make_mut(tts); |
064997fb | 716 | visit_vec(tts, |tree| visit_tt(tree, vis)); |
29967ef6 XL |
717 | } |
718 | } | |
719 | ||
f2b60f7d | 720 | pub fn visit_attr_tts<T: MutVisitor>(AttrTokenStream(tts): &mut AttrTokenStream, vis: &mut T) { |
3c0e092e | 721 | if T::VISIT_TOKENS && !tts.is_empty() { |
cdc7bbd5 | 722 | let tts = Lrc::make_mut(tts); |
f2b60f7d | 723 | visit_vec(tts, |tree| visit_attr_tt(tree, vis)); |
cdc7bbd5 XL |
724 | } |
725 | } | |
726 | ||
f2b60f7d FG |
727 | pub fn visit_lazy_tts_opt_mut<T: MutVisitor>( |
728 | lazy_tts: Option<&mut LazyAttrTokenStream>, | |
729 | vis: &mut T, | |
730 | ) { | |
3c0e092e | 731 | if T::VISIT_TOKENS { |
cdc7bbd5 | 732 | if let Some(lazy_tts) = lazy_tts { |
f2b60f7d FG |
733 | let mut tts = lazy_tts.to_attr_token_stream(); |
734 | visit_attr_tts(&mut tts, vis); | |
735 | *lazy_tts = LazyAttrTokenStream::new(tts); | |
cdc7bbd5 | 736 | } |
29967ef6 | 737 | } |
9fa01778 XL |
738 | } |
739 | ||
f2b60f7d | 740 | pub fn visit_lazy_tts<T: MutVisitor>(lazy_tts: &mut Option<LazyAttrTokenStream>, vis: &mut T) { |
cdc7bbd5 XL |
741 | visit_lazy_tts_opt_mut(lazy_tts.as_mut(), vis); |
742 | } | |
743 | ||
487cf647 FG |
744 | /// Applies ident visitor if it's an ident; applies other visits to interpolated nodes. |
745 | /// In practice the ident part is not actually used by specific visitors right now, | |
746 | /// but there's a test below checking that it works. | |
29967ef6 | 747 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. |
29967ef6 | 748 | pub fn visit_token<T: MutVisitor>(t: &mut Token, vis: &mut T) { |
dc9dc135 XL |
749 | let Token { kind, span } = t; |
750 | match kind { | |
751 | token::Ident(name, _) | token::Lifetime(name) => { | |
752 | let mut ident = Ident::new(*name, *span); | |
753 | vis.visit_ident(&mut ident); | |
754 | *name = ident.name; | |
755 | *span = ident.span; | |
e1599b0c | 756 | return; // Avoid visiting the span for the second time. |
dc9dc135 | 757 | } |
9fa01778 | 758 | token::Interpolated(nt) => { |
487cf647 | 759 | visit_nonterminal(Lrc::make_mut(nt), vis); |
9fa01778 XL |
760 | } |
761 | _ => {} | |
762 | } | |
dc9dc135 | 763 | vis.visit_span(span); |
9fa01778 XL |
764 | } |
765 | ||
29967ef6 | 766 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. |
e1599b0c | 767 | /// Applies the visitor to elements of interpolated nodes. |
9fa01778 XL |
768 | // |
769 | // N.B., this can occur only when applying a visitor to partially expanded | |
770 | // code, where parsed pieces have gotten implanted ito *other* macro | |
771 | // invocations. This is relevant for macro hygiene, but possibly not elsewhere. | |
772 | // | |
773 | // One problem here occurs because the types for flat_map_item, flat_map_stmt, | |
e1599b0c | 774 | // etc., allow the visitor to return *multiple* items; this is a problem for the |
9fa01778 XL |
775 | // nodes here, because they insist on having exactly one piece. One solution |
776 | // would be to mangle the MutVisitor trait to include one-to-many and | |
777 | // one-to-one versions of these entry points, but that would probably confuse a | |
778 | // lot of people and help very few. Instead, I'm just going to put in dynamic | |
779 | // checks. I think the performance impact of this will be pretty much | |
e1599b0c | 780 | // nonexistent. The danger is that someone will apply a `MutVisitor` to a |
9fa01778 | 781 | // partially expanded node, and will be confused by the fact that their |
e1599b0c | 782 | // `flat_map_item` or `flat_map_stmt` isn't getting called on `NtItem` or `NtStmt` |
9fa01778 XL |
783 | // nodes. Hopefully they'll wind up reading this comment, and doing something |
784 | // appropriate. | |
785 | // | |
e1599b0c | 786 | // BTW, design choice: I considered just changing the type of, e.g., `NtItem` to |
9fa01778 | 787 | // contain multiple items, but decided against it when I looked at |
e1599b0c | 788 | // `parse_item_or_view_item` and tried to figure out what I would do with |
9fa01778 | 789 | // multiple items there.... |
04454e1e | 790 | pub fn visit_nonterminal<T: MutVisitor>(nt: &mut token::Nonterminal, vis: &mut T) { |
9fa01778 | 791 | match nt { |
dfeec247 XL |
792 | token::NtItem(item) => visit_clobber(item, |item| { |
793 | // This is probably okay, because the only visitors likely to | |
794 | // peek inside interpolated nodes will be renamings/markings, | |
795 | // which map single items to single items. | |
796 | vis.flat_map_item(item).expect_one("expected visitor to produce exactly one item") | |
797 | }), | |
9fa01778 | 798 | token::NtBlock(block) => vis.visit_block(block), |
dfeec247 XL |
799 | token::NtStmt(stmt) => visit_clobber(stmt, |stmt| { |
800 | // See reasoning above. | |
04454e1e FG |
801 | stmt.map(|stmt| { |
802 | vis.flat_map_stmt(stmt).expect_one("expected visitor to produce exactly one item") | |
803 | }) | |
dfeec247 | 804 | }), |
9fa01778 XL |
805 | token::NtPat(pat) => vis.visit_pat(pat), |
806 | token::NtExpr(expr) => vis.visit_expr(expr), | |
807 | token::NtTy(ty) => vis.visit_ty(ty), | |
808 | token::NtIdent(ident, _is_raw) => vis.visit_ident(ident), | |
809 | token::NtLifetime(ident) => vis.visit_ident(ident), | |
810 | token::NtLiteral(expr) => vis.visit_expr(expr), | |
74b04a01 | 811 | token::NtMeta(item) => { |
29967ef6 | 812 | let AttrItem { path, args, tokens } = item.deref_mut(); |
e74abb32 | 813 | vis.visit_path(path); |
487cf647 | 814 | visit_attr_args(args, vis); |
29967ef6 | 815 | visit_lazy_tts(tokens, vis); |
e74abb32 | 816 | } |
9fa01778 | 817 | token::NtPath(path) => vis.visit_path(path), |
9fa01778 | 818 | token::NtVis(visib) => vis.visit_vis(visib), |
9fa01778 XL |
819 | } |
820 | } | |
821 | ||
3c0e092e XL |
822 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. |
823 | pub fn visit_defaultness<T: MutVisitor>(defaultness: &mut Defaultness, vis: &mut T) { | |
824 | match defaultness { | |
825 | Defaultness::Default(span) => vis.visit_span(span), | |
826 | Defaultness::Final => {} | |
827 | } | |
828 | } | |
829 | ||
830 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
831 | pub fn visit_unsafety<T: MutVisitor>(unsafety: &mut Unsafe, vis: &mut T) { | |
832 | match unsafety { | |
833 | Unsafe::Yes(span) => vis.visit_span(span), | |
834 | Unsafe::No => {} | |
835 | } | |
836 | } | |
837 | ||
838 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
839 | pub fn visit_polarity<T: MutVisitor>(polarity: &mut ImplPolarity, vis: &mut T) { | |
840 | match polarity { | |
841 | ImplPolarity::Positive => {} | |
842 | ImplPolarity::Negative(span) => vis.visit_span(span), | |
843 | } | |
844 | } | |
845 | ||
846 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
847 | pub fn visit_constness<T: MutVisitor>(constness: &mut Const, vis: &mut T) { | |
848 | match constness { | |
849 | Const::Yes(span) => vis.visit_span(span), | |
850 | Const::No => {} | |
851 | } | |
852 | } | |
853 | ||
064997fb FG |
854 | pub fn noop_visit_closure_binder<T: MutVisitor>(binder: &mut ClosureBinder, vis: &mut T) { |
855 | match binder { | |
856 | ClosureBinder::NotPresent => {} | |
857 | ClosureBinder::For { span: _, generic_params } => { | |
9ffffee4 | 858 | generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); |
064997fb FG |
859 | } |
860 | } | |
861 | } | |
862 | ||
74b04a01 | 863 | pub fn noop_visit_asyncness<T: MutVisitor>(asyncness: &mut Async, vis: &mut T) { |
9fa01778 | 864 | match asyncness { |
74b04a01 | 865 | Async::Yes { span: _, closure_id, return_impl_trait_id } => { |
9fa01778 XL |
866 | vis.visit_id(closure_id); |
867 | vis.visit_id(return_impl_trait_id); | |
868 | } | |
74b04a01 | 869 | Async::No => {} |
9fa01778 XL |
870 | } |
871 | } | |
872 | ||
873 | pub fn noop_visit_fn_decl<T: MutVisitor>(decl: &mut P<FnDecl>, vis: &mut T) { | |
e74abb32 | 874 | let FnDecl { inputs, output } = decl.deref_mut(); |
e1599b0c | 875 | inputs.flat_map_in_place(|param| vis.flat_map_param(param)); |
dfeec247 XL |
876 | noop_visit_fn_ret_ty(output, vis); |
877 | } | |
878 | ||
74b04a01 | 879 | pub fn noop_visit_fn_ret_ty<T: MutVisitor>(fn_ret_ty: &mut FnRetTy, vis: &mut T) { |
dfeec247 | 880 | match fn_ret_ty { |
74b04a01 XL |
881 | FnRetTy::Default(span) => vis.visit_span(span), |
882 | FnRetTy::Ty(ty) => vis.visit_ty(ty), | |
9fa01778 XL |
883 | } |
884 | } | |
885 | ||
886 | pub fn noop_visit_param_bound<T: MutVisitor>(pb: &mut GenericBound, vis: &mut T) { | |
887 | match pb { | |
888 | GenericBound::Trait(ty, _modifier) => vis.visit_poly_trait_ref(ty), | |
889 | GenericBound::Outlives(lifetime) => noop_visit_lifetime(lifetime, vis), | |
890 | } | |
891 | } | |
892 | ||
e1599b0c XL |
893 | pub fn noop_flat_map_generic_param<T: MutVisitor>( |
894 | mut param: GenericParam, | |
dfeec247 XL |
895 | vis: &mut T, |
896 | ) -> SmallVec<[GenericParam; 1]> { | |
04454e1e | 897 | let GenericParam { id, ident, attrs, bounds, kind, colon_span, is_placeholder: _ } = &mut param; |
9fa01778 XL |
898 | vis.visit_id(id); |
899 | vis.visit_ident(ident); | |
487cf647 | 900 | if let Some(colon_span) = colon_span { |
04454e1e FG |
901 | vis.visit_span(colon_span); |
902 | } | |
f2b60f7d | 903 | visit_attrs(attrs, vis); |
9fa01778 XL |
904 | visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis)); |
905 | match kind { | |
906 | GenericParamKind::Lifetime => {} | |
907 | GenericParamKind::Type { default } => { | |
908 | visit_opt(default, |default| vis.visit_ty(default)); | |
909 | } | |
5869c6ff | 910 | GenericParamKind::Const { ty, kw_span: _, default } => { |
9fa01778 | 911 | vis.visit_ty(ty); |
5869c6ff | 912 | visit_opt(default, |default| vis.visit_anon_const(default)); |
9fa01778 XL |
913 | } |
914 | } | |
e1599b0c | 915 | smallvec![param] |
9fa01778 XL |
916 | } |
917 | ||
918 | pub fn noop_visit_label<T: MutVisitor>(Label { ident }: &mut Label, vis: &mut T) { | |
919 | vis.visit_ident(ident); | |
920 | } | |
921 | ||
922 | fn noop_visit_lifetime<T: MutVisitor>(Lifetime { id, ident }: &mut Lifetime, vis: &mut T) { | |
923 | vis.visit_id(id); | |
924 | vis.visit_ident(ident); | |
925 | } | |
926 | ||
927 | pub fn noop_visit_generics<T: MutVisitor>(generics: &mut Generics, vis: &mut T) { | |
928 | let Generics { params, where_clause, span } = generics; | |
e1599b0c | 929 | params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); |
9fa01778 XL |
930 | vis.visit_where_clause(where_clause); |
931 | vis.visit_span(span); | |
932 | } | |
933 | ||
934 | pub fn noop_visit_where_clause<T: MutVisitor>(wc: &mut WhereClause, vis: &mut T) { | |
f035d41b | 935 | let WhereClause { has_where_token: _, predicates, span } = wc; |
9ffffee4 | 936 | visit_thin_vec(predicates, |predicate| vis.visit_where_predicate(predicate)); |
9fa01778 XL |
937 | vis.visit_span(span); |
938 | } | |
939 | ||
940 | pub fn noop_visit_where_predicate<T: MutVisitor>(pred: &mut WherePredicate, vis: &mut T) { | |
941 | match pred { | |
942 | WherePredicate::BoundPredicate(bp) => { | |
943 | let WhereBoundPredicate { span, bound_generic_params, bounded_ty, bounds } = bp; | |
944 | vis.visit_span(span); | |
e1599b0c | 945 | bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); |
9fa01778 XL |
946 | vis.visit_ty(bounded_ty); |
947 | visit_vec(bounds, |bound| vis.visit_param_bound(bound)); | |
948 | } | |
949 | WherePredicate::RegionPredicate(rp) => { | |
950 | let WhereRegionPredicate { span, lifetime, bounds } = rp; | |
951 | vis.visit_span(span); | |
952 | noop_visit_lifetime(lifetime, vis); | |
953 | visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis)); | |
954 | } | |
955 | WherePredicate::EqPredicate(ep) => { | |
f2b60f7d | 956 | let WhereEqPredicate { span, lhs_ty, rhs_ty } = ep; |
9fa01778 XL |
957 | vis.visit_span(span); |
958 | vis.visit_ty(lhs_ty); | |
959 | vis.visit_ty(rhs_ty); | |
960 | } | |
961 | } | |
962 | } | |
963 | ||
964 | pub fn noop_visit_variant_data<T: MutVisitor>(vdata: &mut VariantData, vis: &mut T) { | |
965 | match vdata { | |
e1599b0c | 966 | VariantData::Struct(fields, ..) => { |
6a06907d | 967 | fields.flat_map_in_place(|field| vis.flat_map_field_def(field)); |
dfeec247 | 968 | } |
9fa01778 | 969 | VariantData::Tuple(fields, id) => { |
6a06907d | 970 | fields.flat_map_in_place(|field| vis.flat_map_field_def(field)); |
9fa01778 | 971 | vis.visit_id(id); |
dfeec247 | 972 | } |
9fa01778 XL |
973 | VariantData::Unit(id) => vis.visit_id(id), |
974 | } | |
975 | } | |
976 | ||
977 | pub fn noop_visit_trait_ref<T: MutVisitor>(TraitRef { path, ref_id }: &mut TraitRef, vis: &mut T) { | |
978 | vis.visit_path(path); | |
979 | vis.visit_id(ref_id); | |
980 | } | |
981 | ||
982 | pub fn noop_visit_poly_trait_ref<T: MutVisitor>(p: &mut PolyTraitRef, vis: &mut T) { | |
983 | let PolyTraitRef { bound_generic_params, trait_ref, span } = p; | |
e1599b0c | 984 | bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); |
9fa01778 XL |
985 | vis.visit_trait_ref(trait_ref); |
986 | vis.visit_span(span); | |
987 | } | |
988 | ||
6a06907d XL |
989 | pub fn noop_flat_map_field_def<T: MutVisitor>( |
990 | mut fd: FieldDef, | |
dfeec247 | 991 | visitor: &mut T, |
6a06907d XL |
992 | ) -> SmallVec<[FieldDef; 1]> { |
993 | let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _ } = &mut fd; | |
9fa01778 XL |
994 | visitor.visit_span(span); |
995 | visit_opt(ident, |ident| visitor.visit_ident(ident)); | |
996 | visitor.visit_vis(vis); | |
997 | visitor.visit_id(id); | |
998 | visitor.visit_ty(ty); | |
f2b60f7d | 999 | visit_attrs(attrs, visitor); |
6a06907d | 1000 | smallvec![fd] |
9fa01778 XL |
1001 | } |
1002 | ||
6a06907d XL |
1003 | pub fn noop_flat_map_expr_field<T: MutVisitor>( |
1004 | mut f: ExprField, | |
1005 | vis: &mut T, | |
1006 | ) -> SmallVec<[ExprField; 1]> { | |
1007 | let ExprField { ident, expr, span, is_shorthand: _, attrs, id, is_placeholder: _ } = &mut f; | |
9fa01778 XL |
1008 | vis.visit_ident(ident); |
1009 | vis.visit_expr(expr); | |
e1599b0c | 1010 | vis.visit_id(id); |
9fa01778 | 1011 | vis.visit_span(span); |
f2b60f7d | 1012 | visit_attrs(attrs, vis); |
e1599b0c | 1013 | smallvec![f] |
9fa01778 XL |
1014 | } |
1015 | ||
1016 | pub fn noop_visit_mt<T: MutVisitor>(MutTy { ty, mutbl: _ }: &mut MutTy, vis: &mut T) { | |
1017 | vis.visit_ty(ty); | |
1018 | } | |
1019 | ||
1020 | pub fn noop_visit_block<T: MutVisitor>(block: &mut P<Block>, vis: &mut T) { | |
94222f64 | 1021 | let Block { id, stmts, rules: _, span, tokens, could_be_bare_literal: _ } = block.deref_mut(); |
9fa01778 XL |
1022 | vis.visit_id(id); |
1023 | stmts.flat_map_in_place(|stmt| vis.flat_map_stmt(stmt)); | |
1024 | vis.visit_span(span); | |
29967ef6 | 1025 | visit_lazy_tts(tokens, vis); |
9fa01778 XL |
1026 | } |
1027 | ||
1028 | pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) { | |
1029 | match kind { | |
1030 | ItemKind::ExternCrate(_orig_name) => {} | |
1031 | ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree), | |
353b0b11 | 1032 | ItemKind::Static(box StaticItem { ty, mutability: _, expr }) => { |
9fa01778 | 1033 | vis.visit_ty(ty); |
74b04a01 | 1034 | visit_opt(expr, |expr| vis.visit_expr(expr)); |
9fa01778 | 1035 | } |
353b0b11 FG |
1036 | ItemKind::Const(item) => { |
1037 | visit_const_item(item, vis); | |
3c0e092e XL |
1038 | } |
1039 | ItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { | |
1040 | visit_defaultness(defaultness, vis); | |
60c5eb7d | 1041 | visit_fn_sig(sig, vis); |
9fa01778 | 1042 | vis.visit_generics(generics); |
74b04a01 | 1043 | visit_opt(body, |body| vis.visit_block(body)); |
9fa01778 | 1044 | } |
3c0e092e XL |
1045 | ItemKind::Mod(unsafety, mod_kind) => { |
1046 | visit_unsafety(unsafety, vis); | |
1047 | match mod_kind { | |
5e7ed085 | 1048 | ModKind::Loaded(items, _inline, ModSpans { inner_span, inject_use_span }) => { |
3c0e092e | 1049 | vis.visit_span(inner_span); |
5e7ed085 | 1050 | vis.visit_span(inject_use_span); |
3c0e092e XL |
1051 | items.flat_map_in_place(|item| vis.flat_map_item(item)); |
1052 | } | |
1053 | ModKind::Unloaded => {} | |
6a06907d | 1054 | } |
3c0e092e | 1055 | } |
9fa01778 | 1056 | ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm), |
04454e1e | 1057 | ItemKind::GlobalAsm(asm) => vis.visit_inline_asm(asm), |
5e7ed085 FG |
1058 | ItemKind::TyAlias(box TyAlias { |
1059 | defaultness, generics, where_clauses, bounds, ty, .. | |
1060 | }) => { | |
3c0e092e | 1061 | visit_defaultness(defaultness, vis); |
9fa01778 | 1062 | vis.visit_generics(generics); |
5e7ed085 FG |
1063 | vis.visit_span(&mut where_clauses.0.1); |
1064 | vis.visit_span(&mut where_clauses.1.1); | |
74b04a01 XL |
1065 | visit_bounds(bounds, vis); |
1066 | visit_opt(ty, |ty| vis.visit_ty(ty)); | |
9fa01778 | 1067 | } |
9fa01778 | 1068 | ItemKind::Enum(EnumDef { variants }, generics) => { |
e1599b0c | 1069 | variants.flat_map_in_place(|variant| vis.flat_map_variant(variant)); |
9fa01778 XL |
1070 | vis.visit_generics(generics); |
1071 | } | |
dfeec247 | 1072 | ItemKind::Struct(variant_data, generics) | ItemKind::Union(variant_data, generics) => { |
9fa01778 XL |
1073 | vis.visit_variant_data(variant_data); |
1074 | vis.visit_generics(generics); | |
1075 | } | |
3c0e092e XL |
1076 | ItemKind::Impl(box Impl { |
1077 | defaultness, | |
1078 | unsafety, | |
dfeec247 | 1079 | generics, |
3c0e092e XL |
1080 | constness, |
1081 | polarity, | |
dfeec247 XL |
1082 | of_trait, |
1083 | self_ty, | |
1084 | items, | |
5869c6ff | 1085 | }) => { |
3c0e092e XL |
1086 | visit_defaultness(defaultness, vis); |
1087 | visit_unsafety(unsafety, vis); | |
9fa01778 | 1088 | vis.visit_generics(generics); |
3c0e092e XL |
1089 | visit_constness(constness, vis); |
1090 | visit_polarity(polarity, vis); | |
dfeec247 XL |
1091 | visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref)); |
1092 | vis.visit_ty(self_ty); | |
9fa01778 XL |
1093 | items.flat_map_in_place(|item| vis.flat_map_impl_item(item)); |
1094 | } | |
3c0e092e XL |
1095 | ItemKind::Trait(box Trait { unsafety, is_auto: _, generics, bounds, items }) => { |
1096 | visit_unsafety(unsafety, vis); | |
9fa01778 XL |
1097 | vis.visit_generics(generics); |
1098 | visit_bounds(bounds, vis); | |
1099 | items.flat_map_in_place(|item| vis.flat_map_trait_item(item)); | |
1100 | } | |
1101 | ItemKind::TraitAlias(generics, bounds) => { | |
1102 | vis.visit_generics(generics); | |
1103 | visit_bounds(bounds, vis); | |
1104 | } | |
29967ef6 | 1105 | ItemKind::MacCall(m) => vis.visit_mac_call(m), |
9fa01778 XL |
1106 | ItemKind::MacroDef(def) => vis.visit_macro_def(def), |
1107 | } | |
1108 | } | |
1109 | ||
dfeec247 | 1110 | pub fn noop_flat_map_assoc_item<T: MutVisitor>( |
74b04a01 | 1111 | mut item: P<AssocItem>, |
dfeec247 | 1112 | visitor: &mut T, |
74b04a01 | 1113 | ) -> SmallVec<[P<AssocItem>; 1]> { |
29967ef6 | 1114 | let Item { id, ident, vis, attrs, kind, span, tokens } = item.deref_mut(); |
60c5eb7d XL |
1115 | visitor.visit_id(id); |
1116 | visitor.visit_ident(ident); | |
1117 | visitor.visit_vis(vis); | |
1118 | visit_attrs(attrs, visitor); | |
e74abb32 | 1119 | match kind { |
353b0b11 FG |
1120 | AssocItemKind::Const(item) => { |
1121 | visit_const_item(item, visitor); | |
9fa01778 | 1122 | } |
3c0e092e XL |
1123 | AssocItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { |
1124 | visit_defaultness(defaultness, visitor); | |
74b04a01 | 1125 | visitor.visit_generics(generics); |
60c5eb7d XL |
1126 | visit_fn_sig(sig, visitor); |
1127 | visit_opt(body, |body| visitor.visit_block(body)); | |
9fa01778 | 1128 | } |
2b03887a | 1129 | AssocItemKind::Type(box TyAlias { |
5e7ed085 FG |
1130 | defaultness, |
1131 | generics, | |
1132 | where_clauses, | |
1133 | bounds, | |
1134 | ty, | |
1135 | .. | |
1136 | }) => { | |
3c0e092e | 1137 | visit_defaultness(defaultness, visitor); |
74b04a01 | 1138 | visitor.visit_generics(generics); |
5e7ed085 FG |
1139 | visitor.visit_span(&mut where_clauses.0.1); |
1140 | visitor.visit_span(&mut where_clauses.1.1); | |
60c5eb7d | 1141 | visit_bounds(bounds, visitor); |
dfeec247 | 1142 | visit_opt(ty, |ty| visitor.visit_ty(ty)); |
9fa01778 | 1143 | } |
29967ef6 | 1144 | AssocItemKind::MacCall(mac) => visitor.visit_mac_call(mac), |
9fa01778 XL |
1145 | } |
1146 | visitor.visit_span(span); | |
29967ef6 | 1147 | visit_lazy_tts(tokens, visitor); |
9fa01778 XL |
1148 | smallvec![item] |
1149 | } | |
1150 | ||
353b0b11 FG |
1151 | fn visit_const_item<T: MutVisitor>( |
1152 | ConstItem { defaultness, ty, expr }: &mut ConstItem, | |
1153 | visitor: &mut T, | |
1154 | ) { | |
1155 | visit_defaultness(defaultness, visitor); | |
1156 | visitor.visit_ty(ty); | |
1157 | visit_opt(expr, |expr| visitor.visit_expr(expr)); | |
1158 | } | |
1159 | ||
9fa01778 | 1160 | pub fn noop_visit_fn_header<T: MutVisitor>(header: &mut FnHeader, vis: &mut T) { |
3c0e092e XL |
1161 | let FnHeader { unsafety, asyncness, constness, ext: _ } = header; |
1162 | visit_constness(constness, vis); | |
74b04a01 | 1163 | vis.visit_asyncness(asyncness); |
3c0e092e | 1164 | visit_unsafety(unsafety, vis); |
9fa01778 XL |
1165 | } |
1166 | ||
9fa01778 | 1167 | pub fn noop_visit_crate<T: MutVisitor>(krate: &mut Crate, vis: &mut T) { |
5e7ed085 | 1168 | let Crate { attrs, items, spans, id, is_placeholder: _ } = krate; |
a2a8927a XL |
1169 | vis.visit_id(id); |
1170 | visit_attrs(attrs, vis); | |
1171 | items.flat_map_in_place(|item| vis.flat_map_item(item)); | |
5e7ed085 FG |
1172 | let ModSpans { inner_span, inject_use_span } = spans; |
1173 | vis.visit_span(inner_span); | |
1174 | vis.visit_span(inject_use_span); | |
9fa01778 XL |
1175 | } |
1176 | ||
e1599b0c | 1177 | // Mutates one item into possibly many items. |
dfeec247 XL |
1178 | pub fn noop_flat_map_item<T: MutVisitor>( |
1179 | mut item: P<Item>, | |
1180 | visitor: &mut T, | |
1181 | ) -> SmallVec<[P<Item>; 1]> { | |
29967ef6 | 1182 | let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut(); |
9fa01778 XL |
1183 | visitor.visit_ident(ident); |
1184 | visit_attrs(attrs, visitor); | |
1185 | visitor.visit_id(id); | |
e74abb32 | 1186 | visitor.visit_item_kind(kind); |
9fa01778 XL |
1187 | visitor.visit_vis(vis); |
1188 | visitor.visit_span(span); | |
29967ef6 | 1189 | visit_lazy_tts(tokens, visitor); |
9fa01778 XL |
1190 | |
1191 | smallvec![item] | |
1192 | } | |
1193 | ||
dfeec247 | 1194 | pub fn noop_flat_map_foreign_item<T: MutVisitor>( |
74b04a01 | 1195 | mut item: P<ForeignItem>, |
dfeec247 | 1196 | visitor: &mut T, |
74b04a01 | 1197 | ) -> SmallVec<[P<ForeignItem>; 1]> { |
29967ef6 | 1198 | let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut(); |
74b04a01 | 1199 | visitor.visit_id(id); |
9fa01778 | 1200 | visitor.visit_ident(ident); |
74b04a01 | 1201 | visitor.visit_vis(vis); |
9fa01778 | 1202 | visit_attrs(attrs, visitor); |
e74abb32 | 1203 | match kind { |
74b04a01 XL |
1204 | ForeignItemKind::Static(ty, _, expr) => { |
1205 | visitor.visit_ty(ty); | |
1206 | visit_opt(expr, |expr| visitor.visit_expr(expr)); | |
1207 | } | |
3c0e092e XL |
1208 | ForeignItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { |
1209 | visit_defaultness(defaultness, visitor); | |
74b04a01 XL |
1210 | visitor.visit_generics(generics); |
1211 | visit_fn_sig(sig, visitor); | |
1212 | visit_opt(body, |body| visitor.visit_block(body)); | |
1213 | } | |
5e7ed085 FG |
1214 | ForeignItemKind::TyAlias(box TyAlias { |
1215 | defaultness, | |
1216 | generics, | |
1217 | where_clauses, | |
1218 | bounds, | |
1219 | ty, | |
1220 | .. | |
1221 | }) => { | |
3c0e092e | 1222 | visit_defaultness(defaultness, visitor); |
9fa01778 | 1223 | visitor.visit_generics(generics); |
5e7ed085 FG |
1224 | visitor.visit_span(&mut where_clauses.0.1); |
1225 | visitor.visit_span(&mut where_clauses.1.1); | |
74b04a01 XL |
1226 | visit_bounds(bounds, visitor); |
1227 | visit_opt(ty, |ty| visitor.visit_ty(ty)); | |
9fa01778 | 1228 | } |
29967ef6 | 1229 | ForeignItemKind::MacCall(mac) => visitor.visit_mac_call(mac), |
9fa01778 | 1230 | } |
9fa01778 | 1231 | visitor.visit_span(span); |
29967ef6 | 1232 | visit_lazy_tts(tokens, visitor); |
9fa01778 XL |
1233 | smallvec![item] |
1234 | } | |
1235 | ||
1236 | pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) { | |
29967ef6 | 1237 | let Pat { id, kind, span, tokens } = pat.deref_mut(); |
9fa01778 | 1238 | vis.visit_id(id); |
e74abb32 | 1239 | match kind { |
416331ca | 1240 | PatKind::Wild | PatKind::Rest => {} |
9fa01778 XL |
1241 | PatKind::Ident(_binding_mode, ident, sub) => { |
1242 | vis.visit_ident(ident); | |
1243 | visit_opt(sub, |sub| vis.visit_pat(sub)); | |
1244 | } | |
1245 | PatKind::Lit(e) => vis.visit_expr(e), | |
17df50a5 XL |
1246 | PatKind::TupleStruct(qself, path, elems) => { |
1247 | vis.visit_qself(qself); | |
9fa01778 | 1248 | vis.visit_path(path); |
9ffffee4 | 1249 | visit_thin_vec(elems, |elem| vis.visit_pat(elem)); |
9fa01778 XL |
1250 | } |
1251 | PatKind::Path(qself, path) => { | |
1252 | vis.visit_qself(qself); | |
1253 | vis.visit_path(path); | |
1254 | } | |
17df50a5 XL |
1255 | PatKind::Struct(qself, path, fields, _etc) => { |
1256 | vis.visit_qself(qself); | |
9fa01778 | 1257 | vis.visit_path(path); |
6a06907d | 1258 | fields.flat_map_in_place(|field| vis.flat_map_pat_field(field)); |
e1599b0c | 1259 | } |
9fa01778 XL |
1260 | PatKind::Box(inner) => vis.visit_pat(inner), |
1261 | PatKind::Ref(inner, _mutbl) => vis.visit_pat(inner), | |
1262 | PatKind::Range(e1, e2, Spanned { span: _, node: _ }) => { | |
dfeec247 XL |
1263 | visit_opt(e1, |e| vis.visit_expr(e)); |
1264 | visit_opt(e2, |e| vis.visit_expr(e)); | |
9fa01778 XL |
1265 | vis.visit_span(span); |
1266 | } | |
dfeec247 | 1267 | PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => { |
9ffffee4 | 1268 | visit_thin_vec(elems, |elem| vis.visit_pat(elem)) |
dfeec247 | 1269 | } |
9fa01778 | 1270 | PatKind::Paren(inner) => vis.visit_pat(inner), |
29967ef6 | 1271 | PatKind::MacCall(mac) => vis.visit_mac_call(mac), |
9fa01778 XL |
1272 | } |
1273 | vis.visit_span(span); | |
29967ef6 | 1274 | visit_lazy_tts(tokens, vis); |
9fa01778 XL |
1275 | } |
1276 | ||
1277 | pub fn noop_visit_anon_const<T: MutVisitor>(AnonConst { id, value }: &mut AnonConst, vis: &mut T) { | |
1278 | vis.visit_id(id); | |
1279 | vis.visit_expr(value); | |
1280 | } | |
1281 | ||
04454e1e | 1282 | pub fn noop_visit_inline_asm<T: MutVisitor>(asm: &mut InlineAsm, vis: &mut T) { |
17df50a5 XL |
1283 | for (op, _) in &mut asm.operands { |
1284 | match op { | |
1285 | InlineAsmOperand::In { expr, .. } | |
94222f64 | 1286 | | InlineAsmOperand::Out { expr: Some(expr), .. } |
04454e1e | 1287 | | InlineAsmOperand::InOut { expr, .. } => vis.visit_expr(expr), |
94222f64 | 1288 | InlineAsmOperand::Out { expr: None, .. } => {} |
17df50a5 XL |
1289 | InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => { |
1290 | vis.visit_expr(in_expr); | |
1291 | if let Some(out_expr) = out_expr { | |
1292 | vis.visit_expr(out_expr); | |
1293 | } | |
1294 | } | |
04454e1e FG |
1295 | InlineAsmOperand::Const { anon_const } => vis.visit_anon_const(anon_const), |
1296 | InlineAsmOperand::Sym { sym } => vis.visit_inline_asm_sym(sym), | |
17df50a5 XL |
1297 | } |
1298 | } | |
1299 | } | |
1300 | ||
04454e1e FG |
1301 | pub fn noop_visit_inline_asm_sym<T: MutVisitor>( |
1302 | InlineAsmSym { id, qself, path }: &mut InlineAsmSym, | |
1303 | vis: &mut T, | |
1304 | ) { | |
1305 | vis.visit_id(id); | |
1306 | vis.visit_qself(qself); | |
1307 | vis.visit_path(path); | |
1308 | } | |
1309 | ||
9ffffee4 FG |
1310 | pub fn noop_visit_format_args<T: MutVisitor>(fmt: &mut FormatArgs, vis: &mut T) { |
1311 | for arg in fmt.arguments.all_args_mut() { | |
1312 | if let FormatArgumentKind::Named(name) = &mut arg.kind { | |
1313 | vis.visit_ident(name); | |
1314 | } | |
1315 | vis.visit_expr(&mut arg.expr); | |
1316 | } | |
1317 | } | |
1318 | ||
f9f354fc | 1319 | pub fn noop_visit_expr<T: MutVisitor>( |
29967ef6 | 1320 | Expr { kind, id, span, attrs, tokens }: &mut Expr, |
f9f354fc XL |
1321 | vis: &mut T, |
1322 | ) { | |
e74abb32 | 1323 | match kind { |
9ffffee4 | 1324 | ExprKind::Array(exprs) => visit_thin_exprs(exprs, vis), |
29967ef6 XL |
1325 | ExprKind::ConstBlock(anon_const) => { |
1326 | vis.visit_anon_const(anon_const); | |
1327 | } | |
9fa01778 XL |
1328 | ExprKind::Repeat(expr, count) => { |
1329 | vis.visit_expr(expr); | |
1330 | vis.visit_anon_const(count); | |
1331 | } | |
9ffffee4 | 1332 | ExprKind::Tup(exprs) => visit_thin_exprs(exprs, vis), |
9fa01778 XL |
1333 | ExprKind::Call(f, args) => { |
1334 | vis.visit_expr(f); | |
9ffffee4 | 1335 | visit_thin_exprs(args, vis); |
9fa01778 | 1336 | } |
487cf647 FG |
1337 | ExprKind::MethodCall(box MethodCall { |
1338 | seg: PathSegment { ident, id, args: seg_args }, | |
1339 | receiver, | |
1340 | args: call_args, | |
1341 | span, | |
1342 | }) => { | |
9fa01778 XL |
1343 | vis.visit_ident(ident); |
1344 | vis.visit_id(id); | |
487cf647 | 1345 | visit_opt(seg_args, |args| vis.visit_generic_args(args)); |
2b03887a | 1346 | vis.visit_method_receiver_expr(receiver); |
9ffffee4 | 1347 | visit_thin_exprs(call_args, vis); |
f035d41b | 1348 | vis.visit_span(span); |
9fa01778 XL |
1349 | } |
1350 | ExprKind::Binary(_binop, lhs, rhs) => { | |
1351 | vis.visit_expr(lhs); | |
1352 | vis.visit_expr(rhs); | |
1353 | } | |
1354 | ExprKind::Unary(_unop, ohs) => vis.visit_expr(ohs), | |
9fa01778 XL |
1355 | ExprKind::Cast(expr, ty) => { |
1356 | vis.visit_expr(expr); | |
1357 | vis.visit_ty(ty); | |
1358 | } | |
1359 | ExprKind::Type(expr, ty) => { | |
1360 | vis.visit_expr(expr); | |
1361 | vis.visit_ty(ty); | |
1362 | } | |
60c5eb7d | 1363 | ExprKind::AddrOf(_, _, ohs) => vis.visit_expr(ohs), |
94222f64 | 1364 | ExprKind::Let(pat, scrutinee, _) => { |
e1599b0c | 1365 | vis.visit_pat(pat); |
dc9dc135 XL |
1366 | vis.visit_expr(scrutinee); |
1367 | } | |
9fa01778 XL |
1368 | ExprKind::If(cond, tr, fl) => { |
1369 | vis.visit_expr(cond); | |
1370 | vis.visit_block(tr); | |
1371 | visit_opt(fl, |fl| vis.visit_expr(fl)); | |
1372 | } | |
9fa01778 XL |
1373 | ExprKind::While(cond, body, label) => { |
1374 | vis.visit_expr(cond); | |
1375 | vis.visit_block(body); | |
1376 | visit_opt(label, |label| vis.visit_label(label)); | |
1377 | } | |
9fa01778 XL |
1378 | ExprKind::ForLoop(pat, iter, body, label) => { |
1379 | vis.visit_pat(pat); | |
1380 | vis.visit_expr(iter); | |
1381 | vis.visit_block(body); | |
1382 | visit_opt(label, |label| vis.visit_label(label)); | |
1383 | } | |
487cf647 | 1384 | ExprKind::Loop(body, label, span) => { |
9fa01778 XL |
1385 | vis.visit_block(body); |
1386 | visit_opt(label, |label| vis.visit_label(label)); | |
487cf647 | 1387 | vis.visit_span(span); |
9fa01778 XL |
1388 | } |
1389 | ExprKind::Match(expr, arms) => { | |
1390 | vis.visit_expr(expr); | |
e1599b0c | 1391 | arms.flat_map_in_place(|arm| vis.flat_map_arm(arm)); |
9fa01778 | 1392 | } |
487cf647 FG |
1393 | ExprKind::Closure(box Closure { |
1394 | binder, | |
1395 | capture_clause: _, | |
9c376795 | 1396 | constness, |
487cf647 FG |
1397 | asyncness, |
1398 | movability: _, | |
1399 | fn_decl, | |
1400 | body, | |
1401 | fn_decl_span, | |
1402 | fn_arg_span: _, | |
1403 | }) => { | |
064997fb | 1404 | vis.visit_closure_binder(binder); |
9c376795 | 1405 | visit_constness(constness, vis); |
9fa01778 | 1406 | vis.visit_asyncness(asyncness); |
487cf647 | 1407 | vis.visit_fn_decl(fn_decl); |
9fa01778 | 1408 | vis.visit_expr(body); |
487cf647 | 1409 | vis.visit_span(fn_decl_span); |
9fa01778 XL |
1410 | } |
1411 | ExprKind::Block(blk, label) => { | |
1412 | vis.visit_block(blk); | |
1413 | visit_opt(label, |label| vis.visit_label(label)); | |
1414 | } | |
353b0b11 | 1415 | ExprKind::Async(_capture_by, body) => { |
9fa01778 XL |
1416 | vis.visit_block(body); |
1417 | } | |
416331ca | 1418 | ExprKind::Await(expr) => vis.visit_expr(expr), |
dfeec247 | 1419 | ExprKind::Assign(el, er, _) => { |
9fa01778 XL |
1420 | vis.visit_expr(el); |
1421 | vis.visit_expr(er); | |
1422 | } | |
1423 | ExprKind::AssignOp(_op, el, er) => { | |
1424 | vis.visit_expr(el); | |
1425 | vis.visit_expr(er); | |
1426 | } | |
1427 | ExprKind::Field(el, ident) => { | |
1428 | vis.visit_expr(el); | |
1429 | vis.visit_ident(ident); | |
1430 | } | |
1431 | ExprKind::Index(el, er) => { | |
1432 | vis.visit_expr(el); | |
1433 | vis.visit_expr(er); | |
1434 | } | |
1435 | ExprKind::Range(e1, e2, _lim) => { | |
1436 | visit_opt(e1, |e1| vis.visit_expr(e1)); | |
1437 | visit_opt(e2, |e2| vis.visit_expr(e2)); | |
1438 | } | |
fc512014 | 1439 | ExprKind::Underscore => {} |
9fa01778 XL |
1440 | ExprKind::Path(qself, path) => { |
1441 | vis.visit_qself(qself); | |
1442 | vis.visit_path(path); | |
1443 | } | |
1444 | ExprKind::Break(label, expr) => { | |
1445 | visit_opt(label, |label| vis.visit_label(label)); | |
1446 | visit_opt(expr, |expr| vis.visit_expr(expr)); | |
1447 | } | |
1448 | ExprKind::Continue(label) => { | |
1449 | visit_opt(label, |label| vis.visit_label(label)); | |
1450 | } | |
1451 | ExprKind::Ret(expr) => { | |
1452 | visit_opt(expr, |expr| vis.visit_expr(expr)); | |
1453 | } | |
04454e1e FG |
1454 | ExprKind::Yeet(expr) => { |
1455 | visit_opt(expr, |expr| vis.visit_expr(expr)); | |
1456 | } | |
1457 | ExprKind::InlineAsm(asm) => vis.visit_inline_asm(asm), | |
9ffffee4 | 1458 | ExprKind::FormatArgs(fmt) => vis.visit_format_args(fmt), |
29967ef6 | 1459 | ExprKind::MacCall(mac) => vis.visit_mac_call(mac), |
6a06907d | 1460 | ExprKind::Struct(se) => { |
17df50a5 XL |
1461 | let StructExpr { qself, path, fields, rest } = se.deref_mut(); |
1462 | vis.visit_qself(qself); | |
9fa01778 | 1463 | vis.visit_path(path); |
6a06907d XL |
1464 | fields.flat_map_in_place(|field| vis.flat_map_expr_field(field)); |
1465 | match rest { | |
29967ef6 XL |
1466 | StructRest::Base(expr) => vis.visit_expr(expr), |
1467 | StructRest::Rest(_span) => {} | |
1468 | StructRest::None => {} | |
1469 | } | |
dfeec247 | 1470 | } |
9fa01778 XL |
1471 | ExprKind::Paren(expr) => { |
1472 | vis.visit_expr(expr); | |
9fa01778 XL |
1473 | } |
1474 | ExprKind::Yield(expr) => { | |
1475 | visit_opt(expr, |expr| vis.visit_expr(expr)); | |
1476 | } | |
1477 | ExprKind::Try(expr) => vis.visit_expr(expr), | |
1478 | ExprKind::TryBlock(body) => vis.visit_block(body), | |
487cf647 | 1479 | ExprKind::Lit(_) | ExprKind::IncludedBytes(..) | ExprKind::Err => {} |
9fa01778 XL |
1480 | } |
1481 | vis.visit_id(id); | |
1482 | vis.visit_span(span); | |
f2b60f7d | 1483 | visit_attrs(attrs, vis); |
29967ef6 | 1484 | visit_lazy_tts(tokens, vis); |
9fa01778 XL |
1485 | } |
1486 | ||
1487 | pub fn noop_filter_map_expr<T: MutVisitor>(mut e: P<Expr>, vis: &mut T) -> Option<P<Expr>> { | |
dfeec247 XL |
1488 | Some({ |
1489 | vis.visit_expr(&mut e); | |
1490 | e | |
1491 | }) | |
9fa01778 XL |
1492 | } |
1493 | ||
dfeec247 | 1494 | pub fn noop_flat_map_stmt<T: MutVisitor>( |
fc512014 | 1495 | Stmt { kind, mut span, mut id }: Stmt, |
dfeec247 XL |
1496 | vis: &mut T, |
1497 | ) -> SmallVec<[Stmt; 1]> { | |
9fa01778 XL |
1498 | vis.visit_id(&mut id); |
1499 | vis.visit_span(&mut span); | |
94222f64 XL |
1500 | let stmts: SmallVec<_> = noop_flat_map_stmt_kind(kind, vis) |
1501 | .into_iter() | |
1502 | .map(|kind| Stmt { id, kind, span }) | |
1503 | .collect(); | |
1504 | if stmts.len() > 1 { | |
1505 | panic!( | |
1506 | "cloning statement `NodeId`s is prohibited by default, \ | |
1507 | the visitor should implement custom statement visiting" | |
1508 | ); | |
1509 | } | |
1510 | stmts | |
9fa01778 XL |
1511 | } |
1512 | ||
dfeec247 XL |
1513 | pub fn noop_flat_map_stmt_kind<T: MutVisitor>( |
1514 | kind: StmtKind, | |
1515 | vis: &mut T, | |
1516 | ) -> SmallVec<[StmtKind; 1]> { | |
e74abb32 | 1517 | match kind { |
dfeec247 XL |
1518 | StmtKind::Local(mut local) => smallvec![StmtKind::Local({ |
1519 | vis.visit_local(&mut local); | |
1520 | local | |
1521 | })], | |
9fa01778 | 1522 | StmtKind::Item(item) => vis.flat_map_item(item).into_iter().map(StmtKind::Item).collect(), |
dfeec247 XL |
1523 | StmtKind::Expr(expr) => vis.filter_map_expr(expr).into_iter().map(StmtKind::Expr).collect(), |
1524 | StmtKind::Semi(expr) => vis.filter_map_expr(expr).into_iter().map(StmtKind::Semi).collect(), | |
74b04a01 | 1525 | StmtKind::Empty => smallvec![StmtKind::Empty], |
ba9703b0 | 1526 | StmtKind::MacCall(mut mac) => { |
fc512014 | 1527 | let MacCallStmt { mac: mac_, style: _, attrs, tokens } = mac.deref_mut(); |
29967ef6 | 1528 | vis.visit_mac_call(mac_); |
f2b60f7d | 1529 | visit_attrs(attrs, vis); |
fc512014 | 1530 | visit_lazy_tts(tokens, vis); |
ba9703b0 | 1531 | smallvec![StmtKind::MacCall(mac)] |
9fa01778 XL |
1532 | } |
1533 | } | |
1534 | } | |
1535 | ||
1b1a35ee XL |
1536 | pub fn noop_visit_vis<T: MutVisitor>(visibility: &mut Visibility, vis: &mut T) { |
1537 | match &mut visibility.kind { | |
923072b8 | 1538 | VisibilityKind::Public | VisibilityKind::Inherited => {} |
f2b60f7d | 1539 | VisibilityKind::Restricted { path, id, shorthand: _ } => { |
9fa01778 XL |
1540 | vis.visit_path(path); |
1541 | vis.visit_id(id); | |
1542 | } | |
1543 | } | |
1b1a35ee | 1544 | vis.visit_span(&mut visibility.span); |
9fa01778 | 1545 | } |
a2a8927a XL |
1546 | |
1547 | /// Some value for the AST node that is valid but possibly meaningless. | |
1548 | pub trait DummyAstNode { | |
1549 | fn dummy() -> Self; | |
1550 | } | |
1551 | ||
1552 | impl<T> DummyAstNode for Option<T> { | |
1553 | fn dummy() -> Self { | |
1554 | Default::default() | |
1555 | } | |
1556 | } | |
1557 | ||
1558 | impl<T: DummyAstNode + 'static> DummyAstNode for P<T> { | |
1559 | fn dummy() -> Self { | |
1560 | P(DummyAstNode::dummy()) | |
1561 | } | |
1562 | } | |
1563 | ||
a2a8927a XL |
1564 | impl DummyAstNode for Item { |
1565 | fn dummy() -> Self { | |
1566 | Item { | |
1567 | attrs: Default::default(), | |
1568 | id: DUMMY_NODE_ID, | |
1569 | span: Default::default(), | |
1570 | vis: Visibility { | |
1571 | kind: VisibilityKind::Public, | |
1572 | span: Default::default(), | |
1573 | tokens: Default::default(), | |
1574 | }, | |
1575 | ident: Ident::empty(), | |
1576 | kind: ItemKind::ExternCrate(None), | |
1577 | tokens: Default::default(), | |
1578 | } | |
1579 | } | |
1580 | } | |
1581 | ||
1582 | impl DummyAstNode for Expr { | |
1583 | fn dummy() -> Self { | |
1584 | Expr { | |
1585 | id: DUMMY_NODE_ID, | |
1586 | kind: ExprKind::Err, | |
1587 | span: Default::default(), | |
1588 | attrs: Default::default(), | |
1589 | tokens: Default::default(), | |
1590 | } | |
1591 | } | |
1592 | } | |
1593 | ||
1594 | impl DummyAstNode for Ty { | |
1595 | fn dummy() -> Self { | |
1596 | Ty { | |
1597 | id: DUMMY_NODE_ID, | |
1598 | kind: TyKind::Err, | |
1599 | span: Default::default(), | |
1600 | tokens: Default::default(), | |
1601 | } | |
1602 | } | |
1603 | } | |
1604 | ||
1605 | impl DummyAstNode for Pat { | |
1606 | fn dummy() -> Self { | |
1607 | Pat { | |
1608 | id: DUMMY_NODE_ID, | |
1609 | kind: PatKind::Wild, | |
1610 | span: Default::default(), | |
1611 | tokens: Default::default(), | |
1612 | } | |
1613 | } | |
1614 | } | |
1615 | ||
1616 | impl DummyAstNode for Stmt { | |
1617 | fn dummy() -> Self { | |
1618 | Stmt { id: DUMMY_NODE_ID, kind: StmtKind::Empty, span: Default::default() } | |
1619 | } | |
1620 | } | |
1621 | ||
1622 | impl DummyAstNode for Block { | |
1623 | fn dummy() -> Self { | |
1624 | Block { | |
1625 | stmts: Default::default(), | |
1626 | id: DUMMY_NODE_ID, | |
1627 | rules: BlockCheckMode::Default, | |
1628 | span: Default::default(), | |
1629 | tokens: Default::default(), | |
1630 | could_be_bare_literal: Default::default(), | |
1631 | } | |
1632 | } | |
1633 | } | |
1634 | ||
1635 | impl DummyAstNode for Crate { | |
1636 | fn dummy() -> Self { | |
1637 | Crate { | |
1638 | attrs: Default::default(), | |
1639 | items: Default::default(), | |
5e7ed085 | 1640 | spans: Default::default(), |
a2a8927a XL |
1641 | id: DUMMY_NODE_ID, |
1642 | is_placeholder: Default::default(), | |
1643 | } | |
1644 | } | |
1645 | } | |
2b03887a FG |
1646 | |
1647 | impl<N: DummyAstNode, T: DummyAstNode> DummyAstNode for crate::ast_traits::AstNodeWrapper<N, T> { | |
1648 | fn dummy() -> Self { | |
1649 | crate::ast_traits::AstNodeWrapper::new(N::dummy(), T::dummy()) | |
1650 | } | |
1651 | } |