1use rustc_span::symbol::Ident;
9
10use super::{
11 Async, BaseSort, BaseTy, BaseTyKind, ConstArg, ConstArgKind, ConstantInfo, ConstructorArg,
12 Ensures, EnumDef, Expr, ExprKind, ExprPath, ExprPathSegment, FieldExpr, FnInput, FnOutput,
13 FnRetTy, FnSig, GenericArg, GenericArgKind, GenericParam, Generics, Impl, ImplAssocReft,
14 Indices, ItemKind, Lit, Path, PathSegment, Qualifier, RefineArg, RefineParam, Sort, SortPath,
15 SpecFunc, StructDef, Trait, TraitAssocReft, TraitRef, Ty, TyAlias, TyKind, UseTreeKind,
16 VariantDef, VariantRet, WhereBoundPredicate,
17};
18use crate::surface::{FluxItem, ImplItemFn, Item, PrimOpProp, SortDecl, TraitItemFn, UseTree};
19
20#[macro_export]
21macro_rules! walk_list {
22 ($visitor: expr, $method: ident, $list: expr $(, $($extra_args: expr),* )?) => {
23 {
24 #[allow(for_loops_over_fallibles)]
25 for elem in $list {
26 $visitor.$method(elem $(, $($extra_args,)* )?)
27 }
28 }
29 }
30}
31
32pub trait Visitor: Sized {
33 fn visit_flux_item(&mut self, item: &FluxItem) {
34 walk_flux_item(self, item);
35 }
36
37 fn visit_qualifier(&mut self, qualifier: &Qualifier) {
38 walk_qualifier(self, qualifier);
39 }
40
41 fn visit_sort_decl(&mut self, sort_decl: &SortDecl) {
42 walk_sort_decl(self, sort_decl);
43 }
44
45 fn visit_defn(&mut self, defn: &SpecFunc) {
46 walk_defn(self, defn);
47 }
48
49 fn visit_primop_prop(&mut self, prop: &PrimOpProp) {
50 walk_primop_prop(self, prop);
51 }
52
53 fn visit_refine_param(&mut self, param: &RefineParam) {
54 walk_refine_param(self, param);
55 }
56
57 fn visit_generic_param(&mut self, param: &GenericParam) {
58 walk_generic_param(self, param);
59 }
60
61 fn visit_sort(&mut self, sort: &Sort) {
62 walk_sort(self, sort);
63 }
64
65 fn visit_item(&mut self, item: &Item) {
66 walk_item(self, item);
67 }
68
69 fn visit_trait_item(&mut self, item: &TraitItemFn) {
70 walk_trait_item(self, item);
71 }
72
73 fn visit_impl_item(&mut self, item: &ImplItemFn) {
74 walk_impl_item(self, item);
75 }
76
77 fn visit_trait(&mut self, trait_: &Trait) {
78 walk_trait(self, trait_);
79 }
80
81 fn visit_trait_assoc_reft(&mut self, assoc_reft: &TraitAssocReft) {
82 walk_trait_assoc_reft(self, assoc_reft);
83 }
84
85 fn visit_impl(&mut self, impl_: &Impl) {
86 walk_impl(self, impl_);
87 }
88
89 fn visit_impl_assoc_reft(&mut self, assoc_reft: &ImplAssocReft) {
90 walk_impl_assoc_reft(self, assoc_reft);
91 }
92
93 fn visit_trait_ref(&mut self, trait_ref: &TraitRef) {
94 walk_trait_ref(self, trait_ref);
95 }
96
97 fn visit_base_sort(&mut self, bsort: &BaseSort) {
98 walk_base_sort(self, bsort);
99 }
100
101 fn visit_sort_path(&mut self, path: &SortPath) {
102 walk_sort_path(self, path);
103 }
104
105 fn visit_ty_alias(&mut self, ty_alias: &TyAlias) {
106 walk_ty_alias(self, ty_alias);
107 }
108
109 fn visit_struct_def(&mut self, struct_def: &StructDef) {
110 walk_struct_def(self, struct_def);
111 }
112
113 fn visit_constant(&mut self, _constant: &ConstantInfo) {
114 walk_constant(self, _constant);
115 }
116
117 fn visit_enum_def(&mut self, enum_def: &EnumDef) {
118 walk_enum_def(self, enum_def);
119 }
120
121 fn visit_variant(&mut self, variant: &VariantDef) {
122 walk_variant(self, variant);
123 }
124
125 fn visit_variant_ret(&mut self, ret: &VariantRet) {
126 walk_variant_ret(self, ret);
127 }
128
129 fn visit_fn_sig(&mut self, fn_sig: &FnSig) {
130 walk_fn_sig(self, fn_sig);
131 }
132
133 fn visit_fn_output(&mut self, fn_output: &FnOutput) {
134 walk_fn_output(self, fn_output);
135 }
136
137 fn visit_async(&mut self, _asyncness: &Async) {}
138
139 fn visit_generics(&mut self, generics: &Generics) {
140 walk_generics(self, generics);
141 }
142
143 fn visit_fn_input(&mut self, input: &FnInput) {
144 walk_fn_input(self, input);
145 }
146
147 fn visit_fn_ret_ty(&mut self, fn_ret_ty: &FnRetTy) {
148 walk_fn_ret_ty(self, fn_ret_ty);
149 }
150
151 fn visit_ensures(&mut self, ensures: &Ensures) {
152 walk_ensures(self, ensures);
153 }
154
155 fn visit_where_predicate(&mut self, predicate: &WhereBoundPredicate) {
156 walk_where_predicate(self, predicate);
157 }
158
159 fn visit_generic_arg(&mut self, arg: &GenericArg) {
160 walk_generic_arg(self, arg);
161 }
162
163 fn visit_refine_arg(&mut self, arg: &RefineArg) {
164 walk_refine_arg(self, arg);
165 }
166
167 fn visit_indices(&mut self, indices: &Indices) {
168 walk_indices(self, indices);
169 }
170
171 fn visit_ty(&mut self, ty: &Ty) {
172 walk_ty(self, ty);
173 }
174
175 fn visit_const_arg(&mut self, const_arg: &ConstArg) {
176 walk_const_arg(self, const_arg);
177 }
178
179 fn visit_bty(&mut self, bty: &BaseTy) {
180 walk_bty(self, bty);
181 }
182
183 fn visit_path(&mut self, path: &Path) {
184 walk_path(self, path);
185 }
186
187 fn visit_path_segment(&mut self, segment: &PathSegment) {
188 walk_path_segment(self, segment);
189 }
190
191 fn visit_expr(&mut self, expr: &Expr) {
192 walk_expr(self, expr);
193 }
194
195 fn visit_constructor_args(&mut self, expr: &ConstructorArg) {
196 match expr {
197 ConstructorArg::FieldExpr(field_expr) => walk_field_expr(self, field_expr),
198 ConstructorArg::Spread(spread) => self.visit_expr(&spread.expr),
199 }
200 }
201
202 fn visit_path_expr(&mut self, qpath: &ExprPath) {
203 walk_path_expr(self, qpath);
204 }
205
206 fn visit_path_expr_segment(&mut self, segment: &ExprPathSegment) {
207 walk_path_expr_segment(self, segment);
208 }
209
210 fn visit_ident(&mut self, _ident: Ident) {}
211
212 fn visit_literal(&mut self, _lit: Lit) {}
213}
214
215pub fn walk_flux_item<V: Visitor>(vis: &mut V, item: &FluxItem) {
216 match item {
217 FluxItem::Qualifier(qualifier) => vis.visit_qualifier(qualifier),
218 FluxItem::FuncDef(spec_func) => vis.visit_defn(spec_func),
219 FluxItem::SortDecl(sort_decl) => vis.visit_sort_decl(sort_decl),
220 FluxItem::PrimOpProp(prim_op_prop) => vis.visit_primop_prop(prim_op_prop),
221 FluxItem::Use(use_tree) => walk_use_tree(vis, use_tree),
222 }
223}
224
225pub fn walk_use_tree<V: Visitor>(vis: &mut V, use_tree: &UseTree) {
226 vis.visit_path_expr(&use_tree.prefix);
227 match &use_tree.kind {
228 UseTreeKind::Simple => {}
229 UseTreeKind::Nested(items) => {
230 for item in items {
231 walk_use_tree(vis, item);
232 }
233 }
234 }
235}
236
237pub fn walk_qualifier<V: Visitor>(vis: &mut V, qualifier: &Qualifier) {
238 vis.visit_ident(qualifier.name);
239 walk_list!(vis, visit_refine_param, &qualifier.params);
240 vis.visit_expr(&qualifier.expr);
241}
242
243pub fn walk_sort_decl<V: Visitor>(vis: &mut V, sort_decl: &SortDecl) {
244 vis.visit_ident(sort_decl.name);
245 walk_list!(vis, visit_ident, sort_decl.sort_vars.iter().copied());
246}
247
248pub fn walk_defn<V: Visitor>(vis: &mut V, defn: &SpecFunc) {
249 vis.visit_ident(defn.name);
250 walk_list!(vis, visit_ident, defn.sort_vars.iter().copied());
251 walk_list!(vis, visit_refine_param, &defn.params);
252 vis.visit_sort(&defn.output);
253 if let Some(body) = &defn.body {
254 vis.visit_expr(body);
255 }
256}
257
258pub fn walk_primop_prop<V: Visitor>(vis: &mut V, prop: &PrimOpProp) {
259 vis.visit_ident(prop.name);
260 walk_list!(vis, visit_refine_param, &prop.params);
261 vis.visit_expr(&prop.body);
262}
263
264pub fn walk_refine_param<V: Visitor>(vis: &mut V, param: &RefineParam) {
265 vis.visit_ident(param.ident);
266 vis.visit_sort(¶m.sort);
267}
268
269pub fn walk_generic_param<V: Visitor>(vis: &mut V, param: &GenericParam) {
270 vis.visit_ident(param.name);
271}
272
273pub fn walk_sort<V: Visitor>(vis: &mut V, sort: &Sort) {
274 match sort {
275 Sort::Base(bsort) => vis.visit_base_sort(bsort),
276 Sort::Func { inputs, output } => {
277 walk_list!(vis, visit_base_sort, inputs);
278 vis.visit_base_sort(output);
279 }
280 Sort::Infer => {}
281 }
282}
283
284pub fn walk_item<V: Visitor>(vis: &mut V, item: &Item) {
285 match &item.kind {
286 ItemKind::Fn(fn_sig) => {
287 if let Some(fn_sig) = fn_sig {
288 vis.visit_fn_sig(fn_sig);
289 }
290 }
291 ItemKind::Struct(struct_def) => vis.visit_struct_def(struct_def),
292 ItemKind::Enum(enum_def) => vis.visit_enum_def(enum_def),
293 ItemKind::Trait(trait_) => vis.visit_trait(trait_),
294 ItemKind::Impl(impl_) => vis.visit_impl(impl_),
295 ItemKind::Const(cst) => vis.visit_constant(cst),
296 ItemKind::Static(static_info) => vis.visit_ty(&static_info.ty),
297 ItemKind::TyAlias(ty_alias) => vis.visit_ty_alias(ty_alias),
298 ItemKind::Mod => {}
299 }
300}
301
302pub fn walk_trait_item<V: Visitor>(vis: &mut V, item: &TraitItemFn) {
303 if let Some(fn_sig) = item.sig.as_ref() {
304 vis.visit_fn_sig(fn_sig);
305 }
306}
307
308pub fn walk_impl_item<V: Visitor>(vis: &mut V, item: &ImplItemFn) {
309 if let Some(fn_sig) = item.sig.as_ref() {
310 vis.visit_fn_sig(fn_sig);
311 }
312}
313
314pub fn walk_trait<V: Visitor>(vis: &mut V, trait_: &Trait) {
315 if let Some(generics) = &trait_.generics {
316 vis.visit_generics(generics);
317 }
318 walk_list!(vis, visit_trait_assoc_reft, &trait_.assoc_refinements);
319}
320
321pub fn walk_trait_assoc_reft<V: Visitor>(vis: &mut V, assoc_reft: &TraitAssocReft) {
322 vis.visit_ident(assoc_reft.name);
323 walk_list!(vis, visit_refine_param, &assoc_reft.params);
324 vis.visit_base_sort(&assoc_reft.output);
325 if let Some(expr) = &assoc_reft.body {
326 vis.visit_expr(expr);
327 }
328}
329
330pub fn walk_impl<V: Visitor>(vis: &mut V, impl_: &Impl) {
331 if let Some(generics) = &impl_.generics {
332 vis.visit_generics(generics);
333 }
334 walk_list!(vis, visit_impl_assoc_reft, &impl_.assoc_refinements);
335}
336
337pub fn walk_impl_assoc_reft<V: Visitor>(vis: &mut V, assoc_reft: &ImplAssocReft) {
338 vis.visit_ident(assoc_reft.name);
339 walk_list!(vis, visit_refine_param, &assoc_reft.params);
340 vis.visit_expr(&assoc_reft.body);
341 vis.visit_base_sort(&assoc_reft.output);
342}
343
344pub fn walk_trait_ref<V: Visitor>(vis: &mut V, trait_ref: &TraitRef) {
345 vis.visit_path(&trait_ref.path);
346}
347
348pub fn walk_base_sort<V: Visitor>(vis: &mut V, bsort: &BaseSort) {
349 match bsort {
350 BaseSort::BitVec(_len) => {}
351 BaseSort::Path(path) => vis.visit_sort_path(path),
352 BaseSort::SortOf(qself, path) => {
353 vis.visit_ty(qself);
354 vis.visit_path(path);
355 }
356 BaseSort::Tuple(sorts) => {
357 walk_list!(vis, visit_base_sort, sorts);
358 }
359 }
360}
361
362pub fn walk_sort_path<V: Visitor>(vis: &mut V, path: &SortPath) {
363 walk_list!(vis, visit_ident, path.segments.iter().copied());
364 walk_list!(vis, visit_base_sort, &path.args);
365}
366
367pub fn walk_ty_alias<V: Visitor>(vis: &mut V, ty_alias: &TyAlias) {
368 vis.visit_ident(ty_alias.ident);
369 vis.visit_generics(&ty_alias.generics);
370 walk_list!(vis, visit_refine_param, &ty_alias.params);
371 if let Some(index) = &ty_alias.index {
372 vis.visit_refine_param(index);
373 }
374 vis.visit_ty(&ty_alias.ty);
375}
376pub fn walk_constant<V: Visitor>(vis: &mut V, constant_info: &ConstantInfo) {
377 if let Some(expr) = &constant_info.expr {
378 vis.visit_expr(expr);
379 }
380}
381
382pub fn walk_struct_def<V: Visitor>(vis: &mut V, struct_def: &StructDef) {
383 if let Some(generics) = &struct_def.generics {
384 vis.visit_generics(generics);
385 }
386 if let Some(refined_by) = &struct_def.refined_by {
387 walk_list!(vis, visit_refine_param, refined_by);
388 }
389 walk_list!(vis, visit_expr, &struct_def.invariants);
390 struct_def.fields.iter().flatten().for_each(|field| {
391 vis.visit_ty(field);
392 });
393}
394
395pub fn walk_enum_def<V: Visitor>(vis: &mut V, enum_def: &EnumDef) {
396 if let Some(refined_by) = &enum_def.refined_by {
397 walk_list!(vis, visit_refine_param, refined_by);
398 }
399 walk_list!(vis, visit_expr, &enum_def.invariants);
400 enum_def
401 .variants
402 .iter()
403 .flatten()
404 .for_each(|variant| vis.visit_variant(variant));
405}
406
407pub fn walk_variant<V: Visitor>(vis: &mut V, variant: &VariantDef) {
408 walk_list!(vis, visit_ty, &variant.fields);
409 if let Some(ret) = &variant.ret {
410 vis.visit_variant_ret(ret);
411 }
412}
413
414pub fn walk_fn_trait_ref<V: Visitor>(vis: &mut V, in_arg: &GenericArg, out_arg: &GenericArg) {
415 vis.visit_generic_arg(in_arg);
416 vis.visit_generic_arg(out_arg);
417}
418
419pub fn walk_variant_ret<V: Visitor>(vis: &mut V, ret: &VariantRet) {
420 vis.visit_path(&ret.path);
421 vis.visit_indices(&ret.indices);
422}
423
424pub fn walk_fn_sig<V: Visitor>(vis: &mut V, fn_sig: &FnSig) {
425 vis.visit_async(&fn_sig.asyncness);
426 vis.visit_generics(&fn_sig.generics);
427 walk_list!(vis, visit_refine_param, &fn_sig.params);
428 for requires in &fn_sig.requires {
429 walk_list!(vis, visit_refine_param, &requires.params);
430 vis.visit_expr(&requires.pred);
431 }
432 walk_list!(vis, visit_fn_input, &fn_sig.inputs);
433 if let Some(no_panic_expr) = &fn_sig.no_panic {
434 vis.visit_expr(no_panic_expr);
435 }
436 vis.visit_fn_output(&fn_sig.output);
437}
438
439pub fn walk_fn_output<V: Visitor>(vis: &mut V, fn_output: &FnOutput) {
440 vis.visit_fn_ret_ty(&fn_output.returns);
441 walk_list!(vis, visit_ensures, &fn_output.ensures);
442}
443
444pub fn walk_generics<V: Visitor>(vis: &mut V, generics: &Generics) {
445 walk_list!(vis, visit_generic_param, &generics.params);
446 if let Some(predicates) = &generics.predicates {
447 walk_list!(vis, visit_where_predicate, predicates);
448 }
449}
450
451pub fn walk_fn_input<V: Visitor>(vis: &mut V, arg: &FnInput) {
452 match arg {
453 FnInput::Constr(bind, path, pred, _node_id) => {
454 vis.visit_ident(*bind);
455 vis.visit_path(path);
456 vis.visit_expr(pred);
457 }
458 FnInput::StrgRef(bind, ty, _node_id) => {
459 vis.visit_ident(*bind);
460 vis.visit_ty(ty);
461 }
462 FnInput::Ty(bind, ty, _node_id) => {
463 if let Some(bind) = bind {
464 vis.visit_ident(*bind);
465 }
466 vis.visit_ty(ty);
467 }
468 }
469}
470
471pub fn walk_fn_ret_ty<V: Visitor>(vis: &mut V, fn_ret_ty: &FnRetTy) {
472 match fn_ret_ty {
473 FnRetTy::Default(_span) => {}
474 FnRetTy::Ty(ty) => vis.visit_ty(ty),
475 }
476}
477
478pub fn walk_ensures<V: Visitor>(vis: &mut V, ensures: &Ensures) {
479 match ensures {
480 Ensures::Type(bind, ty, _node_id) => {
481 vis.visit_ident(*bind);
482 vis.visit_ty(ty);
483 }
484 Ensures::Pred(pred) => {
485 vis.visit_expr(pred);
486 }
487 }
488}
489
490pub fn walk_where_predicate<V: Visitor>(vis: &mut V, predicate: &WhereBoundPredicate) {
491 vis.visit_ty(&predicate.bounded_ty);
492 walk_list!(vis, visit_trait_ref, &predicate.bounds);
493}
494
495pub fn walk_generic_arg<V: Visitor>(vis: &mut V, arg: &GenericArg) {
496 match &arg.kind {
497 GenericArgKind::Type(ty) => {
498 vis.visit_ty(ty);
499 }
500 GenericArgKind::Constraint(ident, ty) => {
501 vis.visit_ident(*ident);
502 vis.visit_ty(ty);
503 }
504 }
505}
506
507pub fn walk_refine_arg<V: Visitor>(vis: &mut V, arg: &RefineArg) {
508 match arg {
509 RefineArg::Bind(ident, _kind, _span, _node_id) => {
510 vis.visit_ident(*ident);
511 }
512 RefineArg::Expr(e) => {
513 vis.visit_expr(e);
514 }
515 RefineArg::Abs(params, e, _node_id, _span) => {
516 walk_list!(vis, visit_refine_param, params);
517 vis.visit_expr(e);
518 }
519 }
520}
521
522pub fn walk_indices<V: Visitor>(vis: &mut V, indices: &Indices) {
523 walk_list!(vis, visit_refine_arg, &indices.indices);
524}
525
526pub fn walk_ty<V: Visitor>(vis: &mut V, ty: &Ty) {
527 match &ty.kind {
528 TyKind::Base(bty) => vis.visit_bty(bty),
529 TyKind::Indexed { bty, indices } => {
530 vis.visit_indices(indices);
531 vis.visit_bty(bty);
532 }
533
534 TyKind::Exists { bind, bty, pred } => {
535 vis.visit_ident(*bind);
536 vis.visit_bty(bty);
537 vis.visit_expr(pred);
538 }
539 TyKind::GeneralExists { params, ty, pred } => {
540 walk_list!(vis, visit_refine_param, params);
541 vis.visit_ty(ty);
542 if let Some(pred) = pred {
543 vis.visit_expr(pred);
544 }
545 }
546 TyKind::Ref(_mutbl, ty) => {
547 vis.visit_ty(ty);
548 }
549 TyKind::Constr(pred, ty) => {
550 vis.visit_expr(pred);
551 vis.visit_ty(ty);
552 }
553 TyKind::Tuple(tys) => {
554 walk_list!(vis, visit_ty, tys);
555 }
556 TyKind::Array(ty, len) => {
557 vis.visit_const_arg(len);
558 vis.visit_ty(ty);
559 }
560 TyKind::ImplTrait(_node_id, trait_ref) => {
561 walk_list!(vis, visit_trait_ref, trait_ref);
562 }
563 TyKind::Hole => {}
564 }
565}
566
567pub fn walk_const_arg<V: Visitor>(vis: &mut V, const_arg: &ConstArg) {
568 if let ConstArgKind::Path(path) = &const_arg.kind {
569 vis.visit_path(path);
570 }
571}
572
573pub fn walk_bty<V: Visitor>(vis: &mut V, bty: &BaseTy) {
574 match &bty.kind {
575 BaseTyKind::Path(qself, path) => {
576 if let Some(qself) = qself {
577 vis.visit_ty(qself);
578 }
579 vis.visit_path(path);
580 }
581 BaseTyKind::Slice(ty) => vis.visit_ty(ty),
582 BaseTyKind::Ptr(_, ty) => vis.visit_ty(ty),
583 }
584}
585
586pub fn walk_path<V: Visitor>(vis: &mut V, path: &Path) {
587 walk_list!(vis, visit_path_segment, &path.segments);
588 walk_list!(vis, visit_refine_arg, &path.refine);
589}
590
591pub fn walk_path_segment<V: Visitor>(vis: &mut V, segment: &PathSegment) {
592 vis.visit_ident(segment.ident);
593 walk_list!(vis, visit_generic_arg, &segment.args);
594}
595
596pub fn walk_field_expr<V: Visitor>(vis: &mut V, expr: &FieldExpr) {
597 vis.visit_ident(expr.ident);
598 vis.visit_refine_arg(&expr.expr);
599}
600
601pub fn walk_expr<V: Visitor>(vis: &mut V, expr: &Expr) {
602 match &expr.kind {
603 ExprKind::Path(qpath) => vis.visit_path_expr(qpath),
604 ExprKind::Dot(base, fld) => {
605 vis.visit_expr(base);
606 vis.visit_ident(*fld);
607 }
608 ExprKind::Literal(lit) => {
609 vis.visit_literal(*lit);
610 }
611 ExprKind::BinaryOp(_bin_op, box exprs) => {
612 walk_list!(vis, visit_expr, exprs);
613 }
614 ExprKind::UnaryOp(_un_op, e) => {
615 vis.visit_expr(e);
616 }
617 ExprKind::PrimUIF(_) => {}
618 ExprKind::Call(callee, args) => {
619 vis.visit_expr(callee);
620 walk_list!(vis, visit_expr, args);
621 }
622 ExprKind::AssocReft(qself, path, name) => {
623 vis.visit_ty(qself);
624 vis.visit_path(path);
625 vis.visit_ident(*name);
626 }
627 ExprKind::IfThenElse(box exprs) => {
628 walk_list!(vis, visit_expr, exprs);
629 }
630 ExprKind::Constructor(path, exprs) => {
631 if let Some(path) = path {
632 vis.visit_path_expr(path);
633 }
634 walk_list!(vis, visit_constructor_args, exprs);
635 }
636 ExprKind::Quant(_, i, _, e) => {
637 vis.visit_refine_param(i);
638 vis.visit_expr(e);
639 }
640 ExprKind::Block(decls, body) => {
641 for decl in decls {
642 vis.visit_expr(&decl.init);
645 vis.visit_refine_param(&decl.param);
646 }
647 vis.visit_expr(body);
648 }
649 ExprKind::SetLiteral(exprs) => {
650 walk_list!(vis, visit_expr, exprs);
651 }
652 ExprKind::Tuple(exprs) => {
653 walk_list!(vis, visit_expr, exprs);
654 }
655 }
656}
657
658pub fn walk_path_expr<V: Visitor>(vis: &mut V, qpath: &ExprPath) {
659 walk_list!(vis, visit_path_expr_segment, &qpath.segments);
660}
661
662pub fn walk_path_expr_segment<V: Visitor>(vis: &mut V, segment: &ExprPathSegment) {
663 vis.visit_ident(segment.ident);
664}