1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! A Folder represents an HIR->HIR fold; it accepts a HIR piece,
12 //! and returns a piece of the same type.
15 use syntax
::ast
::{Name, NodeId, DUMMY_NODE_ID, Attribute, Attribute_, MetaItem}
;
16 use syntax
::ast
::MetaItemKind
;
19 use syntax
::codemap
::{respan, Spanned}
;
21 use syntax
::parse
::token
::keywords
;
22 use syntax
::util
::move_map
::MoveMap
;
24 pub trait Folder
: Sized
{
25 // Any additions to this trait should happen in form
26 // of a call to a public `noop_*` function that only calls
27 // out to the folder again, not other `noop_*` functions.
29 // This is a necessary API workaround to the problem of not
30 // being able to call out to the super default method
31 // in an overridden default method.
33 fn fold_crate(&mut self, c
: Crate
) -> Crate
{
34 noop_fold_crate(c
, self)
37 fn fold_meta_items(&mut self, meta_items
: HirVec
<P
<MetaItem
>>) -> HirVec
<P
<MetaItem
>> {
38 noop_fold_meta_items(meta_items
, self)
41 fn fold_meta_item(&mut self, meta_item
: P
<MetaItem
>) -> P
<MetaItem
> {
42 noop_fold_meta_item(meta_item
, self)
45 fn fold_view_path(&mut self, view_path
: P
<ViewPath
>) -> P
<ViewPath
> {
46 noop_fold_view_path(view_path
, self)
49 fn fold_foreign_item(&mut self, ni
: ForeignItem
) -> ForeignItem
{
50 noop_fold_foreign_item(ni
, self)
53 fn fold_item(&mut self, i
: Item
) -> Item
{
54 noop_fold_item(i
, self)
57 fn fold_item_id(&mut self, i
: ItemId
) -> ItemId
{
58 noop_fold_item_id(i
, self)
61 fn fold_struct_field(&mut self, sf
: StructField
) -> StructField
{
62 noop_fold_struct_field(sf
, self)
65 fn fold_item_underscore(&mut self, i
: Item_
) -> Item_
{
66 noop_fold_item_underscore(i
, self)
69 fn fold_trait_item(&mut self, i
: TraitItem
) -> TraitItem
{
70 noop_fold_trait_item(i
, self)
73 fn fold_impl_item(&mut self, i
: ImplItem
) -> ImplItem
{
74 noop_fold_impl_item(i
, self)
77 fn fold_fn_decl(&mut self, d
: P
<FnDecl
>) -> P
<FnDecl
> {
78 noop_fold_fn_decl(d
, self)
81 fn fold_block(&mut self, b
: P
<Block
>) -> P
<Block
> {
82 noop_fold_block(b
, self)
85 fn fold_stmt(&mut self, s
: Stmt
) -> Stmt
{
86 noop_fold_stmt(s
, self)
89 fn fold_arm(&mut self, a
: Arm
) -> Arm
{
90 noop_fold_arm(a
, self)
93 fn fold_pat(&mut self, p
: P
<Pat
>) -> P
<Pat
> {
94 noop_fold_pat(p
, self)
97 fn fold_decl(&mut self, d
: P
<Decl
>) -> P
<Decl
> {
98 noop_fold_decl(d
, self)
101 fn fold_expr(&mut self, e
: P
<Expr
>) -> P
<Expr
> {
102 e
.map(|e
| noop_fold_expr(e
, self))
105 fn fold_ty(&mut self, t
: P
<Ty
>) -> P
<Ty
> {
106 noop_fold_ty(t
, self)
109 fn fold_ty_binding(&mut self, t
: TypeBinding
) -> TypeBinding
{
110 noop_fold_ty_binding(t
, self)
113 fn fold_mod(&mut self, m
: Mod
) -> Mod
{
114 noop_fold_mod(m
, self)
117 fn fold_foreign_mod(&mut self, nm
: ForeignMod
) -> ForeignMod
{
118 noop_fold_foreign_mod(nm
, self)
121 fn fold_variant(&mut self, v
: Variant
) -> Variant
{
122 noop_fold_variant(v
, self)
125 fn fold_name(&mut self, n
: Name
) -> Name
{
126 noop_fold_name(n
, self)
129 fn fold_usize(&mut self, i
: usize) -> usize {
130 noop_fold_usize(i
, self)
133 fn fold_path(&mut self, p
: Path
) -> Path
{
134 noop_fold_path(p
, self)
137 fn fold_path_parameters(&mut self, p
: PathParameters
) -> PathParameters
{
138 noop_fold_path_parameters(p
, self)
141 fn fold_angle_bracketed_parameter_data(&mut self,
142 p
: AngleBracketedParameterData
)
143 -> AngleBracketedParameterData
{
144 noop_fold_angle_bracketed_parameter_data(p
, self)
147 fn fold_parenthesized_parameter_data(&mut self,
148 p
: ParenthesizedParameterData
)
149 -> ParenthesizedParameterData
{
150 noop_fold_parenthesized_parameter_data(p
, self)
153 fn fold_local(&mut self, l
: P
<Local
>) -> P
<Local
> {
154 noop_fold_local(l
, self)
157 fn fold_lifetime(&mut self, l
: Lifetime
) -> Lifetime
{
158 noop_fold_lifetime(l
, self)
161 fn fold_lifetime_def(&mut self, l
: LifetimeDef
) -> LifetimeDef
{
162 noop_fold_lifetime_def(l
, self)
165 fn fold_attribute(&mut self, at
: Attribute
) -> Option
<Attribute
> {
166 noop_fold_attribute(at
, self)
169 fn fold_arg(&mut self, a
: Arg
) -> Arg
{
170 noop_fold_arg(a
, self)
173 fn fold_generics(&mut self, generics
: Generics
) -> Generics
{
174 noop_fold_generics(generics
, self)
177 fn fold_trait_ref(&mut self, p
: TraitRef
) -> TraitRef
{
178 noop_fold_trait_ref(p
, self)
181 fn fold_poly_trait_ref(&mut self, p
: PolyTraitRef
) -> PolyTraitRef
{
182 noop_fold_poly_trait_ref(p
, self)
185 fn fold_variant_data(&mut self, vdata
: VariantData
) -> VariantData
{
186 noop_fold_variant_data(vdata
, self)
189 fn fold_lifetimes(&mut self, lts
: HirVec
<Lifetime
>) -> HirVec
<Lifetime
> {
190 noop_fold_lifetimes(lts
, self)
193 fn fold_lifetime_defs(&mut self, lts
: HirVec
<LifetimeDef
>) -> HirVec
<LifetimeDef
> {
194 noop_fold_lifetime_defs(lts
, self)
197 fn fold_ty_param(&mut self, tp
: TyParam
) -> TyParam
{
198 noop_fold_ty_param(tp
, self)
201 fn fold_ty_params(&mut self, tps
: HirVec
<TyParam
>) -> HirVec
<TyParam
> {
202 noop_fold_ty_params(tps
, self)
205 fn fold_opt_lifetime(&mut self, o_lt
: Option
<Lifetime
>) -> Option
<Lifetime
> {
206 noop_fold_opt_lifetime(o_lt
, self)
209 fn fold_opt_bounds(&mut self,
210 b
: Option
<TyParamBounds
>)
211 -> Option
<TyParamBounds
> {
212 noop_fold_opt_bounds(b
, self)
215 fn fold_bounds(&mut self, b
: TyParamBounds
) -> TyParamBounds
{
216 noop_fold_bounds(b
, self)
219 fn fold_ty_param_bound(&mut self, tpb
: TyParamBound
) -> TyParamBound
{
220 noop_fold_ty_param_bound(tpb
, self)
223 fn fold_mt(&mut self, mt
: MutTy
) -> MutTy
{
224 noop_fold_mt(mt
, self)
227 fn fold_field(&mut self, field
: Field
) -> Field
{
228 noop_fold_field(field
, self)
231 fn fold_where_clause(&mut self, where_clause
: WhereClause
) -> WhereClause
{
232 noop_fold_where_clause(where_clause
, self)
235 fn fold_where_predicate(&mut self, where_predicate
: WherePredicate
) -> WherePredicate
{
236 noop_fold_where_predicate(where_predicate
, self)
239 /// called for the `id` on each declaration
240 fn new_id(&mut self, i
: NodeId
) -> NodeId
{
244 /// called for ids that are references (e.g., ItemDef)
245 fn map_id(&mut self, i
: NodeId
) -> NodeId
{
249 fn new_span(&mut self, sp
: Span
) -> Span
{
254 pub fn noop_fold_meta_items
<T
: Folder
>(meta_items
: HirVec
<P
<MetaItem
>>,
256 -> HirVec
<P
<MetaItem
>> {
257 meta_items
.move_map(|x
| fld
.fold_meta_item(x
))
260 pub fn noop_fold_view_path
<T
: Folder
>(view_path
: P
<ViewPath
>, fld
: &mut T
) -> P
<ViewPath
> {
261 view_path
.map(|Spanned { node, span }
| {
264 ViewPathSimple(name
, path
) => {
265 ViewPathSimple(name
, fld
.fold_path(path
))
267 ViewPathGlob(path
) => {
268 ViewPathGlob(fld
.fold_path(path
))
270 ViewPathList(path
, path_list_idents
) => {
271 ViewPathList(fld
.fold_path(path
),
272 path_list_idents
.move_map(|path_list_ident
| {
274 node
: match path_list_ident
.node
{
275 PathListIdent { id, name, rename }
=> PathListIdent
{
280 PathListMod { id, rename }
=> PathListMod
{
285 span
: fld
.new_span(path_list_ident
.span
),
290 span
: fld
.new_span(span
),
295 pub fn fold_attrs
<T
, F
>(attrs
: T
, fld
: &mut F
) -> T
296 where T
: Into
<Vec
<Attribute
>> + From
<Vec
<Attribute
>>,
299 attrs
.into().move_flat_map(|x
| fld
.fold_attribute(x
)).into()
302 pub fn noop_fold_arm
<T
: Folder
>(Arm { attrs, pats, guard, body }
: Arm
, fld
: &mut T
) -> Arm
{
304 attrs
: fold_attrs(attrs
, fld
),
305 pats
: pats
.move_map(|x
| fld
.fold_pat(x
)),
306 guard
: guard
.map(|x
| fld
.fold_expr(x
)),
307 body
: fld
.fold_expr(body
),
311 pub fn noop_fold_decl
<T
: Folder
>(d
: P
<Decl
>, fld
: &mut T
) -> P
<Decl
> {
312 d
.map(|Spanned { node, span }
| {
314 DeclLocal(l
) => Spanned
{
315 node
: DeclLocal(fld
.fold_local(l
)),
316 span
: fld
.new_span(span
),
318 DeclItem(it
) => Spanned
{
319 node
: DeclItem(fld
.fold_item_id(it
)),
320 span
: fld
.new_span(span
),
326 pub fn noop_fold_ty_binding
<T
: Folder
>(b
: TypeBinding
, fld
: &mut T
) -> TypeBinding
{
328 id
: fld
.new_id(b
.id
),
330 ty
: fld
.fold_ty(b
.ty
),
331 span
: fld
.new_span(b
.span
),
335 pub fn noop_fold_ty
<T
: Folder
>(t
: P
<Ty
>, fld
: &mut T
) -> P
<Ty
> {
336 t
.map(|Ty { id, node, span }
| {
341 TyVec(ty
) => TyVec(fld
.fold_ty(ty
)),
342 TyPtr(mt
) => TyPtr(fld
.fold_mt(mt
)),
343 TyRptr(region
, mt
) => {
344 TyRptr(fld
.fold_opt_lifetime(region
), fld
.fold_mt(mt
))
347 TyBareFn(f
.map(|BareFnTy { lifetimes, unsafety, abi, decl }
| {
349 lifetimes
: fld
.fold_lifetime_defs(lifetimes
),
352 decl
: fld
.fold_fn_decl(decl
),
357 TyTup(tys
) => TyTup(tys
.move_map(|ty
| fld
.fold_ty(ty
))),
358 TyPath(qself
, path
) => {
359 let qself
= qself
.map(|QSelf { ty, position }
| {
365 TyPath(qself
, fld
.fold_path(path
))
367 TyObjectSum(ty
, bounds
) => {
368 TyObjectSum(fld
.fold_ty(ty
), fld
.fold_bounds(bounds
))
370 TyFixedLengthVec(ty
, e
) => {
371 TyFixedLengthVec(fld
.fold_ty(ty
), fld
.fold_expr(e
))
374 TyTypeof(fld
.fold_expr(expr
))
376 TyPolyTraitRef(bounds
) => {
377 TyPolyTraitRef(bounds
.move_map(|b
| fld
.fold_ty_param_bound(b
)))
379 TyImplTrait(bounds
) => {
380 TyImplTrait(bounds
.move_map(|b
| fld
.fold_ty_param_bound(b
)))
383 span
: fld
.new_span(span
),
388 pub fn noop_fold_foreign_mod
<T
: Folder
>(ForeignMod { abi, items }
: ForeignMod
,
393 items
: items
.move_map(|x
| fld
.fold_foreign_item(x
)),
397 pub fn noop_fold_variant
<T
: Folder
>(v
: Variant
, fld
: &mut T
) -> Variant
{
401 attrs
: fold_attrs(v
.node
.attrs
, fld
),
402 data
: fld
.fold_variant_data(v
.node
.data
),
403 disr_expr
: v
.node
.disr_expr
.map(|e
| fld
.fold_expr(e
)),
405 span
: fld
.new_span(v
.span
),
409 pub fn noop_fold_name
<T
: Folder
>(n
: Name
, _
: &mut T
) -> Name
{
413 pub fn noop_fold_usize
<T
: Folder
>(i
: usize, _
: &mut T
) -> usize {
417 pub fn noop_fold_path
<T
: Folder
>(Path { global, segments, span }
: Path
, fld
: &mut T
) -> Path
{
420 segments
: segments
.move_map(|PathSegment { name, parameters }
| {
422 name
: fld
.fold_name(name
),
423 parameters
: fld
.fold_path_parameters(parameters
),
426 span
: fld
.new_span(span
),
430 pub fn noop_fold_path_parameters
<T
: Folder
>(path_parameters
: PathParameters
,
433 match path_parameters
{
434 AngleBracketedParameters(data
) =>
435 AngleBracketedParameters(fld
.fold_angle_bracketed_parameter_data(data
)),
436 ParenthesizedParameters(data
) =>
437 ParenthesizedParameters(fld
.fold_parenthesized_parameter_data(data
)),
441 pub fn noop_fold_angle_bracketed_parameter_data
<T
: Folder
>(data
: AngleBracketedParameterData
,
443 -> AngleBracketedParameterData
{
444 let AngleBracketedParameterData { lifetimes, types, bindings }
= data
;
445 AngleBracketedParameterData
{
446 lifetimes
: fld
.fold_lifetimes(lifetimes
),
447 types
: types
.move_map(|ty
| fld
.fold_ty(ty
)),
448 bindings
: bindings
.move_map(|b
| fld
.fold_ty_binding(b
)),
452 pub fn noop_fold_parenthesized_parameter_data
<T
: Folder
>(data
: ParenthesizedParameterData
,
454 -> ParenthesizedParameterData
{
455 let ParenthesizedParameterData { inputs, output, span }
= data
;
456 ParenthesizedParameterData
{
457 inputs
: inputs
.move_map(|ty
| fld
.fold_ty(ty
)),
458 output
: output
.map(|ty
| fld
.fold_ty(ty
)),
459 span
: fld
.new_span(span
),
463 pub fn noop_fold_local
<T
: Folder
>(l
: P
<Local
>, fld
: &mut T
) -> P
<Local
> {
464 l
.map(|Local { id, pat, ty, init, span, attrs }
| {
467 ty
: ty
.map(|t
| fld
.fold_ty(t
)),
468 pat
: fld
.fold_pat(pat
),
469 init
: init
.map(|e
| fld
.fold_expr(e
)),
470 span
: fld
.new_span(span
),
471 attrs
: fold_attrs(attrs
, fld
),
476 pub fn noop_fold_attribute
<T
: Folder
>(at
: Attribute
, fld
: &mut T
) -> Option
<Attribute
> {
477 let Spanned {node: Attribute_ {id, style, value, is_sugared_doc}
, span
} = at
;
482 value
: fld
.fold_meta_item(value
),
483 is_sugared_doc
: is_sugared_doc
,
485 span
: fld
.new_span(span
),
489 pub fn noop_fold_meta_item
<T
: Folder
>(mi
: P
<MetaItem
>, fld
: &mut T
) -> P
<MetaItem
> {
490 mi
.map(|Spanned { node, span }
| {
493 MetaItemKind
::Word(id
) => MetaItemKind
::Word(id
),
494 MetaItemKind
::List(id
, mis
) => {
495 MetaItemKind
::List(id
, mis
.move_map(|e
| fld
.fold_meta_item(e
)))
497 MetaItemKind
::NameValue(id
, s
) => MetaItemKind
::NameValue(id
, s
),
499 span
: fld
.new_span(span
),
504 pub fn noop_fold_arg
<T
: Folder
>(Arg { id, pat, ty }
: Arg
, fld
: &mut T
) -> Arg
{
507 pat
: fld
.fold_pat(pat
),
512 pub fn noop_fold_fn_decl
<T
: Folder
>(decl
: P
<FnDecl
>, fld
: &mut T
) -> P
<FnDecl
> {
513 decl
.map(|FnDecl { inputs, output, variadic }
| {
515 inputs
: inputs
.move_map(|x
| fld
.fold_arg(x
)),
516 output
: match output
{
517 Return(ty
) => Return(fld
.fold_ty(ty
)),
518 DefaultReturn(span
) => DefaultReturn(span
),
525 pub fn noop_fold_ty_param_bound
<T
>(tpb
: TyParamBound
, fld
: &mut T
) -> TyParamBound
529 TraitTyParamBound(ty
, modifier
) => TraitTyParamBound(fld
.fold_poly_trait_ref(ty
), modifier
),
530 RegionTyParamBound(lifetime
) => RegionTyParamBound(fld
.fold_lifetime(lifetime
)),
534 pub fn noop_fold_ty_param
<T
: Folder
>(tp
: TyParam
, fld
: &mut T
) -> TyParam
{
535 let TyParam {id, name, bounds, default, span}
= tp
;
539 bounds
: fld
.fold_bounds(bounds
),
540 default: default.map(|x
| fld
.fold_ty(x
)),
545 pub fn noop_fold_ty_params
<T
: Folder
>(tps
: HirVec
<TyParam
>,
548 tps
.move_map(|tp
| fld
.fold_ty_param(tp
))
551 pub fn noop_fold_lifetime
<T
: Folder
>(l
: Lifetime
, fld
: &mut T
) -> Lifetime
{
553 id
: fld
.new_id(l
.id
),
555 span
: fld
.new_span(l
.span
),
559 pub fn noop_fold_lifetime_def
<T
: Folder
>(l
: LifetimeDef
, fld
: &mut T
) -> LifetimeDef
{
561 lifetime
: fld
.fold_lifetime(l
.lifetime
),
562 bounds
: fld
.fold_lifetimes(l
.bounds
),
566 pub fn noop_fold_lifetimes
<T
: Folder
>(lts
: HirVec
<Lifetime
>, fld
: &mut T
) -> HirVec
<Lifetime
> {
567 lts
.move_map(|l
| fld
.fold_lifetime(l
))
570 pub fn noop_fold_lifetime_defs
<T
: Folder
>(lts
: HirVec
<LifetimeDef
>,
572 -> HirVec
<LifetimeDef
> {
573 lts
.move_map(|l
| fld
.fold_lifetime_def(l
))
576 pub fn noop_fold_opt_lifetime
<T
: Folder
>(o_lt
: Option
<Lifetime
>, fld
: &mut T
) -> Option
<Lifetime
> {
577 o_lt
.map(|lt
| fld
.fold_lifetime(lt
))
580 pub fn noop_fold_generics
<T
: Folder
>(Generics { ty_params, lifetimes, where_clause }
: Generics
,
584 ty_params
: fld
.fold_ty_params(ty_params
),
585 lifetimes
: fld
.fold_lifetime_defs(lifetimes
),
586 where_clause
: fld
.fold_where_clause(where_clause
),
590 pub fn noop_fold_where_clause
<T
: Folder
>(WhereClause { id, predicates }
: WhereClause
,
595 predicates
: predicates
.move_map(|predicate
| fld
.fold_where_predicate(predicate
)),
599 pub fn noop_fold_where_predicate
<T
: Folder
>(pred
: WherePredicate
, fld
: &mut T
) -> WherePredicate
{
601 hir
::WherePredicate
::BoundPredicate(hir
::WhereBoundPredicate
{bound_lifetimes
,
605 hir
::WherePredicate
::BoundPredicate(hir
::WhereBoundPredicate
{
606 bound_lifetimes
: fld
.fold_lifetime_defs(bound_lifetimes
),
607 bounded_ty
: fld
.fold_ty(bounded_ty
),
608 bounds
: bounds
.move_map(|x
| fld
.fold_ty_param_bound(x
)),
609 span
: fld
.new_span(span
),
612 hir
::WherePredicate
::RegionPredicate(hir
::WhereRegionPredicate
{lifetime
,
615 hir
::WherePredicate
::RegionPredicate(hir
::WhereRegionPredicate
{
616 span
: fld
.new_span(span
),
617 lifetime
: fld
.fold_lifetime(lifetime
),
618 bounds
: bounds
.move_map(|bound
| fld
.fold_lifetime(bound
)),
621 hir
::WherePredicate
::EqPredicate(hir
::WhereEqPredicate
{id
,
625 hir
::WherePredicate
::EqPredicate(hir
::WhereEqPredicate
{
627 path
: fld
.fold_path(path
),
629 span
: fld
.new_span(span
),
635 pub fn noop_fold_variant_data
<T
: Folder
>(vdata
: VariantData
, fld
: &mut T
) -> VariantData
{
637 VariantData
::Struct(fields
, id
) => {
638 VariantData
::Struct(fields
.move_map(|f
| fld
.fold_struct_field(f
)),
641 VariantData
::Tuple(fields
, id
) => {
642 VariantData
::Tuple(fields
.move_map(|f
| fld
.fold_struct_field(f
)),
645 VariantData
::Unit(id
) => VariantData
::Unit(fld
.new_id(id
)),
649 pub fn noop_fold_trait_ref
<T
: Folder
>(p
: TraitRef
, fld
: &mut T
) -> TraitRef
{
650 let id
= fld
.new_id(p
.ref_id
);
656 path
: fld
.fold_path(path
),
661 pub fn noop_fold_poly_trait_ref
<T
: Folder
>(p
: PolyTraitRef
, fld
: &mut T
) -> PolyTraitRef
{
663 bound_lifetimes
: fld
.fold_lifetime_defs(p
.bound_lifetimes
),
664 trait_ref
: fld
.fold_trait_ref(p
.trait_ref
),
665 span
: fld
.new_span(p
.span
),
669 pub fn noop_fold_struct_field
<T
: Folder
>(f
: StructField
, fld
: &mut T
) -> StructField
{
671 span
: fld
.new_span(f
.span
),
672 id
: fld
.new_id(f
.id
),
675 ty
: fld
.fold_ty(f
.ty
),
676 attrs
: fold_attrs(f
.attrs
, fld
),
680 pub fn noop_fold_field
<T
: Folder
>(Field { name, expr, span }
: Field
, folder
: &mut T
) -> Field
{
682 name
: respan(folder
.new_span(name
.span
), folder
.fold_name(name
.node
)),
683 expr
: folder
.fold_expr(expr
),
684 span
: folder
.new_span(span
),
688 pub fn noop_fold_mt
<T
: Folder
>(MutTy { ty, mutbl }
: MutTy
, folder
: &mut T
) -> MutTy
{
690 ty
: folder
.fold_ty(ty
),
695 pub fn noop_fold_opt_bounds
<T
: Folder
>(b
: Option
<TyParamBounds
>,
697 -> Option
<TyParamBounds
> {
698 b
.map(|bounds
| folder
.fold_bounds(bounds
))
701 fn noop_fold_bounds
<T
: Folder
>(bounds
: TyParamBounds
, folder
: &mut T
) -> TyParamBounds
{
702 bounds
.move_map(|bound
| folder
.fold_ty_param_bound(bound
))
705 pub fn noop_fold_block
<T
: Folder
>(b
: P
<Block
>, folder
: &mut T
) -> P
<Block
> {
706 b
.map(|Block { id, stmts, expr, rules, span }
| {
708 id
: folder
.new_id(id
),
709 stmts
: stmts
.move_map(|s
| folder
.fold_stmt(s
)),
710 expr
: expr
.map(|x
| folder
.fold_expr(x
)),
712 span
: folder
.new_span(span
),
717 pub fn noop_fold_item_underscore
<T
: Folder
>(i
: Item_
, folder
: &mut T
) -> Item_
{
719 ItemExternCrate(string
) => ItemExternCrate(string
),
720 ItemUse(view_path
) => {
721 ItemUse(folder
.fold_view_path(view_path
))
723 ItemStatic(t
, m
, e
) => {
724 ItemStatic(folder
.fold_ty(t
), m
, folder
.fold_expr(e
))
727 ItemConst(folder
.fold_ty(t
), folder
.fold_expr(e
))
729 ItemFn(decl
, unsafety
, constness
, abi
, generics
, body
) => {
730 ItemFn(folder
.fold_fn_decl(decl
),
734 folder
.fold_generics(generics
),
735 folder
.fold_block(body
))
737 ItemMod(m
) => ItemMod(folder
.fold_mod(m
)),
738 ItemForeignMod(nm
) => ItemForeignMod(folder
.fold_foreign_mod(nm
)),
739 ItemTy(t
, generics
) => {
740 ItemTy(folder
.fold_ty(t
), folder
.fold_generics(generics
))
742 ItemEnum(enum_definition
, generics
) => {
743 ItemEnum(hir
::EnumDef
{
744 variants
: enum_definition
.variants
.move_map(|x
| folder
.fold_variant(x
)),
746 folder
.fold_generics(generics
))
748 ItemStruct(struct_def
, generics
) => {
749 let struct_def
= folder
.fold_variant_data(struct_def
);
750 ItemStruct(struct_def
, folder
.fold_generics(generics
))
752 ItemDefaultImpl(unsafety
, ref trait_ref
) => {
753 ItemDefaultImpl(unsafety
, folder
.fold_trait_ref((*trait_ref
).clone()))
755 ItemImpl(unsafety
, polarity
, generics
, ifce
, ty
, impl_items
) => {
756 let new_impl_items
= impl_items
757 .move_map(|item
| folder
.fold_impl_item(item
));
758 let ifce
= match ifce
{
760 Some(ref trait_ref
) => {
761 Some(folder
.fold_trait_ref((*trait_ref
).clone()))
766 folder
.fold_generics(generics
),
771 ItemTrait(unsafety
, generics
, bounds
, items
) => {
772 let bounds
= folder
.fold_bounds(bounds
);
773 let items
= items
.move_map(|item
| folder
.fold_trait_item(item
));
774 ItemTrait(unsafety
, folder
.fold_generics(generics
), bounds
, items
)
779 pub fn noop_fold_trait_item
<T
: Folder
>(i
: TraitItem
,
783 id
: folder
.new_id(i
.id
),
784 name
: folder
.fold_name(i
.name
),
785 attrs
: fold_attrs(i
.attrs
, folder
),
787 ConstTraitItem(ty
, default) => {
788 ConstTraitItem(folder
.fold_ty(ty
), default.map(|x
| folder
.fold_expr(x
)))
790 MethodTraitItem(sig
, body
) => {
791 MethodTraitItem(noop_fold_method_sig(sig
, folder
),
792 body
.map(|x
| folder
.fold_block(x
)))
794 TypeTraitItem(bounds
, default) => {
795 TypeTraitItem(folder
.fold_bounds(bounds
),
796 default.map(|x
| folder
.fold_ty(x
)))
799 span
: folder
.new_span(i
.span
),
803 pub fn noop_fold_impl_item
<T
: Folder
>(i
: ImplItem
, folder
: &mut T
) -> ImplItem
{
805 id
: folder
.new_id(i
.id
),
806 name
: folder
.fold_name(i
.name
),
807 attrs
: fold_attrs(i
.attrs
, folder
),
809 defaultness
: i
.defaultness
,
811 ImplItemKind
::Const(ty
, expr
) => {
812 ImplItemKind
::Const(folder
.fold_ty(ty
), folder
.fold_expr(expr
))
814 ImplItemKind
::Method(sig
, body
) => {
815 ImplItemKind
::Method(noop_fold_method_sig(sig
, folder
), folder
.fold_block(body
))
817 ImplItemKind
::Type(ty
) => ImplItemKind
::Type(folder
.fold_ty(ty
)),
819 span
: folder
.new_span(i
.span
),
823 pub fn noop_fold_mod
<T
: Folder
>(Mod { inner, item_ids }
: Mod
, folder
: &mut T
) -> Mod
{
825 inner
: folder
.new_span(inner
),
826 item_ids
: item_ids
.move_map(|x
| folder
.fold_item_id(x
)),
830 pub fn noop_fold_crate
<T
: Folder
>(Crate
{ module
, attrs
, config
, span
,
831 exported_macros
, items
}: Crate
,
834 let config
= folder
.fold_meta_items(config
);
836 let crate_mod
= folder
.fold_item(hir
::Item
{
837 name
: keywords
::Invalid
.name(),
842 node
: hir
::ItemMod(module
),
845 let (module
, attrs
, span
) = match crate_mod
{
846 hir
::Item { attrs, span, node, .. }
=> {
848 hir
::ItemMod(m
) => (m
, attrs
, span
),
849 _
=> panic
!("fold converted a module to not a module"),
854 let items
= items
.into_iter()
855 .map(|(id
, item
)| (id
, folder
.fold_item(item
)))
863 exported_macros
: exported_macros
,
868 pub fn noop_fold_item_id
<T
: Folder
>(i
: ItemId
, folder
: &mut T
) -> ItemId
{
869 let id
= folder
.map_id(i
.id
);
873 // fold one item into one item
874 pub fn noop_fold_item
<T
: Folder
>(item
: Item
, folder
: &mut T
) -> Item
{
875 let Item { id, name, attrs, node, vis, span }
= item
;
876 let id
= folder
.new_id(id
);
877 let node
= folder
.fold_item_underscore(node
);
881 name
: folder
.fold_name(name
),
882 attrs
: fold_attrs(attrs
, folder
),
885 span
: folder
.new_span(span
),
889 pub fn noop_fold_foreign_item
<T
: Folder
>(ni
: ForeignItem
, folder
: &mut T
) -> ForeignItem
{
891 id
: folder
.new_id(ni
.id
),
892 name
: folder
.fold_name(ni
.name
),
893 attrs
: fold_attrs(ni
.attrs
, folder
),
894 node
: match ni
.node
{
895 ForeignItemFn(fdec
, generics
) => {
896 ForeignItemFn(folder
.fold_fn_decl(fdec
), folder
.fold_generics(generics
))
898 ForeignItemStatic(t
, m
) => {
899 ForeignItemStatic(folder
.fold_ty(t
), m
)
903 span
: folder
.new_span(ni
.span
),
907 pub fn noop_fold_method_sig
<T
: Folder
>(sig
: MethodSig
, folder
: &mut T
) -> MethodSig
{
909 generics
: folder
.fold_generics(sig
.generics
),
911 unsafety
: sig
.unsafety
,
912 constness
: sig
.constness
,
913 decl
: folder
.fold_fn_decl(sig
.decl
),
917 pub fn noop_fold_pat
<T
: Folder
>(p
: P
<Pat
>, folder
: &mut T
) -> P
<Pat
> {
918 p
.map(|Pat { id, node, span }
| {
920 id
: folder
.new_id(id
),
922 PatKind
::Wild
=> PatKind
::Wild
,
923 PatKind
::Binding(binding_mode
, pth1
, sub
) => {
924 PatKind
::Binding(binding_mode
,
926 span
: folder
.new_span(pth1
.span
),
927 node
: folder
.fold_name(pth1
.node
),
929 sub
.map(|x
| folder
.fold_pat(x
)))
931 PatKind
::Lit(e
) => PatKind
::Lit(folder
.fold_expr(e
)),
932 PatKind
::TupleStruct(pth
, pats
, ddpos
) => {
933 PatKind
::TupleStruct(folder
.fold_path(pth
),
934 pats
.move_map(|x
| folder
.fold_pat(x
)), ddpos
)
936 PatKind
::Path(opt_qself
, pth
) => {
937 let opt_qself
= opt_qself
.map(|qself
| {
938 QSelf { ty: folder.fold_ty(qself.ty), position: qself.position }
940 PatKind
::Path(opt_qself
, folder
.fold_path(pth
))
942 PatKind
::Struct(pth
, fields
, etc
) => {
943 let pth
= folder
.fold_path(pth
);
944 let fs
= fields
.move_map(|f
| {
946 span
: folder
.new_span(f
.span
),
947 node
: hir
::FieldPat
{
949 pat
: folder
.fold_pat(f
.node
.pat
),
950 is_shorthand
: f
.node
.is_shorthand
,
954 PatKind
::Struct(pth
, fs
, etc
)
956 PatKind
::Tuple(elts
, ddpos
) => {
957 PatKind
::Tuple(elts
.move_map(|x
| folder
.fold_pat(x
)), ddpos
)
959 PatKind
::Box(inner
) => PatKind
::Box(folder
.fold_pat(inner
)),
960 PatKind
::Ref(inner
, mutbl
) => PatKind
::Ref(folder
.fold_pat(inner
), mutbl
),
961 PatKind
::Range(e1
, e2
) => {
962 PatKind
::Range(folder
.fold_expr(e1
), folder
.fold_expr(e2
))
964 PatKind
::Vec(before
, slice
, after
) => {
965 PatKind
::Vec(before
.move_map(|x
| folder
.fold_pat(x
)),
966 slice
.map(|x
| folder
.fold_pat(x
)),
967 after
.move_map(|x
| folder
.fold_pat(x
)))
970 span
: folder
.new_span(span
),
975 pub fn noop_fold_expr
<T
: Folder
>(Expr { id, node, span, attrs }
: Expr
, folder
: &mut T
) -> Expr
{
977 id
: folder
.new_id(id
),
980 ExprBox(folder
.fold_expr(e
))
983 ExprVec(exprs
.move_map(|x
| folder
.fold_expr(x
)))
985 ExprRepeat(expr
, count
) => {
986 ExprRepeat(folder
.fold_expr(expr
), folder
.fold_expr(count
))
988 ExprTup(elts
) => ExprTup(elts
.move_map(|x
| folder
.fold_expr(x
))),
989 ExprCall(f
, args
) => {
990 ExprCall(folder
.fold_expr(f
), args
.move_map(|x
| folder
.fold_expr(x
)))
992 ExprMethodCall(name
, tps
, args
) => {
993 ExprMethodCall(respan(folder
.new_span(name
.span
), folder
.fold_name(name
.node
)),
994 tps
.move_map(|x
| folder
.fold_ty(x
)),
995 args
.move_map(|x
| folder
.fold_expr(x
)))
997 ExprBinary(binop
, lhs
, rhs
) => {
998 ExprBinary(binop
, folder
.fold_expr(lhs
), folder
.fold_expr(rhs
))
1000 ExprUnary(binop
, ohs
) => {
1001 ExprUnary(binop
, folder
.fold_expr(ohs
))
1003 ExprLit(l
) => ExprLit(l
),
1004 ExprCast(expr
, ty
) => {
1005 ExprCast(folder
.fold_expr(expr
), folder
.fold_ty(ty
))
1007 ExprType(expr
, ty
) => {
1008 ExprType(folder
.fold_expr(expr
), folder
.fold_ty(ty
))
1010 ExprAddrOf(m
, ohs
) => ExprAddrOf(m
, folder
.fold_expr(ohs
)),
1011 ExprIf(cond
, tr
, fl
) => {
1012 ExprIf(folder
.fold_expr(cond
),
1013 folder
.fold_block(tr
),
1014 fl
.map(|x
| folder
.fold_expr(x
)))
1016 ExprWhile(cond
, body
, opt_name
) => {
1017 ExprWhile(folder
.fold_expr(cond
),
1018 folder
.fold_block(body
),
1019 opt_name
.map(|label
| {
1020 respan(folder
.new_span(label
.span
), folder
.fold_name(label
.node
))
1023 ExprLoop(body
, opt_name
) => {
1024 ExprLoop(folder
.fold_block(body
),
1025 opt_name
.map(|label
| {
1026 respan(folder
.new_span(label
.span
), folder
.fold_name(label
.node
))
1029 ExprMatch(expr
, arms
, source
) => {
1030 ExprMatch(folder
.fold_expr(expr
),
1031 arms
.move_map(|x
| folder
.fold_arm(x
)),
1034 ExprClosure(capture_clause
, decl
, body
, fn_decl_span
) => {
1035 ExprClosure(capture_clause
,
1036 folder
.fold_fn_decl(decl
),
1037 folder
.fold_block(body
),
1038 folder
.new_span(fn_decl_span
))
1040 ExprBlock(blk
) => ExprBlock(folder
.fold_block(blk
)),
1041 ExprAssign(el
, er
) => {
1042 ExprAssign(folder
.fold_expr(el
), folder
.fold_expr(er
))
1044 ExprAssignOp(op
, el
, er
) => {
1045 ExprAssignOp(op
, folder
.fold_expr(el
), folder
.fold_expr(er
))
1047 ExprField(el
, name
) => {
1048 ExprField(folder
.fold_expr(el
),
1049 respan(folder
.new_span(name
.span
), folder
.fold_name(name
.node
)))
1051 ExprTupField(el
, index
) => {
1052 ExprTupField(folder
.fold_expr(el
),
1053 respan(folder
.new_span(index
.span
), folder
.fold_usize(index
.node
)))
1055 ExprIndex(el
, er
) => {
1056 ExprIndex(folder
.fold_expr(el
), folder
.fold_expr(er
))
1058 ExprPath(qself
, path
) => {
1059 let qself
= qself
.map(|QSelf { ty, position }
| {
1061 ty
: folder
.fold_ty(ty
),
1065 ExprPath(qself
, folder
.fold_path(path
))
1067 ExprBreak(opt_name
) => ExprBreak(opt_name
.map(|label
| {
1068 respan(folder
.new_span(label
.span
), folder
.fold_name(label
.node
))
1070 ExprAgain(opt_name
) => ExprAgain(opt_name
.map(|label
| {
1071 respan(folder
.new_span(label
.span
), folder
.fold_name(label
.node
))
1073 ExprRet(e
) => ExprRet(e
.map(|x
| folder
.fold_expr(x
))),
1074 ExprInlineAsm(asm
, outputs
, inputs
) => {
1076 outputs
.move_map(|x
| folder
.fold_expr(x
)),
1077 inputs
.move_map(|x
| folder
.fold_expr(x
)))
1079 ExprStruct(path
, fields
, maybe_expr
) => {
1080 ExprStruct(folder
.fold_path(path
),
1081 fields
.move_map(|x
| folder
.fold_field(x
)),
1082 maybe_expr
.map(|x
| folder
.fold_expr(x
)))
1085 span
: folder
.new_span(span
),
1086 attrs
: fold_attrs(attrs
, folder
),
1090 pub fn noop_fold_stmt
<T
: Folder
>(stmt
: Stmt
, folder
: &mut T
) -> Stmt
{
1091 let span
= folder
.new_span(stmt
.span
);
1093 StmtDecl(d
, id
) => {
1094 let id
= folder
.new_id(id
);
1096 node
: StmtDecl(folder
.fold_decl(d
), id
),
1100 StmtExpr(e
, id
) => {
1101 let id
= folder
.new_id(id
);
1103 node
: StmtExpr(folder
.fold_expr(e
), id
),
1107 StmtSemi(e
, id
) => {
1108 let id
= folder
.new_id(id
);
1110 node
: StmtSemi(folder
.fold_expr(e
), id
),