Skip to content

Commit 90f0892

Browse files
authored
Add missing parens in pattern in 'let+ (Cstr _) : t = ...' (#2661)
The parentheses check is unified between value_binding and binding_op to prevent similar bugs in the future.
1 parent 6534b38 commit 90f0892

15 files changed

+126
-16
lines changed

CHANGES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ profile. This started with version 0.26.0.
2222
- `Ast_mapper.default_mapper` now iterates on the location of `in` in `let+ .. in ..`
2323
(#2658, @v-gb)
2424

25+
- Fix missing parentheses in `let+ (Cstr _) : _ = _` (#2661, @Julow)
26+
This caused a crash as the generated code wasn't valid syntax.
27+
2528
## 0.27.0
2629

2730
### Highlight

lib/Ast.ml

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1877,22 +1877,32 @@ end = struct
18771877
| Ppat_tuple _ -> true
18781878
| _ -> false
18791879

1880-
let parenze_pat_in_bindings bindings pat =
1881-
let parenze_pat_in_binding ~pvb_constraint =
1880+
let parenze_pat_in_bindings' ~pat_of_binding bindings pat =
1881+
let parenze_pat_in_binding ~constraint_ =
18821882
(* Some patterns must be parenthesed when followed by a colon. *)
1883-
(exposed_right_colon pat && Option.is_some pvb_constraint)
1883+
(exposed_right_colon pat && Option.is_some constraint_)
18841884
||
18851885
match pat.ppat_desc with
18861886
| Ppat_construct (_, Some _)
18871887
|Ppat_variant (_, Some _)
18881888
|Ppat_cons _ | Ppat_alias _ | Ppat_or _ ->
1889-
(* Add disambiguation parentheses that are not necessary. *)
1889+
(* These parentheses serve as disambiguation for value_bindings but
1890+
are mandatory for binding_op. *)
18901891
true
18911892
| _ -> false
18921893
in
1893-
List.exists bindings ~f:(fun {pvb_pat; pvb_constraint; _} ->
1894+
List.exists bindings ~f:(fun binding ->
1895+
let pat', constraint_ = pat_of_binding binding in
18941896
(* [pat] appears on the left side of a binding. *)
1895-
pvb_pat == pat && parenze_pat_in_binding ~pvb_constraint )
1897+
pat' == pat && parenze_pat_in_binding ~constraint_ )
1898+
1899+
let parenze_pat_in_bindings =
1900+
let pat_of_binding {pvb_pat= p; pvb_constraint= t; _} = (p, t) in
1901+
parenze_pat_in_bindings' ~pat_of_binding
1902+
1903+
let parenze_pat_in_letop let_ ands pat =
1904+
let pat_of_binding {pbop_pat= p; pbop_typ= t; _} = (p, t) in
1905+
parenze_pat_in_bindings' ~pat_of_binding (let_ :: ands) pat
18961906

18971907
(** [parenze_pat {ctx; ast}] holds when pattern [ast] should be
18981908
parenthesized in context [ctx]. *)
@@ -1913,16 +1923,6 @@ end = struct
19131923
| Fpc {pparam_desc= _; _}, Ppat_cons _ -> true
19141924
| Pat {ppat_desc= Ppat_construct _; _}, Ppat_cons _ -> true
19151925
| _, Ppat_constraint (_, {ptyp_desc= Ptyp_poly _; _}) -> false
1916-
| ( Exp {pexp_desc= Pexp_letop _; _}
1917-
, ( Ppat_construct (_, Some _)
1918-
| Ppat_cons _
1919-
| Ppat_variant (_, Some _)
1920-
| Ppat_or _ | Ppat_alias _
1921-
| Ppat_constraint ({ppat_desc= Ppat_any; _}, _) ) ) ->
1922-
true
1923-
| ( Exp {pexp_desc= Pexp_letop _; _}
1924-
, Ppat_constraint ({ppat_desc= Ppat_tuple _; _}, _) ) ->
1925-
false
19261926
| ( Bo {pbop_typ= None; _}
19271927
, ( Ppat_construct (_, Some _)
19281928
| Ppat_cons _
@@ -1988,6 +1988,10 @@ end = struct
19881988
, _ )
19891989
when parenze_pat_in_bindings pvbs_bindings pat ->
19901990
true
1991+
| Exp {pexp_desc= Pexp_letop {let_; ands; _}; _}, _
1992+
when parenze_pat_in_letop let_ ands pat ->
1993+
true
1994+
| Bo bo, _ when parenze_pat_in_letop bo [] pat -> true
19911995
| ( Lb {pvb_pat; _}
19921996
, ( Ppat_construct (_, Some _)
19931997
| Ppat_variant (_, Some _)

test/passing/refs.default/let_binding-deindent-fun.ml.ref

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,3 +262,11 @@ let _ =
262262
| Strict | Alias -> Immutable
263263
| StrictOpt -> Mutable
264264
;;
265+
266+
let rewrite_export =
267+
let (Raw id) : binary indice = () in
268+
let (a, b) : a * b = () in
269+
let+ (Raw id) : binary indice = () in
270+
let+ (a, b) : a * b = () in
271+
()
272+
;;

test/passing/refs.default/let_binding-in_indent.ml.ref

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,3 +262,11 @@ let _ =
262262
| Strict | Alias -> Immutable
263263
| StrictOpt -> Mutable
264264
;;
265+
266+
let rewrite_export =
267+
let (Raw id) : binary indice = () in
268+
let (a, b) : a * b = () in
269+
let+ (Raw id) : binary indice = () in
270+
let+ (a, b) : a * b = () in
271+
()
272+
;;

test/passing/refs.default/let_binding-indent.ml.ref

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,3 +263,11 @@ let _ =
263263
| Strict | Alias -> Immutable
264264
| StrictOpt -> Mutable
265265
;;
266+
267+
let rewrite_export =
268+
let (Raw id) : binary indice = () in
269+
let (a, b) : a * b = () in
270+
let+ (Raw id) : binary indice = () in
271+
let+ (a, b) : a * b = () in
272+
()
273+
;;

test/passing/refs.default/let_binding.ml.ref

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,3 +262,11 @@ let _ =
262262
| Strict | Alias -> Immutable
263263
| StrictOpt -> Mutable
264264
;;
265+
266+
let rewrite_export =
267+
let (Raw id) : binary indice = () in
268+
let (a, b) : a * b = () in
269+
let+ (Raw id) : binary indice = () in
270+
let+ (a, b) : a * b = () in
271+
()
272+
;;

test/passing/refs.janestreet/let_binding-deindent-fun.ml.ref

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,3 +315,11 @@ let _ =
315315
| Strict | Alias -> Immutable
316316
| StrictOpt -> Mutable
317317
;;
318+
319+
let rewrite_export =
320+
let (Raw id) : binary indice = () in
321+
let (a, b) : a * b = () in
322+
let+ (Raw id) : binary indice = () in
323+
let+ (a, b) : a * b = () in
324+
()
325+
;;

test/passing/refs.janestreet/let_binding-in_indent.ml.ref

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,3 +315,11 @@ let _ =
315315
| Strict | Alias -> Immutable
316316
| StrictOpt -> Mutable
317317
;;
318+
319+
let rewrite_export =
320+
let (Raw id) : binary indice = () in
321+
let (a, b) : a * b = () in
322+
let+ (Raw id) : binary indice = () in
323+
let+ (a, b) : a * b = () in
324+
()
325+
;;

test/passing/refs.janestreet/let_binding-indent.ml.ref

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,3 +315,11 @@ let _ =
315315
| Strict | Alias -> Immutable
316316
| StrictOpt -> Mutable
317317
;;
318+
319+
let rewrite_export =
320+
let (Raw id) : binary indice = () in
321+
let (a, b) : a * b = () in
322+
let+ (Raw id) : binary indice = () in
323+
let+ (a, b) : a * b = () in
324+
()
325+
;;

test/passing/refs.janestreet/let_binding.ml.ref

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,3 +315,11 @@ let _ =
315315
| Strict | Alias -> Immutable
316316
| StrictOpt -> Mutable
317317
;;
318+
319+
let rewrite_export =
320+
let (Raw id) : binary indice = () in
321+
let (a, b) : a * b = () in
322+
let+ (Raw id) : binary indice = () in
323+
let+ (a, b) : a * b = () in
324+
()
325+
;;

0 commit comments

Comments
 (0)