Skip to content

Commit ecd40f2

Browse files
authored
Fix dropped attributes on begin-end in a match case (ocaml-ppx#2421)
The special formatting of a begin-end in a match case was dropping attributes.
1 parent 2d9fb4a commit ecd40f2

File tree

7 files changed

+88
-27
lines changed

7 files changed

+88
-27
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ profile. This started with version 0.26.0.
88

99
### Bug fixes
1010

11+
- Fix dropped attributes on a begin-end in a match case (#2421, @Julow)
1112
- Fix non-stabilizing comments before a functor type argument (#2420, @Julow)
1213
- Fix crash caused by module types with nested `with module` (#2419, @Julow)
1314

lib/Fmt_ast.ml

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2641,14 +2641,6 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0)
26412641
when List.exists eN ~f:(fun x ->
26422642
Base.phys_equal xexp.ast x.if_body ) ->
26432643
Fn.id
2644-
(* begin-end keywords are handled when printing pattern-matching
2645-
cases *)
2646-
| Exp
2647-
{ pexp_desc=
2648-
Pexp_function xs | Pexp_match (_, xs) | Pexp_try (_, xs)
2649-
; _ }
2650-
when List.exists xs ~f:(fun x -> Poly.(x.pc_rhs = exp)) ->
2651-
Fn.id
26522644
| _ ->
26532645
fun k ->
26542646
let opn = str "begin" $ fmt_extension_suffix c ext
@@ -3058,7 +3050,7 @@ and fmt_case c ctx ~first ~last case =
30583050
$ p.open_paren_branch )
30593051
$ p.break_after_opening_paren
30603052
$ hovbox 0
3061-
( fmt_expression ?eol c ?parens:p.expr_parens xrhs
3053+
( fmt_expression ?eol c ?parens:p.expr_parens p.branch_expr
30623054
$ p.close_paren_branch ) )
30633055

30643056
and fmt_value_description ?ext c ctx vd =

lib/Params.ml

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ type cases =
135135
; open_paren_branch: Fmt.t
136136
; break_after_opening_paren: Fmt.t
137137
; expr_parens: bool option
138+
; branch_expr: expression Ast.xt
138139
; close_paren_branch: Fmt.t }
139140

140141
let get_cases (c : Conf.t) ~ctx ~first ~last ~xbch:({ast; _} as xast) =
@@ -165,24 +166,25 @@ let get_cases (c : Conf.t) ~ctx ~first ~last ~xbch:({ast; _} as xast) =
165166
else (parenze_exp xast && not body_has_parens, Some false)
166167
in
167168
let indent = if align_nested_match then 0 else indent in
168-
let beginend =
169-
match ast with {pexp_desc= Pexp_beginend _; _} -> true | _ -> false
170-
in
171-
let open_paren_branch =
172-
if beginend then fmt "@;<1 0>begin" else fmt_if parens_branch " ("
173-
in
174-
let close_paren_branch =
175-
if beginend then
176-
let offset =
177-
match c.fmt_opts.break_cases.v with `Nested -> 0 | _ -> -2
178-
in
179-
fits_breaks " end" ~level:1 ~hint:(1000, offset) "end"
180-
else
181-
fmt_if_k parens_branch
182-
( match c.fmt_opts.indicate_multiline_delimiters.v with
183-
| `Space -> fmt "@ )"
184-
| `No -> fmt "@,)"
185-
| `Closing_on_separate_line -> fmt "@;<1000 -2>)" )
169+
let open_paren_branch, close_paren_branch, branch_expr =
170+
match ast with
171+
| {pexp_desc= Pexp_beginend nested_exp; pexp_attributes= []; _} ->
172+
let close_paren =
173+
let offset =
174+
match c.fmt_opts.break_cases.v with `Nested -> 0 | _ -> -2
175+
in
176+
fits_breaks " end" ~level:1 ~hint:(1000, offset) "end"
177+
in
178+
(fmt "@;<1 0>begin", close_paren, sub_exp ~ctx:(Exp ast) nested_exp)
179+
| _ ->
180+
let close_paren =
181+
fmt_if_k parens_branch
182+
( match c.fmt_opts.indicate_multiline_delimiters.v with
183+
| `Space -> fmt "@ )"
184+
| `No -> fmt "@,)"
185+
| `Closing_on_separate_line -> fmt "@;<1000 -2>)" )
186+
in
187+
(fmt_if parens_branch " (", close_paren, xast)
186188
in
187189
match c.fmt_opts.break_cases.v with
188190
| `Fit ->
@@ -195,6 +197,7 @@ let get_cases (c : Conf.t) ~ctx ~first ~last ~xbch:({ast; _} as xast) =
195197
; open_paren_branch
196198
; break_after_opening_paren= fmt "@ "
197199
; expr_parens
200+
; branch_expr
198201
; close_paren_branch }
199202
| `Nested ->
200203
{ leading_space= fmt_if (not first) "@ "
@@ -206,6 +209,7 @@ let get_cases (c : Conf.t) ~ctx ~first ~last ~xbch:({ast; _} as xast) =
206209
; open_paren_branch
207210
; break_after_opening_paren= fmt_or (indent > 2) "@;<1 4>" "@;<1 2>"
208211
; expr_parens
212+
; branch_expr
209213
; close_paren_branch }
210214
| `Fit_or_vertical ->
211215
{ leading_space= break_unless_newline 1000 0
@@ -217,6 +221,7 @@ let get_cases (c : Conf.t) ~ctx ~first ~last ~xbch:({ast; _} as xast) =
217221
; open_paren_branch
218222
; break_after_opening_paren= fmt "@ "
219223
; expr_parens
224+
; branch_expr
220225
; close_paren_branch }
221226
| `Toplevel | `All ->
222227
{ leading_space= break_unless_newline 1000 0
@@ -228,6 +233,7 @@ let get_cases (c : Conf.t) ~ctx ~first ~last ~xbch:({ast; _} as xast) =
228233
; open_paren_branch
229234
; break_after_opening_paren= fmt "@ "
230235
; expr_parens
236+
; branch_expr
231237
; close_paren_branch }
232238
| `Vertical ->
233239
{ leading_space= break_unless_newline 1000 0
@@ -239,6 +245,7 @@ let get_cases (c : Conf.t) ~ctx ~first ~last ~xbch:({ast; _} as xast) =
239245
; open_paren_branch
240246
; break_after_opening_paren= break 1000 0
241247
; expr_parens
248+
; branch_expr
242249
; close_paren_branch }
243250

