diff options
| -rw-r--r-- | src/boot/be/x86.ml | 5 | ||||
| -rw-r--r-- | src/boot/driver/lib.ml | 4 | ||||
| -rw-r--r-- | src/boot/driver/main.ml | 6 | ||||
| -rw-r--r-- | src/boot/fe/cexp.ml | 2 | ||||
| -rw-r--r-- | src/boot/fe/item.ml | 1 | ||||
| -rw-r--r-- | src/boot/fe/parser.ml | 2 | ||||
| -rw-r--r-- | src/boot/me/dwarf.ml | 14 | ||||
| -rw-r--r-- | src/boot/me/effect.ml | 4 | ||||
| -rw-r--r-- | src/boot/me/resolve.ml | 40 | ||||
| -rw-r--r-- | src/boot/me/semant.ml | 24 | ||||
| -rw-r--r-- | src/boot/me/trans.ml | 94 | ||||
| -rw-r--r-- | src/boot/me/type.ml | 18 | ||||
| -rw-r--r-- | src/boot/me/typestate.ml | 2 | ||||
| -rw-r--r-- | src/boot/me/walk.ml | 14 |
14 files changed, 117 insertions, 113 deletions
diff --git a/src/boot/be/x86.ml b/src/boot/be/x86.ml index 267dc657..182096ed 100644 --- a/src/boot/be/x86.ml +++ b/src/boot/be/x86.ml @@ -1245,8 +1245,9 @@ let fn_prologue sub (rc esp) dynamic_frame_sz; (* Zero the frame. - * - * FIXME: this is awful, will go away when we have proper CFI. + * + * FIXME (ssue 27): this is awful, will go away when we have proper + * CFI. *) mov (rc edi) (ro esp); diff --git a/src/boot/driver/lib.ml b/src/boot/driver/lib.ml index e0391c65..764fd688 100644 --- a/src/boot/driver/lib.ml +++ b/src/boot/driver/lib.ml @@ -12,7 +12,7 @@ let iflog (sess:Session.sess) (thunk:(unit -> unit)) : unit = else () ;; -(* FIXME: move these to sess. *) +(* FIXME (issue #67): move these to sess. *) let ar_cache = Hashtbl.create 0 ;; let sects_cache = Hashtbl.create 0;; let meta_cache = Hashtbl.create 0;; @@ -138,7 +138,7 @@ let get_mod then true else match meta.(i) with - (* FIXME: bind the wildcards. *) + (* FIXME (issue #68): bind the wildcards. *) (_, None) -> meta_matches (i+1) f_meta | (k, Some v) -> match atab_search f_meta k with diff --git a/src/boot/driver/main.ml b/src/boot/driver/main.ml index 18416590..61d419e7 100644 --- a/src/boot/driver/main.ml +++ b/src/boot/driver/main.ml @@ -9,7 +9,7 @@ let _ = let (targ:Common.target) = match Sys.os_type with "Unix" -> - (* FIXME: this is an absurd heuristic. *) + (* FIXME (issue #69): this is an absurd heuristic. *) if Sys.file_exists "/System/Library" then MacOS_x86_macho else Linux_x86_elf @@ -26,7 +26,9 @@ let (sess:Session.sess) = Session.sess_out = None; Session.sess_library_mode = false; Session.sess_alt_backend = false; - (* FIXME: need something fancier here for unix sub-flavours. *) + (* FIXME (issue #69): need something fancier here for unix + * sub-flavours. + *) Session.sess_targ = targ; Session.sess_log_lex = false; Session.sess_log_parse = false; diff --git a/src/boot/fe/cexp.ml b/src/boot/fe/cexp.ml index 6dffdb96..bf5e32b8 100644 --- a/src/boot/fe/cexp.ml +++ b/src/boot/fe/cexp.ml @@ -325,7 +325,7 @@ let unexpected_val (expected:string) (v:pval) = | PVAL_num i -> "num " ^ (Int64.to_string i) | PVAL_bool b -> if b then "bool true" else "bool false" in - (* FIXME: proper error reporting, please. *) + (* FIXME (issue #70): proper error reporting, please. *) bug () "expected %s, got %s" expected got ;; diff --git a/src/boot/fe/item.ml b/src/boot/fe/item.ml index a2763d96..3efd4e2a 100644 --- a/src/boot/fe/item.ml +++ b/src/boot/fe/item.ml @@ -960,7 +960,6 @@ and parse_mod_item_from_signature (ps:pstate) let bpos = lexpos ps in (ident, span ps apos bpos (decl params (Ast.MOD_ITEM_type t))) - (* FIXME: parse obj. *) | _ -> raise (unexpected ps) diff --git a/src/boot/fe/parser.ml b/src/boot/fe/parser.ml index 3dda93ac..5df44303 100644 --- a/src/boot/fe/parser.ml +++ b/src/boot/fe/parser.ml @@ -209,7 +209,7 @@ let build_tmp (* Simple helpers *) -(* FIXME: please rename these, they make eyes bleed. *) +(* FIXME (issue #71): please rename these, they make eyes bleed. *) let arr (ls:'a list) : 'a array = Array.of_list ls ;; let arl (ls:'a list) : 'a array = Array.of_list (List.rev ls) ;; diff --git a/src/boot/me/dwarf.ml b/src/boot/me/dwarf.ml index 910ef983..b7fdf309 100644 --- a/src/boot/me/dwarf.ml +++ b/src/boot/me/dwarf.ml @@ -1356,7 +1356,6 @@ let (abbrev_variant:abbrev) = let (abbrev_subroutine_type:abbrev) = (DW_TAG_subroutine_type, DW_CHILDREN_yes, [| - (* FIXME: model effects properly. *) (DW_AT_type, DW_FORM_ref_addr); (* NB: output type. *) (DW_AT_mutable, DW_FORM_flag); (DW_AT_pure, DW_FORM_flag); @@ -1375,7 +1374,6 @@ let (abbrev_formal_type:abbrev) = let (abbrev_obj_subroutine_type:abbrev) = (DW_TAG_subroutine_type, DW_CHILDREN_yes, [| - (* FIXME: model effects properly. *) (DW_AT_name, DW_FORM_string); (DW_AT_type, DW_FORM_ref_addr); (* NB: output type. *) (DW_AT_mutable, DW_FORM_flag); @@ -1568,7 +1566,7 @@ let dwarf_visitor |])); ref_addr_for_fix fix - (* FIXME: encode mutable-ness of interiors. *) + (* FIXME (issue #72): encode mutable-ness of interiors. *) | Ast.MODE_interior -> ref_type_die (slot_ty slot) | Ast.MODE_alias -> @@ -2473,7 +2471,9 @@ let dwarf_visitor Some off -> begin match Il.size_to_expr64 off with - (* FIXME: handle dynamic-size slots. *) + (* FIXME (issue #73): handle dynamic-size + * slots. + *) None -> () | Some off -> emit_var_die @@ -3001,7 +3001,9 @@ let rec extract_mod_items Ast.slot_ty = Some ty } | _ -> let ty = get_ty die in - (* FIXME: encode mutability of interior slots properly. *) + (* FIXME (issue #28): encode mutability of interior slots + * properly. + *) { Ast.slot_mode = Ast.MODE_interior; Ast.slot_mutable = false; Ast.slot_ty = Some ty } @@ -3114,7 +3116,7 @@ let rec extract_mod_items htab_put mis ident (decl [||] mi) | DW_TAG_subprogram -> - (* FIXME: finish this. *) + (* FIXME (issue #74): finish this. *) let ident = get_name die in let oslot = get_referenced_slot die in let effect = get_effect die in diff --git a/src/boot/me/effect.ml b/src/boot/me/effect.ml index 289976a0..ad9a4cb3 100644 --- a/src/boot/me/effect.ml +++ b/src/boot/me/effect.ml @@ -40,7 +40,9 @@ let mutability_checking_visitor then () else err (Some id) "writing to non-mutable slot" in - (* FIXME: enforce the no-write-alias-to-immutable-slot rule. *) + (* FIXME (issue #75): enforce the no-write-alias-to-immutable-slot + * rule. + *) let visit_stmt_pre s = begin match s.node with diff --git a/src/boot/me/resolve.ml b/src/boot/me/resolve.ml index c0146c97..489655f3 100644 --- a/src/boot/me/resolve.ml +++ b/src/boot/me/resolve.ml @@ -170,7 +170,6 @@ let all_item_collecting_visitor htab_put cx.ctxt_all_item_names i.id (Walk.path_to_name path); log cx "collected item #%d: %s" (int_of_node i.id) n; begin - (* FIXME: this is incomplete. *) match i.node.Ast.decl_item with Ast.MOD_ITEM_fn f -> note_header i.id f.Ast.fn_input_slots; @@ -345,8 +344,6 @@ let rec ty_iso_of let group_table = Hashtbl.find recursive_tag_groups n in let group_array = Array.of_list (htab_keys group_table) in let compare_nodes a_id b_id = - (* FIXME: this should sort by the sorted name-lists of the - *constructors* of the tag, not the tag type name. *) let a_name = Hashtbl.find cx.ctxt_all_item_names a_id in let b_name = Hashtbl.find cx.ctxt_all_item_names b_id in compare a_name b_name @@ -935,11 +932,11 @@ let pattern_resolving_visitor let lval_id = lval_base_id lval in let tag_ctor_id = lval_to_referent cx lval_id in if referent_is_item cx tag_ctor_id - (* - * FIXME we should actually check here that the function - * is a tag value-ctor. For now this actually allows any - * function returning a tag type to pass as a tag pattern. - *) + + (* FIXME (issue #76): we should actually check here that the + * function is a tag value-ctor. For now this actually allows + * any function returning a tag type to pass as a tag + * pattern. *) then resolve_pat_tag lval_nm lval_id pats tag_ctor_id else not_tag_ctor lval_nm lval_id | _ -> () @@ -948,28 +945,29 @@ let pattern_resolving_visitor let visit_stmt_pre stmt = begin match stmt.node with - Ast.STMT_alt_tag { Ast.alt_tag_lval = _; Ast.alt_tag_arms = arms } -> - Array.iter resolve_arm arms - | _ -> () + Ast.STMT_alt_tag { Ast.alt_tag_lval = _; + Ast.alt_tag_arms = arms } -> + Array.iter resolve_arm arms + | _ -> () end; inner.Walk.visit_stmt_pre stmt in - { inner with Walk.visit_stmt_pre = visit_stmt_pre } + { inner with Walk.visit_stmt_pre = visit_stmt_pre } ;; let export_referencing_visitor (cx:ctxt) (inner:Walk.visitor) : Walk.visitor = - let visit_mod_item_pre id params item = - begin - match item.node.Ast.decl_item with - Ast.MOD_ITEM_mod (view, items) -> - let is_defining_mod = - (* auto-ref the default-export cases only if - * the containing mod is 'defining', meaning - * not-native / not-use - *) + let visit_mod_item_pre id params item = + begin + match item.node.Ast.decl_item with + Ast.MOD_ITEM_mod (view, items) -> + let is_defining_mod = + (* auto-ref the default-export cases only if + * the containing mod is 'defining', meaning + * not-native / not-use + *) not (Hashtbl.mem cx.ctxt_required_items item.id) in let reference _ item = diff --git a/src/boot/me/semant.ml b/src/boot/me/semant.ml index 40dd33bf..3868d6f0 100644 --- a/src/boot/me/semant.ml +++ b/src/boot/me/semant.ml @@ -874,13 +874,10 @@ let rebuild_ty_under_params } in let t' = fold_ty fold t in - (* - * FIXME: "substituted" and "ty'" here are only required - * because the current type-equality-comparison code in Type - * uses <> and will judge some cases, such as rebuilt tags, as - * unequal simply due to the different hashtable order in the - * fold. - *) + (* FIXME (issue #77): "substituted" and "ty'" here are only required + * because the current type-equality-comparison code in Type uses <> + * and will judge some cases, such as rebuilt tags, as unequal simply + * due to the different hashtable order in the fold. *) if !substituted then t' else t @@ -2080,7 +2077,7 @@ let ty_str (ty:Ast.ty) : string = ty_fold_vec = (fun s -> "v" ^ s); ty_fold_iso = fold_iso; ty_fold_idx = (fun i -> "x" ^ (string_of_int i)); - (* FIXME: encode constrs, aux as well. *) + (* FIXME (issue #78): encode constrs, aux as well. *) ty_fold_fn = (fun ((ins,_,out),_) -> "f" ^ ins ^ out); (* Built-in special types. *) @@ -2092,10 +2089,10 @@ let ty_str (ty:Ast.ty) : string = ty_fold_param = (fun _ -> "P"); ty_fold_type = (fun _ -> "Y"); - (* FIXME: encode obj types. *) - (* FIXME: encode opaque and param numbers. *) + (* FIXME (issue #78): encode obj types. *) + (* FIXME (issue #78): encode opaque and param numbers. *) ty_fold_named = (fun _ -> bug () "string-encoding named type"); - (* FIXME: encode constrs as well. *) + (* FIXME (issue #78): encode constrs as well. *) ty_fold_constrained = (fun (t,_)-> t) } in fold_ty fold ty @@ -2124,8 +2121,9 @@ let glue_str (cx:ctxt) (g:glue) : string = | GLUE_drop_frame i -> "glue$drop_frame$" ^ (item_str cx i) | GLUE_reloc_frame i -> "glue$reloc_frame$" ^ (item_str cx i) (* - * FIXME: the node_id here isn't an item, it's a statement; - * lookup bind target and encode bound arg tuple type. + * FIXME (issue #78): the node_id here isn't an item, it's + * a statement; lookup bind target and encode bound arg + * tuple type. *) | GLUE_fn_binding i -> "glue$fn_binding$" ^ (string_of_int (int_of_node i)) diff --git a/src/boot/me/trans.ml b/src/boot/me/trans.ml index 4b7c5b17..584c2e79 100644 --- a/src/boot/me/trans.ml +++ b/src/boot/me/trans.ml @@ -832,13 +832,14 @@ let trans_visitor then bug () "unsupported nested for each loop"; for i = 2 to diff do - (* FIXME: access outer caller-block fps, - * given nearest caller-block fp. + (* FIXME (issue #79): access outer + * caller-block fps, given nearest + * caller-block fp. *) let _ = annotate "step to outer-outer frame" in - mov fp (Il.Cell fp) + mov fp (Il.Cell fp) done; let _ = annotate "calculate size" in let p = @@ -1179,7 +1180,7 @@ let trans_visitor trans_copy_forward_args self_args_rty; iflog (fun _ -> annotate "call through to callee"); - (* FIXME: use a tail-call here. *) + (* FIXME (issue #80): use a tail-call here. *) call_code (code_of_cell callee_fn_cell); trans_glue_frame_exit fix spill g; fix @@ -1419,7 +1420,7 @@ let trans_visitor let (callee_ty:Ast.ty) = mk_simple_ty_fn arg_slots in let self_closure_rty = closure_referent_type bound_slots in - (* FIXME: binding type parameters doesn't work. *) + (* FIXME (issue #81): binding type parameters doesn't work. *) let self_args_rty = call_args_referent_type cx 0 self_ty (Some self_closure_rty) in @@ -2009,7 +2010,7 @@ let trans_visitor let (fptr_operand, fn_ty) = trans_callee fn_lval in (*let fn_ty_params = [| |] in*) let _ = - (* FIXME: handle indirect-spawns (clone closure). *) + (* FIXME (issue #82): handle indirect-spawns (clone closure). *) if not (lval_is_direct_fn cx fn_lval) then bug () "unhandled indirect-spawn" in @@ -2214,7 +2215,9 @@ let trans_visitor let descs_ptr = next_vreg_cell Il.voidptr_t in if (Array.length descs) > 0 then - (* FIXME: this relies on knowledge that spills are contiguous. *) + (* FIXME (issue #83): this relies on knowledge that spills are + * contiguous. + *) let spills = Array.map (fun _ -> next_spill_cell Il.voidptr_t) descs in @@ -2229,7 +2232,7 @@ let trans_visitor td and get_tydesc (idopt:node_id option) (ty:Ast.ty) : Il.cell = - log cx "getting tydesc for %a" Ast.sprintf_ty ty; + log cx "getting tydesc for %a" Ast.sprintf_ty ty; match ty with Ast.TY_param (idx, _) -> (get_ty_param_in_current_frame idx) @@ -2243,7 +2246,7 @@ let trans_visitor and exterior_ctrl_cell (cell:Il.cell) (off:int) : Il.cell = let (mem, _) = need_mem_cell (deref_imm cell (word_n off)) in - word_at mem + word_at mem and exterior_rc_cell (cell:Il.cell) : Il.cell = exterior_ctrl_cell cell Abi.exterior_rc_slot_field_refcnt @@ -2294,31 +2297,31 @@ let trans_visitor (curr_iso:Ast.ty_iso option) : unit = let tag_keys = sorted_htab_keys ttag in - let src_tag = get_element_ptr src_cell 0 in - let dst_tag = get_element_ptr dst_cell 0 in - let src_union = get_element_ptr_dyn ty_params src_cell 1 in - let dst_union = get_element_ptr_dyn ty_params dst_cell 1 in - let tmp = next_vreg_cell word_ty in - f dst_tag src_tag word_slot curr_iso; - mov tmp (Il.Cell src_tag); - Array.iteri - begin - fun i key -> - (iflog (fun _ -> - annotate (Printf.sprintf "tag case #%i == %a" i - Ast.sprintf_name key))); - let jmps = - trans_compare Il.JNE (Il.Cell tmp) (imm (Int64.of_int i)) - in - let ttup = Hashtbl.find ttag key in - iter_tup_slots - (get_element_ptr_dyn ty_params) - (get_variant_ptr dst_union i) - (get_variant_ptr src_union i) - ttup f curr_iso; - List.iter patch jmps - end - tag_keys + let src_tag = get_element_ptr src_cell 0 in + let dst_tag = get_element_ptr dst_cell 0 in + let src_union = get_element_ptr_dyn ty_params src_cell 1 in + let dst_union = get_element_ptr_dyn ty_params dst_cell 1 in + let tmp = next_vreg_cell word_ty in + f dst_tag src_tag word_slot curr_iso; + mov tmp (Il.Cell src_tag); + Array.iteri + begin + fun i key -> + (iflog (fun _ -> + annotate (Printf.sprintf "tag case #%i == %a" i + Ast.sprintf_name key))); + let jmps = + trans_compare Il.JNE (Il.Cell tmp) (imm (Int64.of_int i)) + in + let ttup = Hashtbl.find ttag key in + iter_tup_slots + (get_element_ptr_dyn ty_params) + (get_variant_ptr dst_union i) + (get_variant_ptr src_union i) + ttup f curr_iso; + List.iter patch jmps + end + tag_keys and get_iso_tag tiso = tiso.Ast.iso_group.(tiso.Ast.iso_index) @@ -3129,14 +3132,13 @@ let trans_visitor let src_cell = need_cell (trans_atom a) in let src_slot = interior_slot src_ty in - (* FIXME: this is wrong. It treats the underlying obj-state - * as the same as the callee and simply substitutes the - * forwarding vtbl, which would be great if it had any way + (* FIXME (issue #84): this is wrong. It treats the underlying + * obj-state as the same as the callee and simply substitutes + * the forwarding vtbl, which would be great if it had any way * convey the callee vtbl to the forwarding functions. But it * doesn't. Instead, we have to malloc a fresh 3-word * refcounted obj to hold the callee's vtbl+state pair, copy - * that in as the state here. - *) + * that in as the state here. *) let _ = trans_copy_slot (get_ty_params_of_current_frame()) initializing @@ -3260,10 +3262,8 @@ let trans_visitor then match clone with CLONE_none -> - (* - * FIXME: this won't work on mutable aliases, it - * doesn't know to reload. Try something - * else. + (* Aliasing a literal is a bit weird since nobody + * else will ever see it, but it seems harmless. *) mov dst (Il.Cell (alias (Il.Mem (force_to_mem src)))) | _ -> @@ -3326,7 +3326,7 @@ let trans_visitor call_iterator_args = call_iterator_args None; call_indirect_args = call_indirect_args flv cc } in - (* FIXME: true if caller is object fn *) + (* FIXME (issue #85): true if caller is object fn *) let caller_is_closure = false in log cx "trans_be_fn: %s call to lval %a" (call_ctrl_string cc) Ast.sprintf_lval flv; @@ -3796,9 +3796,9 @@ let trans_visitor | CALL_vtbl -> begin match flv with - (* - * FIXME: will need to pass both words of obj if we add - * a 'self' value for self-dispatch within objs. + (* FIXME (issue #84): will need to pass both words of obj + * if we add a 'self' value for self-dispatch within + * objs. Also to support forwarding-functions / 'as'. *) Ast.LVAL_ext (base, _) -> [| callee_binding_ptr base cc |] | _ -> diff --git a/src/boot/me/type.ml b/src/boot/me/type.ml index 01438142..4e0e6ea9 100644 --- a/src/boot/me/type.ml +++ b/src/boot/me/type.ml @@ -859,9 +859,8 @@ let process_crate (cx:ctxt) (crate:Ast.crate) : unit = unify_atom atom tv_a; unify_tyvars tv tv_a | Ast.UNOP_cast t -> - (* - * FIXME: check cast-validity in post-typecheck pass. - * Only some casts make sense. + (* FIXME (issue #84): check cast-validity in + * post-typecheck pass. Only some casts make sense. *) let tv_a = ref TYSPEC_all in let t = Hashtbl.find cx.ctxt_all_cast_types t.id in @@ -889,8 +888,8 @@ let process_crate (cx:ctxt) (crate:Ast.crate) : unit = begin fun _ -> let tv = Hashtbl.find bindings referent in - log cx "lval-base slot tyspec for %a = %s" - Ast.sprintf_lval lval (tyspec_to_str (!tv)); + log cx "lval-base slot tyspec for %a = %s" + Ast.sprintf_lval lval (tyspec_to_str (!tv)); end; unify_slot slot (Some referent) tv @@ -949,7 +948,7 @@ let process_crate (cx:ctxt) (crate:Ast.crate) : unit = and unify_lval (lval:Ast.lval) (tv:tyvar) : unit = let id = lval_base_id lval in - (* Fetch lval with type components resolved. *) + (* Fetch lval with type components resolved. *) let lval = Hashtbl.find cx.ctxt_all_lvals id in iflog cx (fun _ -> log cx "fetched resolved version of lval #%d = %a" @@ -1056,7 +1055,6 @@ let process_crate (cx:ctxt) (crate:Ast.crate) : unit = | Ast.STMT_decl _ -> () - (* FIXME: deal with difference between return-type vs. put-type *) | Ast.STMT_ret atom_opt | Ast.STMT_put atom_opt -> begin @@ -1069,7 +1067,9 @@ let process_crate (cx:ctxt) (crate:Ast.crate) : unit = check_callable (retval_tv()) callee args | Ast.STMT_bind (bound, callee, arg_opts) -> - (* FIXME: handle binding type parameters eventually. *) + (* FIXME (issue #81): handle binding type parameters + * eventually. + *) let out_tv = ref TYSPEC_all in let residue = ref [] in let gen_atom_opt_tvs atoms = @@ -1112,7 +1112,7 @@ let process_crate (cx:ctxt) (crate:Ast.crate) : unit = let lval_tv = ref TYSPEC_all in unify_lval lval lval_tv; Array.iter (fun _ -> push_pat_tv lval_tv) arms - + (* FIXME (issue #52): plenty more to handle here. *) | _ -> log cx "warning: not typechecking stmt %s\n" diff --git a/src/boot/me/typestate.ml b/src/boot/me/typestate.ml index 1824a56d..d42aaf6d 100644 --- a/src/boot/me/typestate.ml +++ b/src/boot/me/typestate.ml @@ -487,7 +487,7 @@ let condition_assigning_visitor | Ast.STMT_alt_tag at -> let precond = slot_inits (lval_slots cx at.Ast.alt_tag_lval) in let visit_arm { node = (pat, block) } = - (* FIXME: propagate tag-carried constrs here. *) + (* FIXME (issue #34): propagate tag-carried constrs here. *) let rec get_slots pat = match pat with Ast.PAT_slot header_slot -> [| header_slot |] diff --git a/src/boot/me/walk.ml b/src/boot/me/walk.ml index 57864f99..203acfce 100644 --- a/src/boot/me/walk.ml +++ b/src/boot/me/walk.ml @@ -524,7 +524,9 @@ and walk_stmt walk_lval v lv; Array.iter (walk_atom v) ats - (* FIXME: this should have a param array, and invoke the visitors. *) + (* FIXME (issue #86): this should have a param array, and invoke the + * visitors. + *) | Ast.STMT_decl (Ast.DECL_mod_item (id, mi)) -> walk_mod_item v id mi @@ -568,11 +570,11 @@ and walk_stmt | Ast.STMT_alt_tag { Ast.alt_tag_lval = lval; Ast.alt_tag_arms = arms } -> walk_lval v lval; - let walk_arm { node = (pat, block) } = - walk_pat v pat; - walk_block v block - in - Array.iter walk_arm arms + let walk_arm { node = (pat, block) } = + walk_pat v pat; + walk_block v block + in + Array.iter walk_arm arms (* FIXME (issue #20): finish this as needed. *) | Ast.STMT_slice _ |