Skip to content

Commit 7e8eb2c

Browse files
authored
Fix destruct crashing on closed variant types (#1602)
from voodoos/repro-issue-1601
2 parents b22a75c + c803ab5 commit 7e8eb2c

File tree

3 files changed

+55
-4
lines changed

3 files changed

+55
-4
lines changed

CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ unreleased
1919
- Fix incorrect locations for string literals (#1574)
2020
- Fixed an issue that caused `errors` to erroneously alert about missing
2121
`cmi` files (#1577)
22+
- Prevent destruct from crashing on closed variant types (#1602,
23+
fixes #1601)
2224
+ editor modes
2325
- emacs: call the user's configured completion UI in
2426
`merlin-construct` (#1598)

src/analysis/destruct.ml

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ let placeholder =
8686

8787
let rec gen_patterns ?(recurse=true) env type_expr =
8888
let open Types in
89+
log ~title:"gen_patterns" "%a" Logger.fmt (fun fmt ->
90+
Format.fprintf fmt "Generating patterns for type %a"
91+
Printtyp.type_expr type_expr);
8992
match get_desc type_expr with
9093
| Tlink _ -> assert false (* impossible after [Btype.repr] *)
9194
| Tvar _ -> raise (Not_allowed "non-immediate type")
@@ -158,7 +161,14 @@ let rec gen_patterns ?(recurse=true) env type_expr =
158161
| lbl, Rpresent param_opt ->
159162
let popt = Option.map param_opt ~f:(fun _ -> Patterns.omega) in
160163
Some (Tast_helper.Pat.variant env type_expr lbl popt (ref row_desc))
161-
| _, _ -> None
164+
| _, Reither (_, l, _) ->
165+
let popt = match l with
166+
| [] -> None
167+
| _ :: _ -> Some Patterns.omega
168+
in
169+
Some (Tast_helper.Pat.variant env type_expr lbl popt (ref row_desc))
170+
| _, _ ->
171+
log ~title:"gen_patterns" "Absent"; None
162172
)
163173
| _ ->
164174
let fmt, to_string = Format.to_string () in
@@ -547,17 +557,18 @@ let rec node config source selected_node parents =
547557
let str = Mreader.print_pretty config source (Pretty_case_list cases) in
548558
loc, str
549559
| [] ->
560+
(* The match is already complete, we try to refine it *)
550561
begin match Typedtree.classify_pattern patt with
551562
| Computation -> raise (Not_allowed ("computation pattern"));
552563
| Value ->
553564
let _patt : Typedtree.value Typedtree.general_pattern = patt in
554565
if not (destructible patt) then raise Nothing_to_do else
555566
let ty = patt.Typedtree.pat_type in
556-
(* Printf.eprintf "pouet cp \n%!" ; *)
557567
begin match gen_patterns patt.Typedtree.pat_env ty with
558-
| [] -> assert false (* we raise Not_allowed, but never return [] *)
568+
| [] ->
569+
(* gen_patterns might raise Not_allowed, but should never return [] *)
570+
assert false
559571
| [ more_precise ] ->
560-
(* Printf.eprintf "one cp \n%!" ; *)
561572
(* If only one pattern is generated, then we're only refining the
562573
current pattern, not generating new branches. *)
563574
let ppat = filter_pat_attr (Untypeast.untype_pattern more_precise) in
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
$ cat >main.ml <<EOF
2+
> let foo : [< \`Foo ] option = None
3+
>
4+
> let () =
5+
> match foo with
6+
> | None | Some _ -> ()
7+
> EOF
8+
9+
$ $MERLIN single case-analysis -start 5:16 -end 5:16 \
10+
> -filename main.ml <main.ml |
11+
> jq '.value[1]'
12+
"`Foo"
13+
14+
$ cat >main.ml <<EOF
15+
> let foo : [> \`Foo ] option = None
16+
>
17+
> let () =
18+
> match foo with
19+
> | None | Some _ -> ()
20+
> EOF
21+
22+
$ $MERLIN single case-analysis -start 5:16 -end 5:16 \
23+
> -filename main.ml <main.ml |
24+
> jq '.value[1]'
25+
"`Foo"
26+
27+
$ cat >main.ml <<EOF
28+
> let foo : [< \`Foo | \`Bar > \`Foo] option = None
29+
>
30+
> let () =
31+
> match foo with
32+
> | None | Some _ -> ()
33+
> EOF
34+
35+
$ $MERLIN single case-analysis -start 5:16 -end 5:16 \
36+
> -filename main.ml <main.ml |
37+
> jq '.value[1]'
38+
"None | Some `Bar | Some `Foo"

0 commit comments

Comments
 (0)