Skip to content

Commit bcaccfc

Browse files
committed
refactor: more logic in ast_untagged_variants
1 parent 787a764 commit bcaccfc

File tree

2 files changed

+43
-28
lines changed

2 files changed

+43
-28
lines changed

compiler/ml/ast_untagged_variants.ml

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,12 @@ type switch_names = {consts: tag array; blocks: block array}
9191

9292
let untagged = "unboxed"
9393

94+
let block_type_can_be_undefined = function
95+
| IntType | StringType | FloatType | BigintType | BooleanType | InstanceType _
96+
| FunctionType | ObjectType ->
97+
false
98+
| UnknownType -> true
99+
94100
let has_untagged (attrs : Parsetree.attributes) =
95101
Ext_list.exists attrs (function {txt}, _ -> txt = untagged)
96102

@@ -328,23 +334,35 @@ let check_invariant ~is_untagged_def ~(consts : (Location.t * tag) list)
328334
invariant loc block.tag.name
329335
| None -> ())
330336

337+
let get_cstr_loc_tag (cstr : Types.constructor_declaration) =
338+
( cstr.cd_loc,
339+
{
340+
name = Ident.name cstr.cd_id;
341+
tag_type = process_tag_type cstr.cd_attributes;
342+
} )
343+
344+
let constructor_declaration_from_constructor_description ~env
345+
(cd : Types.constructor_description) : Types.constructor_declaration option
346+
=
347+
match cd.cstr_res.desc with
348+
| Tconstr (path, _, _) -> (
349+
match Env.find_type path env with
350+
| {type_kind = Type_variant cstrs} ->
351+
Ext_list.find_opt cstrs (fun cstr ->
352+
if cstr.cd_id.name = cd.cstr_name then Some cstr else None)
353+
| _ -> None)
354+
| _ -> None
355+
331356
let names_from_type_variant ?(is_untagged_def = false) ~env
332357
(cstrs : Types.constructor_declaration list) =
333-
let get_cstr_name (cstr : Types.constructor_declaration) =
334-
( cstr.cd_loc,
335-
{
336-
name = Ident.name cstr.cd_id;
337-
tag_type = process_tag_type cstr.cd_attributes;
338-
} )
339-
in
340358
let get_block (cstr : Types.constructor_declaration) : block =
341-
let tag = snd (get_cstr_name cstr) in
359+
let tag = snd (get_cstr_loc_tag cstr) in
342360
{tag; tag_name = get_tag_name cstr; block_type = get_block_type ~env cstr}
343361
in
344362
let consts, blocks =
345363
Ext_list.fold_left cstrs ([], []) (fun (consts, blocks) cstr ->
346364
if is_nullary_variant cstr.cd_args then
347-
(get_cstr_name cstr :: consts, blocks)
365+
(get_cstr_loc_tag cstr :: consts, blocks)
348366
else (consts, (cstr.cd_loc, get_block cstr) :: blocks))
349367
in
350368
check_invariant ~is_untagged_def ~consts ~blocks;

compiler/ml/parmatch.ml

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -544,26 +544,23 @@ let all_record_args lbls =
544544
_,
545545
[({pat_desc = Tpat_construct (_, cd, _)} as pat_construct)] )
546546
when lbl_is_optional () -> (
547-
let block_type =
548-
match cd.cstr_res.desc with
549-
| Tconstr (path, _, _) -> (
550-
match Env.find_type path pat.pat_env with
551-
| {type_kind = Type_variant cstrs} ->
552-
Ext_list.find_opt cstrs (fun cstr ->
553-
if cstr.cd_id.name = cd.cstr_name then
554-
Ast_untagged_variants.get_block_type ~env:pat.pat_env
555-
cstr
556-
else None)
557-
| _ -> None)
558-
| _ -> None
547+
let cdecl =
548+
Ast_untagged_variants
549+
.constructor_declaration_from_constructor_description
550+
~env:pat.pat_env cd
559551
in
560-
match block_type with
561-
| Some
562-
( IntType | StringType | FloatType | BigintType | BooleanType
563-
| InstanceType _ | FunctionType | ObjectType ) ->
564-
(* These types cannot be undefined *)
565-
(id, lbl, pat_construct)
566-
| _ -> x)
552+
match cdecl with
553+
| None -> x
554+
| Some cstr -> (
555+
match
556+
Ast_untagged_variants.get_block_type ~env:pat.pat_env cstr
557+
with
558+
| Some block_type
559+
when not
560+
(Ast_untagged_variants.block_type_can_be_undefined
561+
block_type) ->
562+
(id, lbl, pat_construct)
563+
| _ -> x))
567564
| _ -> x
568565
in
569566
t.(lbl.lbl_pos) <- x)

0 commit comments

Comments
 (0)