Correctly handle Option<T> types in visitor codegen
diff --git a/src/gen/fold.rs b/src/gen/fold.rs
index 326bf4c..6f5e77f 100644
--- a/src/gen/fold.rs
+++ b/src/gen/fold.rs
@@ -32,6 +32,18 @@
}
}
+
+#[cfg(feature = "full")]
+macro_rules! full {
+ ($e:expr) => { $e }
+}
+
+#[cfg(not(feature = "full"))]
+macro_rules! full {
+ ($e:expr) => { unreachable!() }
+}
+
+
/// AST->AST fold.
///
/// Each method of the Folder trait is a hook to be potentially overridden. Each
@@ -448,7 +460,7 @@
attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
pats: FoldHelper::lift(_i . pats, |it| { _visitor.fold_pat(it) }),
if_token: _i . if_token,
- guard: _i . guard,
+ guard: (_i . guard).map(|it| { Box::new(_visitor.fold_expr(* it)) }),
rocket_token: _i . rocket_token,
body: Box::new(_visitor.fold_expr(* _i . body)),
comma: _i . comma,
@@ -503,9 +515,9 @@
pub fn walk_bare_fn_ty<V: Folder + ?Sized>(_visitor: &mut V, _i: BareFnTy) -> BareFnTy {
BareFnTy {
- lifetimes: _i . lifetimes,
+ lifetimes: (_i . lifetimes).map(|it| { _visitor.fold_bound_lifetimes(it) }),
unsafety: _visitor.fold_unsafety(_i . unsafety),
- abi: _i . abi,
+ abi: (_i . abi).map(|it| { _visitor.fold_abi(it) }),
fn_token: _i . fn_token,
paren_token: _i . paren_token,
inputs: FoldHelper::lift(_i . inputs, |it| { _visitor.fold_bare_fn_arg(it) }),
@@ -834,7 +846,7 @@
pub fn walk_expr_break<V: Folder + ?Sized>(_visitor: &mut V, _i: ExprBreak) -> ExprBreak {
ExprBreak {
label: _i . label,
- expr: _i . expr,
+ expr: (_i . expr).map(|it| { Box::new(_visitor.fold_expr(* it)) }),
break_token: _i . break_token,
}
}
@@ -911,7 +923,7 @@
ExprIf {
cond: Box::new(_visitor.fold_expr(* _i . cond)),
if_true: _visitor.fold_block(_i . if_true),
- if_false: _i . if_false,
+ if_false: (_i . if_false).map(|it| { Box::new(_visitor.fold_expr(* it)) }),
if_token: _i . if_token,
else_token: _i . else_token,
}
@@ -922,7 +934,7 @@
pat: Box::new(_visitor.fold_pat(* _i . pat)),
expr: Box::new(_visitor.fold_expr(* _i . expr)),
if_true: _visitor.fold_block(_i . if_true),
- if_false: _i . if_false,
+ if_false: (_i . if_false).map(|it| { Box::new(_visitor.fold_expr(* it)) }),
if_token: _i . if_token,
let_token: _i . let_token,
eq_token: _i . eq_token,
@@ -951,17 +963,17 @@
match _i {
Box(_binding_0, ) => {
Box (
- { #[cfg(feature = "full")] { _visitor.fold_expr_box(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_box(_binding_0)),
)
}
InPlace(_binding_0, ) => {
InPlace (
- { #[cfg(feature = "full")] { _visitor.fold_expr_in_place(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_in_place(_binding_0)),
)
}
Array(_binding_0, ) => {
Array (
- { #[cfg(feature = "full")] { _visitor.fold_expr_array(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_array(_binding_0)),
)
}
Call(_binding_0, ) => {
@@ -971,12 +983,12 @@
}
MethodCall(_binding_0, ) => {
MethodCall (
- { #[cfg(feature = "full")] { _visitor.fold_expr_method_call(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_method_call(_binding_0)),
)
}
Tup(_binding_0, ) => {
Tup (
- { #[cfg(feature = "full")] { _visitor.fold_expr_tup(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_tup(_binding_0)),
)
}
Binary(_binding_0, ) => {
@@ -1006,67 +1018,67 @@
}
If(_binding_0, ) => {
If (
- { #[cfg(feature = "full")] { _visitor.fold_expr_if(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_if(_binding_0)),
)
}
IfLet(_binding_0, ) => {
IfLet (
- { #[cfg(feature = "full")] { _visitor.fold_expr_if_let(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_if_let(_binding_0)),
)
}
While(_binding_0, ) => {
While (
- { #[cfg(feature = "full")] { _visitor.fold_expr_while(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_while(_binding_0)),
)
}
WhileLet(_binding_0, ) => {
WhileLet (
- { #[cfg(feature = "full")] { _visitor.fold_expr_while_let(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_while_let(_binding_0)),
)
}
ForLoop(_binding_0, ) => {
ForLoop (
- { #[cfg(feature = "full")] { _visitor.fold_expr_for_loop(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_for_loop(_binding_0)),
)
}
Loop(_binding_0, ) => {
Loop (
- { #[cfg(feature = "full")] { _visitor.fold_expr_loop(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_loop(_binding_0)),
)
}
Match(_binding_0, ) => {
Match (
- { #[cfg(feature = "full")] { _visitor.fold_expr_match(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_match(_binding_0)),
)
}
Closure(_binding_0, ) => {
Closure (
- { #[cfg(feature = "full")] { _visitor.fold_expr_closure(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_closure(_binding_0)),
)
}
Block(_binding_0, ) => {
Block (
- { #[cfg(feature = "full")] { _visitor.fold_expr_block(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_block(_binding_0)),
)
}
Assign(_binding_0, ) => {
Assign (
- { #[cfg(feature = "full")] { _visitor.fold_expr_assign(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_assign(_binding_0)),
)
}
AssignOp(_binding_0, ) => {
AssignOp (
- { #[cfg(feature = "full")] { _visitor.fold_expr_assign_op(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_assign_op(_binding_0)),
)
}
Field(_binding_0, ) => {
Field (
- { #[cfg(feature = "full")] { _visitor.fold_expr_field(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_field(_binding_0)),
)
}
TupField(_binding_0, ) => {
TupField (
- { #[cfg(feature = "full")] { _visitor.fold_expr_tup_field(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_tup_field(_binding_0)),
)
}
Index(_binding_0, ) => {
@@ -1076,7 +1088,7 @@
}
Range(_binding_0, ) => {
Range (
- { #[cfg(feature = "full")] { _visitor.fold_expr_range(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_range(_binding_0)),
)
}
Path(_binding_0, ) => {
@@ -1086,22 +1098,22 @@
}
AddrOf(_binding_0, ) => {
AddrOf (
- { #[cfg(feature = "full")] { _visitor.fold_expr_addr_of(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_addr_of(_binding_0)),
)
}
Break(_binding_0, ) => {
Break (
- { #[cfg(feature = "full")] { _visitor.fold_expr_break(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_break(_binding_0)),
)
}
Continue(_binding_0, ) => {
Continue (
- { #[cfg(feature = "full")] { _visitor.fold_expr_continue(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_continue(_binding_0)),
)
}
Ret(_binding_0, ) => {
Ret (
- { #[cfg(feature = "full")] { _visitor.fold_expr_ret(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_ret(_binding_0)),
)
}
Mac(_binding_0, ) => {
@@ -1111,12 +1123,12 @@
}
Struct(_binding_0, ) => {
Struct (
- { #[cfg(feature = "full")] { _visitor.fold_expr_struct(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_struct(_binding_0)),
)
}
Repeat(_binding_0, ) => {
Repeat (
- { #[cfg(feature = "full")] { _visitor.fold_expr_repeat(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_repeat(_binding_0)),
)
}
Paren(_binding_0, ) => {
@@ -1131,17 +1143,17 @@
}
Try(_binding_0, ) => {
Try (
- { #[cfg(feature = "full")] { _visitor.fold_expr_try(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_try(_binding_0)),
)
}
Catch(_binding_0, ) => {
Catch (
- { #[cfg(feature = "full")] { _visitor.fold_expr_catch(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_catch(_binding_0)),
)
}
Yield(_binding_0, ) => {
Yield (
- { #[cfg(feature = "full")] { _visitor.fold_expr_yield(_binding_0) } #[cfg(not(feature = "full"))] unreachable!() },
+ full!(_visitor.fold_expr_yield(_binding_0)),
)
}
}
@@ -1188,15 +1200,15 @@
pub fn walk_expr_path<V: Folder + ?Sized>(_visitor: &mut V, _i: ExprPath) -> ExprPath {
ExprPath {
- qself: _i . qself,
+ qself: (_i . qself).map(|it| { _visitor.fold_qself(it) }),
path: _visitor.fold_path(_i . path),
}
}
# [ cfg ( feature = "full" ) ]
pub fn walk_expr_range<V: Folder + ?Sized>(_visitor: &mut V, _i: ExprRange) -> ExprRange {
ExprRange {
- from: _i . from,
- to: _i . to,
+ from: (_i . from).map(|it| { Box::new(_visitor.fold_expr(* it)) }),
+ to: (_i . to).map(|it| { Box::new(_visitor.fold_expr(* it)) }),
limits: _visitor.fold_range_limits(_i . limits),
}
}
@@ -1212,7 +1224,7 @@
# [ cfg ( feature = "full" ) ]
pub fn walk_expr_ret<V: Folder + ?Sized>(_visitor: &mut V, _i: ExprRet) -> ExprRet {
ExprRet {
- expr: _i . expr,
+ expr: (_i . expr).map(|it| { Box::new(_visitor.fold_expr(* it)) }),
return_token: _i . return_token,
}
}
@@ -1221,7 +1233,7 @@
ExprStruct {
path: _visitor.fold_path(_i . path),
fields: FoldHelper::lift(_i . fields, |it| { _visitor.fold_field_value(it) }),
- rest: _i . rest,
+ rest: (_i . rest).map(|it| { Box::new(_visitor.fold_expr(* it)) }),
dot2_token: _i . dot2_token,
brace_token: _i . brace_token,
}
@@ -1291,7 +1303,7 @@
pub fn walk_expr_yield<V: Folder + ?Sized>(_visitor: &mut V, _i: ExprYield) -> ExprYield {
ExprYield {
yield_token: _i . yield_token,
- expr: _i . expr,
+ expr: (_i . expr).map(|it| { Box::new(_visitor.fold_expr(* it)) }),
}
}
@@ -1589,7 +1601,7 @@
vis: _visitor.fold_visibility(_i . vis),
constness: _visitor.fold_constness(_i . constness),
unsafety: _visitor.fold_unsafety(_i . unsafety),
- abi: _i . abi,
+ abi: (_i . abi).map(|it| { _visitor.fold_abi(it) }),
decl: Box::new(_visitor.fold_fn_decl(* _i . decl)),
ident: _i . ident,
block: Box::new(_visitor.fold_block(* _i . block)),
@@ -1794,8 +1806,8 @@
eq_token: _i . eq_token,
semi_token: _i . semi_token,
pat: Box::new(_visitor.fold_pat(* _i . pat)),
- ty: _i . ty,
- init: _i . init,
+ ty: (_i . ty).map(|it| { Box::new(_visitor.fold_ty(* it)) }),
+ init: (_i . init).map(|it| { Box::new(_visitor.fold_expr(* it)) }),
attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
}
}
@@ -1863,7 +1875,7 @@
MethodSig {
constness: _visitor.fold_constness(_i . constness),
unsafety: _visitor.fold_unsafety(_i . unsafety),
- abi: _i . abi,
+ abi: (_i . abi).map(|it| { _visitor.fold_abi(it) }),
ident: _i . ident,
decl: _visitor.fold_fn_decl(_i . decl),
}
@@ -1989,7 +2001,7 @@
PatIdent {
mode: _visitor.fold_binding_mode(_i . mode),
ident: _i . ident,
- subpat: _i . subpat,
+ subpat: (_i . subpat).map(|it| { Box::new(_visitor.fold_pat(* it)) }),
at_token: _i . at_token,
}
}
@@ -2002,7 +2014,7 @@
# [ cfg ( feature = "full" ) ]
pub fn walk_pat_path<V: Folder + ?Sized>(_visitor: &mut V, _i: PatPath) -> PatPath {
PatPath {
- qself: _i . qself,
+ qself: (_i . qself).map(|it| { _visitor.fold_qself(it) }),
path: _visitor.fold_path(_i . path),
}
}
@@ -2026,7 +2038,7 @@
pub fn walk_pat_slice<V: Folder + ?Sized>(_visitor: &mut V, _i: PatSlice) -> PatSlice {
PatSlice {
front: FoldHelper::lift(_i . front, |it| { _visitor.fold_pat(it) }),
- middle: _i . middle,
+ middle: (_i . middle).map(|it| { Box::new(_visitor.fold_pat(* it)) }),
back: FoldHelper::lift(_i . back, |it| { _visitor.fold_pat(it) }),
dot2_token: _i . dot2_token,
comma_token: _i . comma_token,
@@ -2132,7 +2144,7 @@
pub fn walk_poly_trait_ref<V: Folder + ?Sized>(_visitor: &mut V, _i: PolyTraitRef) -> PolyTraitRef {
PolyTraitRef {
- bound_lifetimes: _i . bound_lifetimes,
+ bound_lifetimes: (_i . bound_lifetimes).map(|it| { _visitor.fold_bound_lifetimes(it) }),
trait_ref: _visitor.fold_path(_i . trait_ref),
}
}
@@ -2254,7 +2266,7 @@
pub fn walk_trait_item_method<V: Folder + ?Sized>(_visitor: &mut V, _i: TraitItemMethod) -> TraitItemMethod {
TraitItemMethod {
sig: _visitor.fold_method_sig(_i . sig),
- default: _i . default,
+ default: (_i . default).map(|it| { _visitor.fold_block(it) }),
semi_token: _i . semi_token,
}
}
@@ -2394,7 +2406,7 @@
colon_token: _i . colon_token,
bounds: FoldHelper::lift(_i . bounds, |it| { _visitor.fold_ty_param_bound(it) }),
eq_token: _i . eq_token,
- default: _i . default,
+ default: (_i . default).map(|it| { _visitor.fold_ty(it) }),
}
}
@@ -2424,7 +2436,7 @@
pub fn walk_ty_path<V: Folder + ?Sized>(_visitor: &mut V, _i: TyPath) -> TyPath {
TyPath {
- qself: _i . qself,
+ qself: (_i . qself).map(|it| { _visitor.fold_qself(it) }),
path: _visitor.fold_path(_i . path),
}
}
@@ -2512,7 +2524,7 @@
ident: _i . ident,
attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
data: _visitor.fold_variant_data(_i . data),
- discriminant: _i . discriminant,
+ discriminant: (_i . discriminant).map(|it| { _visitor.fold_expr(it) }),
eq_token: _i . eq_token,
}
}
@@ -2613,7 +2625,7 @@
pub fn walk_where_bound_predicate<V: Folder + ?Sized>(_visitor: &mut V, _i: WhereBoundPredicate) -> WhereBoundPredicate {
WhereBoundPredicate {
- bound_lifetimes: _i . bound_lifetimes,
+ bound_lifetimes: (_i . bound_lifetimes).map(|it| { _visitor.fold_bound_lifetimes(it) }),
bounded_ty: _visitor.fold_ty(_i . bounded_ty),
colon_token: _i . colon_token,
bounds: FoldHelper::lift(_i . bounds, |it| { _visitor.fold_ty_param_bound(it) }),