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
;
17 use syntax
::attr
::ThinAttributesExt
;
19 use syntax
::codemap
::{respan, Span, Spanned}
;
21 use syntax
::parse
::token
;
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_ident(&mut self, i
: Ident
) -> Ident
{
130 noop_fold_ident(i
, self)
133 fn fold_usize(&mut self, i
: usize) -> usize {
134 noop_fold_usize(i
, self)
137 fn fold_path(&mut self, p
: Path
) -> Path
{
138 noop_fold_path(p
, self)
141 fn fold_path_parameters(&mut self, p
: PathParameters
) -> PathParameters
{
142 noop_fold_path_parameters(p
, self)
145 fn fold_angle_bracketed_parameter_data(&mut self,
146 p
: AngleBracketedParameterData
)
147 -> AngleBracketedParameterData
{
148 noop_fold_angle_bracketed_parameter_data(p
, self)
151 fn fold_parenthesized_parameter_data(&mut self,
152 p
: ParenthesizedParameterData
)
153 -> ParenthesizedParameterData
{
154 noop_fold_parenthesized_parameter_data(p
, self)
157 fn fold_local(&mut self, l
: P
<Local
>) -> P
<Local
> {
158 noop_fold_local(l
, self)
161 fn fold_explicit_self(&mut self, es
: ExplicitSelf
) -> ExplicitSelf
{
162 noop_fold_explicit_self(es
, self)
165 fn fold_explicit_self_underscore(&mut self, es
: ExplicitSelf_
) -> ExplicitSelf_
{
166 noop_fold_explicit_self_underscore(es
, self)
169 fn fold_lifetime(&mut self, l
: Lifetime
) -> Lifetime
{
170 noop_fold_lifetime(l
, self)
173 fn fold_lifetime_def(&mut self, l
: LifetimeDef
) -> LifetimeDef
{
174 noop_fold_lifetime_def(l
, self)
177 fn fold_attribute(&mut self, at
: Attribute
) -> Option
<Attribute
> {
178 noop_fold_attribute(at
, self)
181 fn fold_arg(&mut self, a
: Arg
) -> Arg
{
182 noop_fold_arg(a
, self)
185 fn fold_generics(&mut self, generics
: Generics
) -> Generics
{
186 noop_fold_generics(generics
, self)
189 fn fold_trait_ref(&mut self, p
: TraitRef
) -> TraitRef
{
190 noop_fold_trait_ref(p
, self)
193 fn fold_poly_trait_ref(&mut self, p
: PolyTraitRef
) -> PolyTraitRef
{
194 noop_fold_poly_trait_ref(p
, self)
197 fn fold_variant_data(&mut self, vdata
: VariantData
) -> VariantData
{
198 noop_fold_variant_data(vdata
, self)
201 fn fold_lifetimes(&mut self, lts
: HirVec
<Lifetime
>) -> HirVec
<Lifetime
> {
202 noop_fold_lifetimes(lts
, self)
205 fn fold_lifetime_defs(&mut self, lts
: HirVec
<LifetimeDef
>) -> HirVec
<LifetimeDef
> {
206 noop_fold_lifetime_defs(lts
, self)
209 fn fold_ty_param(&mut self, tp
: TyParam
) -> TyParam
{
210 noop_fold_ty_param(tp
, self)
213 fn fold_ty_params(&mut self, tps
: HirVec
<TyParam
>) -> HirVec
<TyParam
> {
214 noop_fold_ty_params(tps
, self)
217 fn fold_opt_lifetime(&mut self, o_lt
: Option
<Lifetime
>) -> Option
<Lifetime
> {
218 noop_fold_opt_lifetime(o_lt
, self)
221 fn fold_opt_bounds(&mut self,
222 b
: Option
<TyParamBounds
>)
223 -> Option
<TyParamBounds
> {
224 noop_fold_opt_bounds(b
, self)
227 fn fold_bounds(&mut self, b
: TyParamBounds
) -> TyParamBounds
{
228 noop_fold_bounds(b
, self)
231 fn fold_ty_param_bound(&mut self, tpb
: TyParamBound
) -> TyParamBound
{
232 noop_fold_ty_param_bound(tpb
, self)
235 fn fold_mt(&mut self, mt
: MutTy
) -> MutTy
{
236 noop_fold_mt(mt
, self)
239 fn fold_field(&mut self, field
: Field
) -> Field
{
240 noop_fold_field(field
, self)
243 fn fold_where_clause(&mut self, where_clause
: WhereClause
) -> WhereClause
{
244 noop_fold_where_clause(where_clause
, self)
247 fn fold_where_predicate(&mut self, where_predicate
: WherePredicate
) -> WherePredicate
{
248 noop_fold_where_predicate(where_predicate
, self)
251 /// called for the `id` on each declaration
252 fn new_id(&mut self, i
: NodeId
) -> NodeId
{
256 /// called for ids that are references (e.g., ItemDef)
257 fn map_id(&mut self, i
: NodeId
) -> NodeId
{
261 fn new_span(&mut self, sp
: Span
) -> Span
{
266 pub fn noop_fold_meta_items
<T
: Folder
>(meta_items
: HirVec
<P
<MetaItem
>>,
268 -> HirVec
<P
<MetaItem
>> {
269 meta_items
.move_map(|x
| fld
.fold_meta_item(x
))
272 pub fn noop_fold_view_path
<T
: Folder
>(view_path
: P
<ViewPath
>, fld
: &mut T
) -> P
<ViewPath
> {
273 view_path
.map(|Spanned { node, span }
| {
276 ViewPathSimple(name
, path
) => {
277 ViewPathSimple(name
, fld
.fold_path(path
))
279 ViewPathGlob(path
) => {
280 ViewPathGlob(fld
.fold_path(path
))
282 ViewPathList(path
, path_list_idents
) => {
283 ViewPathList(fld
.fold_path(path
),
284 path_list_idents
.move_map(|path_list_ident
| {
286 node
: match path_list_ident
.node
{
287 PathListIdent { id, name, rename }
=> PathListIdent
{
292 PathListMod { id, rename }
=> PathListMod
{
297 span
: fld
.new_span(path_list_ident
.span
),
302 span
: fld
.new_span(span
),
307 pub fn fold_attrs
<T
: Folder
>(attrs
: HirVec
<Attribute
>, fld
: &mut T
) -> HirVec
<Attribute
> {
308 attrs
.move_flat_map(|x
| fld
.fold_attribute(x
))
311 pub fn noop_fold_arm
<T
: Folder
>(Arm { attrs, pats, guard, body }
: Arm
, fld
: &mut T
) -> Arm
{
313 attrs
: fold_attrs(attrs
, fld
),
314 pats
: pats
.move_map(|x
| fld
.fold_pat(x
)),
315 guard
: guard
.map(|x
| fld
.fold_expr(x
)),
316 body
: fld
.fold_expr(body
),
320 pub fn noop_fold_decl
<T
: Folder
>(d
: P
<Decl
>, fld
: &mut T
) -> P
<Decl
> {
321 d
.map(|Spanned { node, span }
| {
323 DeclLocal(l
) => Spanned
{
324 node
: DeclLocal(fld
.fold_local(l
)),
325 span
: fld
.new_span(span
),
327 DeclItem(it
) => Spanned
{
328 node
: DeclItem(fld
.fold_item_id(it
)),
329 span
: fld
.new_span(span
),
335 pub fn noop_fold_ty_binding
<T
: Folder
>(b
: TypeBinding
, fld
: &mut T
) -> TypeBinding
{
337 id
: fld
.new_id(b
.id
),
339 ty
: fld
.fold_ty(b
.ty
),
340 span
: fld
.new_span(b
.span
),
344 pub fn noop_fold_ty
<T
: Folder
>(t
: P
<Ty
>, fld
: &mut T
) -> P
<Ty
> {
345 t
.map(|Ty { id, node, span }
| {
350 TyVec(ty
) => TyVec(fld
.fold_ty(ty
)),
351 TyPtr(mt
) => TyPtr(fld
.fold_mt(mt
)),
352 TyRptr(region
, mt
) => {
353 TyRptr(fld
.fold_opt_lifetime(region
), fld
.fold_mt(mt
))
356 TyBareFn(f
.map(|BareFnTy { lifetimes, unsafety, abi, decl }
| {
358 lifetimes
: fld
.fold_lifetime_defs(lifetimes
),
361 decl
: fld
.fold_fn_decl(decl
),
365 TyTup(tys
) => TyTup(tys
.move_map(|ty
| fld
.fold_ty(ty
))),
366 TyPath(qself
, path
) => {
367 let qself
= qself
.map(|QSelf { ty, position }
| {
373 TyPath(qself
, fld
.fold_path(path
))
375 TyObjectSum(ty
, bounds
) => {
376 TyObjectSum(fld
.fold_ty(ty
), fld
.fold_bounds(bounds
))
378 TyFixedLengthVec(ty
, e
) => {
379 TyFixedLengthVec(fld
.fold_ty(ty
), fld
.fold_expr(e
))
382 TyTypeof(fld
.fold_expr(expr
))
384 TyPolyTraitRef(bounds
) => {
385 TyPolyTraitRef(bounds
.move_map(|b
| fld
.fold_ty_param_bound(b
)))
388 span
: fld
.new_span(span
),
393 pub fn noop_fold_foreign_mod
<T
: Folder
>(ForeignMod { abi, items }
: ForeignMod
,
398 items
: items
.move_map(|x
| fld
.fold_foreign_item(x
)),
402 pub fn noop_fold_variant
<T
: Folder
>(v
: Variant
, fld
: &mut T
) -> Variant
{
406 attrs
: fold_attrs(v
.node
.attrs
, fld
),
407 data
: fld
.fold_variant_data(v
.node
.data
),
408 disr_expr
: v
.node
.disr_expr
.map(|e
| fld
.fold_expr(e
)),
410 span
: fld
.new_span(v
.span
),
414 pub fn noop_fold_name
<T
: Folder
>(n
: Name
, _
: &mut T
) -> Name
{
418 pub fn noop_fold_ident
<T
: Folder
>(i
: Ident
, _
: &mut T
) -> Ident
{
422 pub fn noop_fold_usize
<T
: Folder
>(i
: usize, _
: &mut T
) -> usize {
426 pub fn noop_fold_path
<T
: Folder
>(Path { global, segments, span }
: Path
, fld
: &mut T
) -> Path
{
429 segments
: segments
.move_map(|PathSegment { identifier, parameters }
| {
431 identifier
: fld
.fold_ident(identifier
),
432 parameters
: fld
.fold_path_parameters(parameters
),
435 span
: fld
.new_span(span
),
439 pub fn noop_fold_path_parameters
<T
: Folder
>(path_parameters
: PathParameters
,
442 match path_parameters
{
443 AngleBracketedParameters(data
) =>
444 AngleBracketedParameters(fld
.fold_angle_bracketed_parameter_data(data
)),
445 ParenthesizedParameters(data
) =>
446 ParenthesizedParameters(fld
.fold_parenthesized_parameter_data(data
)),
450 pub fn noop_fold_angle_bracketed_parameter_data
<T
: Folder
>(data
: AngleBracketedParameterData
,
452 -> AngleBracketedParameterData
{
453 let AngleBracketedParameterData { lifetimes, types, bindings }
= data
;
454 AngleBracketedParameterData
{
455 lifetimes
: fld
.fold_lifetimes(lifetimes
),
456 types
: types
.move_map(|ty
| fld
.fold_ty(ty
)),
457 bindings
: bindings
.move_map(|b
| fld
.fold_ty_binding(b
)),
461 pub fn noop_fold_parenthesized_parameter_data
<T
: Folder
>(data
: ParenthesizedParameterData
,
463 -> ParenthesizedParameterData
{
464 let ParenthesizedParameterData { inputs, output, span }
= data
;
465 ParenthesizedParameterData
{
466 inputs
: inputs
.move_map(|ty
| fld
.fold_ty(ty
)),
467 output
: output
.map(|ty
| fld
.fold_ty(ty
)),
468 span
: fld
.new_span(span
),
472 pub fn noop_fold_local
<T
: Folder
>(l
: P
<Local
>, fld
: &mut T
) -> P
<Local
> {
473 l
.map(|Local { id, pat, ty, init, span, attrs }
| {
476 ty
: ty
.map(|t
| fld
.fold_ty(t
)),
477 pat
: fld
.fold_pat(pat
),
478 init
: init
.map(|e
| fld
.fold_expr(e
)),
479 span
: fld
.new_span(span
),
480 attrs
: attrs
.map_thin_attrs(|attrs
| fold_attrs(attrs
.into(), fld
).into()),
485 pub fn noop_fold_attribute
<T
: Folder
>(at
: Attribute
, fld
: &mut T
) -> Option
<Attribute
> {
486 let Spanned {node: Attribute_ {id, style, value, is_sugared_doc}
, span
} = at
;
491 value
: fld
.fold_meta_item(value
),
492 is_sugared_doc
: is_sugared_doc
,
494 span
: fld
.new_span(span
),
498 pub fn noop_fold_explicit_self_underscore
<T
: Folder
>(es
: ExplicitSelf_
,
502 SelfStatic
| SelfValue(_
) => es
,
503 SelfRegion(lifetime
, m
, name
) => {
504 SelfRegion(fld
.fold_opt_lifetime(lifetime
), m
, name
)
506 SelfExplicit(typ
, name
) => {
507 SelfExplicit(fld
.fold_ty(typ
), name
)
512 pub fn noop_fold_explicit_self
<T
: Folder
>(Spanned { span, node }
: ExplicitSelf
,
516 node
: fld
.fold_explicit_self_underscore(node
),
517 span
: fld
.new_span(span
),
521 pub fn noop_fold_meta_item
<T
: Folder
>(mi
: P
<MetaItem
>, fld
: &mut T
) -> P
<MetaItem
> {
522 mi
.map(|Spanned { node, span }
| {
525 MetaItemKind
::Word(id
) => MetaItemKind
::Word(id
),
526 MetaItemKind
::List(id
, mis
) => {
527 MetaItemKind
::List(id
, mis
.move_map(|e
| fld
.fold_meta_item(e
)))
529 MetaItemKind
::NameValue(id
, s
) => MetaItemKind
::NameValue(id
, s
),
531 span
: fld
.new_span(span
),
536 pub fn noop_fold_arg
<T
: Folder
>(Arg { id, pat, ty }
: Arg
, fld
: &mut T
) -> Arg
{
539 pat
: fld
.fold_pat(pat
),
544 pub fn noop_fold_fn_decl
<T
: Folder
>(decl
: P
<FnDecl
>, fld
: &mut T
) -> P
<FnDecl
> {
545 decl
.map(|FnDecl { inputs, output, variadic }
| {
547 inputs
: inputs
.move_map(|x
| fld
.fold_arg(x
)),
548 output
: match output
{
549 Return(ty
) => Return(fld
.fold_ty(ty
)),
550 DefaultReturn(span
) => DefaultReturn(span
),
551 NoReturn(span
) => NoReturn(span
),
558 pub fn noop_fold_ty_param_bound
<T
>(tpb
: TyParamBound
, fld
: &mut T
) -> TyParamBound
562 TraitTyParamBound(ty
, modifier
) => TraitTyParamBound(fld
.fold_poly_trait_ref(ty
), modifier
),
563 RegionTyParamBound(lifetime
) => RegionTyParamBound(fld
.fold_lifetime(lifetime
)),
567 pub fn noop_fold_ty_param
<T
: Folder
>(tp
: TyParam
, fld
: &mut T
) -> TyParam
{
568 let TyParam {id, name, bounds, default, span}
= tp
;
572 bounds
: fld
.fold_bounds(bounds
),
573 default: default.map(|x
| fld
.fold_ty(x
)),
578 pub fn noop_fold_ty_params
<T
: Folder
>(tps
: HirVec
<TyParam
>,
581 tps
.move_map(|tp
| fld
.fold_ty_param(tp
))
584 pub fn noop_fold_lifetime
<T
: Folder
>(l
: Lifetime
, fld
: &mut T
) -> Lifetime
{
586 id
: fld
.new_id(l
.id
),
588 span
: fld
.new_span(l
.span
),
592 pub fn noop_fold_lifetime_def
<T
: Folder
>(l
: LifetimeDef
, fld
: &mut T
) -> LifetimeDef
{
594 lifetime
: fld
.fold_lifetime(l
.lifetime
),
595 bounds
: fld
.fold_lifetimes(l
.bounds
),
599 pub fn noop_fold_lifetimes
<T
: Folder
>(lts
: HirVec
<Lifetime
>, fld
: &mut T
) -> HirVec
<Lifetime
> {
600 lts
.move_map(|l
| fld
.fold_lifetime(l
))
603 pub fn noop_fold_lifetime_defs
<T
: Folder
>(lts
: HirVec
<LifetimeDef
>,
605 -> HirVec
<LifetimeDef
> {
606 lts
.move_map(|l
| fld
.fold_lifetime_def(l
))
609 pub fn noop_fold_opt_lifetime
<T
: Folder
>(o_lt
: Option
<Lifetime
>, fld
: &mut T
) -> Option
<Lifetime
> {
610 o_lt
.map(|lt
| fld
.fold_lifetime(lt
))
613 pub fn noop_fold_generics
<T
: Folder
>(Generics { ty_params, lifetimes, where_clause }
: Generics
,
617 ty_params
: fld
.fold_ty_params(ty_params
),
618 lifetimes
: fld
.fold_lifetime_defs(lifetimes
),
619 where_clause
: fld
.fold_where_clause(where_clause
),
623 pub fn noop_fold_where_clause
<T
: Folder
>(WhereClause { id, predicates }
: WhereClause
,
628 predicates
: predicates
.move_map(|predicate
| fld
.fold_where_predicate(predicate
)),
632 pub fn noop_fold_where_predicate
<T
: Folder
>(pred
: WherePredicate
, fld
: &mut T
) -> WherePredicate
{
634 hir
::WherePredicate
::BoundPredicate(hir
::WhereBoundPredicate
{bound_lifetimes
,
638 hir
::WherePredicate
::BoundPredicate(hir
::WhereBoundPredicate
{
639 bound_lifetimes
: fld
.fold_lifetime_defs(bound_lifetimes
),
640 bounded_ty
: fld
.fold_ty(bounded_ty
),
641 bounds
: bounds
.move_map(|x
| fld
.fold_ty_param_bound(x
)),
642 span
: fld
.new_span(span
),
645 hir
::WherePredicate
::RegionPredicate(hir
::WhereRegionPredicate
{lifetime
,
648 hir
::WherePredicate
::RegionPredicate(hir
::WhereRegionPredicate
{
649 span
: fld
.new_span(span
),
650 lifetime
: fld
.fold_lifetime(lifetime
),
651 bounds
: bounds
.move_map(|bound
| fld
.fold_lifetime(bound
)),
654 hir
::WherePredicate
::EqPredicate(hir
::WhereEqPredicate
{id
,
658 hir
::WherePredicate
::EqPredicate(hir
::WhereEqPredicate
{
660 path
: fld
.fold_path(path
),
662 span
: fld
.new_span(span
),
668 pub fn noop_fold_variant_data
<T
: Folder
>(vdata
: VariantData
, fld
: &mut T
) -> VariantData
{
670 VariantData
::Struct(fields
, id
) => {
671 VariantData
::Struct(fields
.move_map(|f
| fld
.fold_struct_field(f
)),
674 VariantData
::Tuple(fields
, id
) => {
675 VariantData
::Tuple(fields
.move_map(|f
| fld
.fold_struct_field(f
)),
678 VariantData
::Unit(id
) => VariantData
::Unit(fld
.new_id(id
)),
682 pub fn noop_fold_trait_ref
<T
: Folder
>(p
: TraitRef
, fld
: &mut T
) -> TraitRef
{
683 let id
= fld
.new_id(p
.ref_id
);
689 path
: fld
.fold_path(path
),
694 pub fn noop_fold_poly_trait_ref
<T
: Folder
>(p
: PolyTraitRef
, fld
: &mut T
) -> PolyTraitRef
{
696 bound_lifetimes
: fld
.fold_lifetime_defs(p
.bound_lifetimes
),
697 trait_ref
: fld
.fold_trait_ref(p
.trait_ref
),
698 span
: fld
.new_span(p
.span
),
702 pub fn noop_fold_struct_field
<T
: Folder
>(f
: StructField
, fld
: &mut T
) -> StructField
{
704 span
: fld
.new_span(f
.span
),
705 id
: fld
.new_id(f
.id
),
708 ty
: fld
.fold_ty(f
.ty
),
709 attrs
: fold_attrs(f
.attrs
, fld
),
713 pub fn noop_fold_field
<T
: Folder
>(Field { name, expr, span }
: Field
, folder
: &mut T
) -> Field
{
715 name
: respan(folder
.new_span(name
.span
), folder
.fold_name(name
.node
)),
716 expr
: folder
.fold_expr(expr
),
717 span
: folder
.new_span(span
),
721 pub fn noop_fold_mt
<T
: Folder
>(MutTy { ty, mutbl }
: MutTy
, folder
: &mut T
) -> MutTy
{
723 ty
: folder
.fold_ty(ty
),
728 pub fn noop_fold_opt_bounds
<T
: Folder
>(b
: Option
<TyParamBounds
>,
730 -> Option
<TyParamBounds
> {
731 b
.map(|bounds
| folder
.fold_bounds(bounds
))
734 fn noop_fold_bounds
<T
: Folder
>(bounds
: TyParamBounds
, folder
: &mut T
) -> TyParamBounds
{
735 bounds
.move_map(|bound
| folder
.fold_ty_param_bound(bound
))
738 pub fn noop_fold_block
<T
: Folder
>(b
: P
<Block
>, folder
: &mut T
) -> P
<Block
> {
739 b
.map(|Block { id, stmts, expr, rules, span }
| {
741 id
: folder
.new_id(id
),
742 stmts
: stmts
.move_map(|s
| folder
.fold_stmt(s
)),
743 expr
: expr
.map(|x
| folder
.fold_expr(x
)),
745 span
: folder
.new_span(span
),
750 pub fn noop_fold_item_underscore
<T
: Folder
>(i
: Item_
, folder
: &mut T
) -> Item_
{
752 ItemExternCrate(string
) => ItemExternCrate(string
),
753 ItemUse(view_path
) => {
754 ItemUse(folder
.fold_view_path(view_path
))
756 ItemStatic(t
, m
, e
) => {
757 ItemStatic(folder
.fold_ty(t
), m
, folder
.fold_expr(e
))
760 ItemConst(folder
.fold_ty(t
), folder
.fold_expr(e
))
762 ItemFn(decl
, unsafety
, constness
, abi
, generics
, body
) => {
763 ItemFn(folder
.fold_fn_decl(decl
),
767 folder
.fold_generics(generics
),
768 folder
.fold_block(body
))
770 ItemMod(m
) => ItemMod(folder
.fold_mod(m
)),
771 ItemForeignMod(nm
) => ItemForeignMod(folder
.fold_foreign_mod(nm
)),
772 ItemTy(t
, generics
) => {
773 ItemTy(folder
.fold_ty(t
), folder
.fold_generics(generics
))
775 ItemEnum(enum_definition
, generics
) => {
776 ItemEnum(hir
::EnumDef
{
777 variants
: enum_definition
.variants
.move_map(|x
| folder
.fold_variant(x
)),
779 folder
.fold_generics(generics
))
781 ItemStruct(struct_def
, generics
) => {
782 let struct_def
= folder
.fold_variant_data(struct_def
);
783 ItemStruct(struct_def
, folder
.fold_generics(generics
))
785 ItemDefaultImpl(unsafety
, ref trait_ref
) => {
786 ItemDefaultImpl(unsafety
, folder
.fold_trait_ref((*trait_ref
).clone()))
788 ItemImpl(unsafety
, polarity
, generics
, ifce
, ty
, impl_items
) => {
789 let new_impl_items
= impl_items
790 .move_map(|item
| folder
.fold_impl_item(item
));
791 let ifce
= match ifce
{
793 Some(ref trait_ref
) => {
794 Some(folder
.fold_trait_ref((*trait_ref
).clone()))
799 folder
.fold_generics(generics
),
804 ItemTrait(unsafety
, generics
, bounds
, items
) => {
805 let bounds
= folder
.fold_bounds(bounds
);
806 let items
= items
.move_map(|item
| folder
.fold_trait_item(item
));
807 ItemTrait(unsafety
, folder
.fold_generics(generics
), bounds
, items
)
812 pub fn noop_fold_trait_item
<T
: Folder
>(i
: TraitItem
,
816 id
: folder
.new_id(i
.id
),
817 name
: folder
.fold_name(i
.name
),
818 attrs
: fold_attrs(i
.attrs
, folder
),
820 ConstTraitItem(ty
, default) => {
821 ConstTraitItem(folder
.fold_ty(ty
), default.map(|x
| folder
.fold_expr(x
)))
823 MethodTraitItem(sig
, body
) => {
824 MethodTraitItem(noop_fold_method_sig(sig
, folder
),
825 body
.map(|x
| folder
.fold_block(x
)))
827 TypeTraitItem(bounds
, default) => {
828 TypeTraitItem(folder
.fold_bounds(bounds
),
829 default.map(|x
| folder
.fold_ty(x
)))
832 span
: folder
.new_span(i
.span
),
836 pub fn noop_fold_impl_item
<T
: Folder
>(i
: ImplItem
, folder
: &mut T
) -> ImplItem
{
838 id
: folder
.new_id(i
.id
),
839 name
: folder
.fold_name(i
.name
),
840 attrs
: fold_attrs(i
.attrs
, folder
),
842 defaultness
: i
.defaultness
,
844 ImplItemKind
::Const(ty
, expr
) => {
845 ImplItemKind
::Const(folder
.fold_ty(ty
), folder
.fold_expr(expr
))
847 ImplItemKind
::Method(sig
, body
) => {
848 ImplItemKind
::Method(noop_fold_method_sig(sig
, folder
), folder
.fold_block(body
))
850 ImplItemKind
::Type(ty
) => ImplItemKind
::Type(folder
.fold_ty(ty
)),
852 span
: folder
.new_span(i
.span
),
856 pub fn noop_fold_mod
<T
: Folder
>(Mod { inner, item_ids }
: Mod
, folder
: &mut T
) -> Mod
{
858 inner
: folder
.new_span(inner
),
859 item_ids
: item_ids
.move_map(|x
| folder
.fold_item_id(x
)),
863 pub fn noop_fold_crate
<T
: Folder
>(Crate
{ module
, attrs
, config
, span
,
864 exported_macros
, items
}: Crate
,
867 let config
= folder
.fold_meta_items(config
);
869 let crate_mod
= folder
.fold_item(hir
::Item
{
870 name
: token
::special_idents
::invalid
.name
,
875 node
: hir
::ItemMod(module
),
878 let (module
, attrs
, span
) = match crate_mod
{
879 hir
::Item { attrs, span, node, .. }
=> {
881 hir
::ItemMod(m
) => (m
, attrs
, span
),
882 _
=> panic
!("fold converted a module to not a module"),
887 let items
= items
.into_iter()
888 .map(|(id
, item
)| (id
, folder
.fold_item(item
)))
896 exported_macros
: exported_macros
,
901 pub fn noop_fold_item_id
<T
: Folder
>(i
: ItemId
, folder
: &mut T
) -> ItemId
{
902 let id
= folder
.map_id(i
.id
);
906 // fold one item into one item
907 pub fn noop_fold_item
<T
: Folder
>(item
: Item
, folder
: &mut T
) -> Item
{
908 let Item { id, name, attrs, node, vis, span }
= item
;
909 let id
= folder
.new_id(id
);
910 let node
= folder
.fold_item_underscore(node
);
914 name
: folder
.fold_name(name
),
915 attrs
: fold_attrs(attrs
, folder
),
918 span
: folder
.new_span(span
),
922 pub fn noop_fold_foreign_item
<T
: Folder
>(ni
: ForeignItem
, folder
: &mut T
) -> ForeignItem
{
924 id
: folder
.new_id(ni
.id
),
925 name
: folder
.fold_name(ni
.name
),
926 attrs
: fold_attrs(ni
.attrs
, folder
),
927 node
: match ni
.node
{
928 ForeignItemFn(fdec
, generics
) => {
929 ForeignItemFn(folder
.fold_fn_decl(fdec
), folder
.fold_generics(generics
))
931 ForeignItemStatic(t
, m
) => {
932 ForeignItemStatic(folder
.fold_ty(t
), m
)
936 span
: folder
.new_span(ni
.span
),
940 pub fn noop_fold_method_sig
<T
: Folder
>(sig
: MethodSig
, folder
: &mut T
) -> MethodSig
{
942 generics
: folder
.fold_generics(sig
.generics
),
944 explicit_self
: folder
.fold_explicit_self(sig
.explicit_self
),
945 unsafety
: sig
.unsafety
,
946 constness
: sig
.constness
,
947 decl
: folder
.fold_fn_decl(sig
.decl
),
951 pub fn noop_fold_pat
<T
: Folder
>(p
: P
<Pat
>, folder
: &mut T
) -> P
<Pat
> {
952 p
.map(|Pat { id, node, span }
| {
954 id
: folder
.new_id(id
),
956 PatKind
::Wild
=> PatKind
::Wild
,
957 PatKind
::Ident(binding_mode
, pth1
, sub
) => {
958 PatKind
::Ident(binding_mode
,
960 span
: folder
.new_span(pth1
.span
),
961 node
: folder
.fold_ident(pth1
.node
),
963 sub
.map(|x
| folder
.fold_pat(x
)))
965 PatKind
::Lit(e
) => PatKind
::Lit(folder
.fold_expr(e
)),
966 PatKind
::TupleStruct(pth
, pats
) => {
967 PatKind
::TupleStruct(folder
.fold_path(pth
),
968 pats
.map(|pats
| pats
.move_map(|x
| folder
.fold_pat(x
))))
970 PatKind
::Path(pth
) => {
971 PatKind
::Path(folder
.fold_path(pth
))
973 PatKind
::QPath(qself
, pth
) => {
974 let qself
= QSelf { ty: folder.fold_ty(qself.ty), ..qself }
;
975 PatKind
::QPath(qself
, folder
.fold_path(pth
))
977 PatKind
::Struct(pth
, fields
, etc
) => {
978 let pth
= folder
.fold_path(pth
);
979 let fs
= fields
.move_map(|f
| {
981 span
: folder
.new_span(f
.span
),
982 node
: hir
::FieldPat
{
984 pat
: folder
.fold_pat(f
.node
.pat
),
985 is_shorthand
: f
.node
.is_shorthand
,
989 PatKind
::Struct(pth
, fs
, etc
)
991 PatKind
::Tup(elts
) => PatKind
::Tup(elts
.move_map(|x
| folder
.fold_pat(x
))),
992 PatKind
::Box(inner
) => PatKind
::Box(folder
.fold_pat(inner
)),
993 PatKind
::Ref(inner
, mutbl
) => PatKind
::Ref(folder
.fold_pat(inner
), mutbl
),
994 PatKind
::Range(e1
, e2
) => {
995 PatKind
::Range(folder
.fold_expr(e1
), folder
.fold_expr(e2
))
997 PatKind
::Vec(before
, slice
, after
) => {
998 PatKind
::Vec(before
.move_map(|x
| folder
.fold_pat(x
)),
999 slice
.map(|x
| folder
.fold_pat(x
)),
1000 after
.move_map(|x
| folder
.fold_pat(x
)))
1003 span
: folder
.new_span(span
),
1008 pub fn noop_fold_expr
<T
: Folder
>(Expr { id, node, span, attrs }
: Expr
, folder
: &mut T
) -> Expr
{
1010 id
: folder
.new_id(id
),
1013 ExprBox(folder
.fold_expr(e
))
1016 ExprVec(exprs
.move_map(|x
| folder
.fold_expr(x
)))
1018 ExprRepeat(expr
, count
) => {
1019 ExprRepeat(folder
.fold_expr(expr
), folder
.fold_expr(count
))
1021 ExprTup(elts
) => ExprTup(elts
.move_map(|x
| folder
.fold_expr(x
))),
1022 ExprCall(f
, args
) => {
1023 ExprCall(folder
.fold_expr(f
), args
.move_map(|x
| folder
.fold_expr(x
)))
1025 ExprMethodCall(name
, tps
, args
) => {
1026 ExprMethodCall(respan(folder
.new_span(name
.span
), folder
.fold_name(name
.node
)),
1027 tps
.move_map(|x
| folder
.fold_ty(x
)),
1028 args
.move_map(|x
| folder
.fold_expr(x
)))
1030 ExprBinary(binop
, lhs
, rhs
) => {
1031 ExprBinary(binop
, folder
.fold_expr(lhs
), folder
.fold_expr(rhs
))
1033 ExprUnary(binop
, ohs
) => {
1034 ExprUnary(binop
, folder
.fold_expr(ohs
))
1036 ExprLit(l
) => ExprLit(l
),
1037 ExprCast(expr
, ty
) => {
1038 ExprCast(folder
.fold_expr(expr
), folder
.fold_ty(ty
))
1040 ExprType(expr
, ty
) => {
1041 ExprType(folder
.fold_expr(expr
), folder
.fold_ty(ty
))
1043 ExprAddrOf(m
, ohs
) => ExprAddrOf(m
, folder
.fold_expr(ohs
)),
1044 ExprIf(cond
, tr
, fl
) => {
1045 ExprIf(folder
.fold_expr(cond
),
1046 folder
.fold_block(tr
),
1047 fl
.map(|x
| folder
.fold_expr(x
)))
1049 ExprWhile(cond
, body
, opt_ident
) => {
1050 ExprWhile(folder
.fold_expr(cond
),
1051 folder
.fold_block(body
),
1052 opt_ident
.map(|i
| folder
.fold_ident(i
)))
1054 ExprLoop(body
, opt_ident
) => {
1055 ExprLoop(folder
.fold_block(body
),
1056 opt_ident
.map(|i
| folder
.fold_ident(i
)))
1058 ExprMatch(expr
, arms
, source
) => {
1059 ExprMatch(folder
.fold_expr(expr
),
1060 arms
.move_map(|x
| folder
.fold_arm(x
)),
1063 ExprClosure(capture_clause
, decl
, body
) => {
1064 ExprClosure(capture_clause
,
1065 folder
.fold_fn_decl(decl
),
1066 folder
.fold_block(body
))
1068 ExprBlock(blk
) => ExprBlock(folder
.fold_block(blk
)),
1069 ExprAssign(el
, er
) => {
1070 ExprAssign(folder
.fold_expr(el
), folder
.fold_expr(er
))
1072 ExprAssignOp(op
, el
, er
) => {
1073 ExprAssignOp(op
, folder
.fold_expr(el
), folder
.fold_expr(er
))
1075 ExprField(el
, name
) => {
1076 ExprField(folder
.fold_expr(el
),
1077 respan(folder
.new_span(name
.span
), folder
.fold_name(name
.node
)))
1079 ExprTupField(el
, index
) => {
1080 ExprTupField(folder
.fold_expr(el
),
1081 respan(folder
.new_span(index
.span
), folder
.fold_usize(index
.node
)))
1083 ExprIndex(el
, er
) => {
1084 ExprIndex(folder
.fold_expr(el
), folder
.fold_expr(er
))
1086 ExprPath(qself
, path
) => {
1087 let qself
= qself
.map(|QSelf { ty, position }
| {
1089 ty
: folder
.fold_ty(ty
),
1093 ExprPath(qself
, folder
.fold_path(path
))
1095 ExprBreak(opt_ident
) => ExprBreak(opt_ident
.map(|label
| {
1096 respan(folder
.new_span(label
.span
), folder
.fold_ident(label
.node
))
1098 ExprAgain(opt_ident
) => ExprAgain(opt_ident
.map(|label
| {
1099 respan(folder
.new_span(label
.span
), folder
.fold_ident(label
.node
))
1101 ExprRet(e
) => ExprRet(e
.map(|x
| folder
.fold_expr(x
))),
1102 ExprInlineAsm(asm
, outputs
, inputs
) => {
1104 outputs
.move_map(|x
| folder
.fold_expr(x
)),
1105 inputs
.move_map(|x
| folder
.fold_expr(x
)))
1107 ExprStruct(path
, fields
, maybe_expr
) => {
1108 ExprStruct(folder
.fold_path(path
),
1109 fields
.move_map(|x
| folder
.fold_field(x
)),
1110 maybe_expr
.map(|x
| folder
.fold_expr(x
)))
1113 span
: folder
.new_span(span
),
1114 attrs
: attrs
.map_thin_attrs(|attrs
| fold_attrs(attrs
.into(), folder
).into()),
1118 pub fn noop_fold_stmt
<T
: Folder
>(stmt
: Stmt
, folder
: &mut T
) -> Stmt
{
1119 let span
= folder
.new_span(stmt
.span
);
1121 StmtDecl(d
, id
) => {
1122 let id
= folder
.new_id(id
);
1124 node
: StmtDecl(folder
.fold_decl(d
), id
),
1128 StmtExpr(e
, id
) => {
1129 let id
= folder
.new_id(id
);
1131 node
: StmtExpr(folder
.fold_expr(e
), id
),
1135 StmtSemi(e
, id
) => {
1136 let id
= folder
.new_id(id
);
1138 node
: StmtSemi(folder
.fold_expr(e
), id
),