244251
let wrap_collec c ~space_around opn cls =

lib/Params.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ type cases =
6161
; open_paren_branch: Fmt.t
6262
; break_after_opening_paren: Fmt.t
6363
; expr_parens: bool option
64+
; branch_expr: expression Ast.xt (** Expression on the RHS of the [->]. *)
6465
; close_paren_branch: Fmt.t }
6566

6667
val get_cases :

test/passing/tests/exp_grouping-parens.ml.ref

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,3 +307,24 @@ let _ =
307307
[@landmark "parse_constant_dividends"]
308308

309309
let () = if a then b (* asd *)
310+
311+
let x =
312+
let get_path_and_distance pv1 pv2 =
313+
if is_loop pv1 pv2 then
314+
Some ([], 0)
315+
else
316+
match Tbl.find dist_tbl (pv1, pv2) with
317+
| None ->
318+
(* FIXME: temporary hack to avoid Jane Street's annoying warnings. *)
319+
begin
320+
try
321+
let path', dist = Dijkstra.shortest_path pgraph pv1 pv2 in
322+
let path = unwrap_path path' in
323+
Tbl.set dist_tbl ~key:(pv1, pv2) ~data:(path, dist) ;
324+
Some (path, dist)
325+
with Not_found | Not_found_s _ -> None
326+
end
327+
[@warning "-3"]
328+
| pd -> pd
329+
in
330+
()

test/passing/tests/exp_grouping.ml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,3 +249,21 @@ let () =
249249
if a then begin b
250250
(* asd *)
251251
end
252+
253+
let x =
254+
let get_path_and_distance pv1 pv2 =
255+
if is_loop pv1 pv2 then Some ([],0) else
256+
match Tbl.find dist_tbl (pv1, pv2) with
257+
| None ->
258+
(* FIXME: temporary hack to avoid Jane Street's annoying warnings. *)
259+
begin[@warning "-3"] try
260+
let path', dist = Dijkstra.shortest_path pgraph pv1 pv2 in
261+
let path = unwrap_path path' in
262+
Tbl.set dist_tbl ~key:(pv1, pv2) ~data:(path, dist);
263+
Some (path, dist)
264+
with Not_found | Not_found_s _ ->
265+
None
266+
end
267+
| pd -> pd
268+
in
269+
()

test/passing/tests/exp_grouping.ml.ref

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,3 +361,24 @@ let () =
361361
b
362362
(* asd *)
363363
end
364+
365+
let x =
366+
let get_path_and_distance pv1 pv2 =
367+
if is_loop pv1 pv2 then
368+
Some ([], 0)
369+
else
370+
match Tbl.find dist_tbl (pv1, pv2) with
371+
| None ->
372+
(* FIXME: temporary hack to avoid Jane Street's annoying warnings. *)
373+
begin
374+
try
375+
let path', dist = Dijkstra.shortest_path pgraph pv1 pv2 in
376+
let path = unwrap_path path' in
377+
Tbl.set dist_tbl ~key:(pv1, pv2) ~data:(path, dist) ;
378+
Some (path, dist)
379+
with Not_found | Not_found_s _ -> None
380+
end
381+
[@warning "-3"]
382+
| pd -> pd
383+
in
384+
()

0 commit comments

Comments
 (0)