@@ -97,6 +97,24 @@ module ErrorMessages = struct
9797 ...b}` wouldn't make sense, as `b` would override every field of `a` \
9898 anyway."
9999
100+ let record_field_missing_colon =
101+ " Records use `:` when assigning fields. Example: `{field: value}`"
102+
103+ let record_pattern_field_missing_colon =
104+ " Record patterns use `:` when matching fields. Example: `{field: value}`"
105+
106+ let record_type_field_missing_colon =
107+ " Record fields in type declarations use `:`. Example: `{field: string}`"
108+
109+ let dict_field_missing_colon =
110+ " Dict entries use `:` to separate keys from values. Example: `{\" k\" : v}`"
111+
112+ let labelled_argument_missing_equal =
113+ " Use `=` to pass a labelled argument. Example: `~label=value`"
114+
115+ let optional_labelled_argument_missing_equal =
116+ " Optional labelled arguments use `=?`. Example: `~label=?value`"
117+
100118 let variant_ident =
101119 " A polymorphic variant (e.g. #id) must start with an alphabetical letter \
102120 or be a number (e.g. #742)"
@@ -1412,6 +1430,13 @@ and parse_record_pattern_row_field ~attrs p =
14121430 let optional = parse_optional_label p in
14131431 let pat = parse_pattern p in
14141432 (pat, optional)
1433+ | Equal ->
1434+ Parser. err ~start_pos: p.start_pos ~end_pos: p.end_pos p
1435+ (Diagnostics. message ErrorMessages. record_pattern_field_missing_colon);
1436+ Parser. next p;
1437+ let optional = parse_optional_label p in
1438+ let pat = parse_pattern p in
1439+ (pat, optional)
14151440 | _ ->
14161441 ( Ast_helper.Pat. var ~loc: label.loc ~attrs
14171442 (Location. mkloc (Longident. last label.txt) label.loc),
@@ -3060,6 +3085,19 @@ and parse_braced_or_record_expr p =
30603085 in
30613086 Parser. expect Rbrace p;
30623087 expr
3088+ | Equal ->
3089+ Parser. err ~start_pos: p.start_pos ~end_pos: p.end_pos p
3090+ (Diagnostics. message ErrorMessages. record_field_missing_colon);
3091+ Parser. next p;
3092+ let field_expr = parse_expr p in
3093+ Parser. optional p Comma |> ignore;
3094+ let expr =
3095+ parse_record_expr_with_string_keys ~start_pos
3096+ {Parsetree. lid = field; x = field_expr; opt = false }
3097+ p
3098+ in
3099+ Parser. expect Rbrace p;
3100+ expr
30633101 | _ -> (
30643102 let tag = if p.mode = ParseForTypeChecker then Some " js" else None in
30653103 let constant =
@@ -3153,6 +3191,28 @@ and parse_braced_or_record_expr p =
31533191 in
31543192 Parser. expect Rbrace p;
31553193 expr)
3194+ | Equal -> (
3195+ Parser. err ~start_pos: p.start_pos ~end_pos: p.end_pos p
3196+ (Diagnostics. message ErrorMessages. record_field_missing_colon);
3197+ Parser. next p;
3198+ let optional = parse_optional_label p in
3199+ let field_expr = parse_expr p in
3200+ match p.Parser. token with
3201+ | Rbrace ->
3202+ Parser. next p;
3203+ let loc = mk_loc start_pos p.prev_end_pos in
3204+ Ast_helper.Exp. record ~loc
3205+ [{lid = path_ident; x = field_expr; opt = optional}]
3206+ None
3207+ | _ ->
3208+ Parser. expect Comma p;
3209+ let expr =
3210+ parse_record_expr ~start_pos
3211+ [{lid = path_ident; x = field_expr; opt = optional}]
3212+ p
3213+ in
3214+ Parser. expect Rbrace p;
3215+ expr)
31563216 (* error case *)
31573217 | Lident _ ->
31583218 if p.prev_end_pos.pos_lnum < p.start_pos.pos_lnum then (
@@ -3295,6 +3355,12 @@ and parse_record_expr_row_with_string_key p :
32953355 Parser. next p;
32963356 let field_expr = parse_expr p in
32973357 Some {lid = field; x = field_expr; opt = false }
3358+ | Equal ->
3359+ Parser. err ~start_pos: p.start_pos ~end_pos: p.end_pos p
3360+ (Diagnostics. message ErrorMessages. record_field_missing_colon);
3361+ Parser. next p;
3362+ let field_expr = parse_expr p in
3363+ Some {lid = field; x = field_expr; opt = false }
32983364 | _ ->
32993365 Some
33003366 {
@@ -3324,6 +3390,13 @@ and parse_record_expr_row p :
33243390 let optional = parse_optional_label p in
33253391 let field_expr = parse_expr p in
33263392 Some {lid = field; x = field_expr; opt = optional}
3393+ | Equal ->
3394+ Parser. err ~start_pos: p.start_pos ~end_pos: p.end_pos p
3395+ (Diagnostics. message ErrorMessages. record_field_missing_colon);
3396+ Parser. next p;
3397+ let optional = parse_optional_label p in
3398+ let field_expr = parse_expr p in
3399+ Some {lid = field; x = field_expr; opt = optional}
33273400 | _ ->
33283401 let value = Ast_helper.Exp. ident ~loc: field.loc ~attrs field in
33293402 let value =
@@ -3377,6 +3450,12 @@ and parse_dict_expr_row p =
33773450 Parser. next p;
33783451 let fieldExpr = parse_expr p in
33793452 Some (field, fieldExpr)
3453+ | Equal ->
3454+ Parser. err ~start_pos: p.start_pos ~end_pos: p.end_pos p
3455+ (Diagnostics. message ErrorMessages. dict_field_missing_colon);
3456+ Parser. next p;
3457+ let fieldExpr = parse_expr p in
3458+ Some (field, fieldExpr)
33803459 | _ -> Some (field, Ast_helper.Exp. ident ~loc: field.loc field))
33813460 | _ -> None
33823461
@@ -3881,12 +3960,42 @@ and parse_argument2 p : argument option =
38813960 in
38823961 Some {label; expr}
38833962 | Colon ->
3963+ let colon_start = p.start_pos in
38843964 Parser. next p;
3885- let typ = parse_typ_expr p in
3886- let loc = mk_loc start_pos p.prev_end_pos in
3887- let expr = Ast_helper.Exp. constraint_ ~loc ident_expr typ in
3888- Some
3889- {label = Asttypes. Labelled {txt = ident; loc = named_arg_loc}; expr}
3965+ let colon_end = p.prev_end_pos in
3966+ if Grammar. is_typ_expr_start p.Parser. token then
3967+ let typ = parse_typ_expr p in
3968+ let loc = mk_loc start_pos p.prev_end_pos in
3969+ let expr = Ast_helper.Exp. constraint_ ~loc ident_expr typ in
3970+ Some
3971+ {label = Asttypes. Labelled {txt = ident; loc = named_arg_loc}; expr}
3972+ else
3973+ let label, expr =
3974+ match p.Parser. token with
3975+ | Question ->
3976+ Parser. err ~start_pos: colon_start ~end_pos: colon_end p
3977+ (Diagnostics. message
3978+ ErrorMessages. optional_labelled_argument_missing_equal);
3979+ Parser. next p;
3980+ let expr = parse_constrained_or_coerced_expr p in
3981+ (Asttypes. Optional {txt = ident; loc = named_arg_loc}, expr)
3982+ | _ ->
3983+ Parser. err ~start_pos: colon_start ~end_pos: colon_end p
3984+ (Diagnostics. message
3985+ ErrorMessages. labelled_argument_missing_equal);
3986+ let expr =
3987+ match p.Parser. token with
3988+ | Underscore
3989+ when not (is_es6_arrow_expression ~in_ternary: false p) ->
3990+ let loc = mk_loc p.start_pos p.end_pos in
3991+ Parser. next p;
3992+ Ast_helper.Exp. ident ~loc
3993+ (Location. mkloc (Longident. Lident " _" ) loc)
3994+ | _ -> parse_constrained_or_coerced_expr p
3995+ in
3996+ (Asttypes. Labelled {txt = ident; loc = named_arg_loc}, expr)
3997+ in
3998+ Some {label; expr}
38903999 | _ ->
38914000 Some
38924001 {
@@ -4783,7 +4892,13 @@ and parse_string_field_declaration p =
47834892 let name_end_pos = p.end_pos in
47844893 Parser. next p;
47854894 let field_name = Location. mkloc name (mk_loc name_start_pos name_end_pos) in
4786- Parser. expect ~grammar: Grammar. TypeExpression Colon p;
4895+ (match p.Parser. token with
4896+ | Colon -> Parser. next p
4897+ | Equal ->
4898+ Parser. err ~start_pos: p.start_pos ~end_pos: p.end_pos p
4899+ (Diagnostics. message ErrorMessages. record_type_field_missing_colon);
4900+ Parser. next p
4901+ | _ -> Parser. expect ~grammar: Grammar. TypeExpression Colon p);
47874902 let typ = parse_poly_type_expr p in
47884903 Some (Parsetree. Otag (field_name, attrs, typ))
47894904 | DotDotDot ->
@@ -4796,7 +4911,13 @@ and parse_string_field_declaration p =
47964911 (Diagnostics. message (ErrorMessages. object_quoted_field_name name));
47974912 Parser. next p;
47984913 let field_name = Location. mkloc name name_loc in
4799- Parser. expect ~grammar: Grammar. TypeExpression Colon p;
4914+ (match p.Parser. token with
4915+ | Colon -> Parser. next p
4916+ | Equal ->
4917+ Parser. err ~start_pos: p.start_pos ~end_pos: p.end_pos p
4918+ (Diagnostics. message ErrorMessages. record_type_field_missing_colon);
4919+ Parser. next p
4920+ | _ -> Parser. expect ~grammar: Grammar. TypeExpression Colon p);
48004921 let typ = parse_poly_type_expr p in
48014922 Some (Parsetree. Otag (field_name, attrs, typ))
48024923 | _token -> None
@@ -4825,6 +4946,14 @@ and parse_field_declaration ?current_type_name_path ?inline_types_context p =
48254946 extend_current_type_name_path current_type_name_path name.txt
48264947 in
48274948 parse_poly_type_expr ?current_type_name_path ?inline_types_context p
4949+ | Equal ->
4950+ Parser. err ~start_pos: p.start_pos ~end_pos: p.end_pos p
4951+ (Diagnostics. message ErrorMessages. record_type_field_missing_colon);
4952+ Parser. next p;
4953+ let current_type_name_path =
4954+ extend_current_type_name_path current_type_name_path name.txt
4955+ in
4956+ parse_poly_type_expr ?current_type_name_path ?inline_types_context p
48284957 | _ ->
48294958 Ast_helper.Typ. constr ~loc: name.loc {name with txt = Lident name.txt} []
48304959 in
@@ -4866,6 +4995,11 @@ and parse_field_declaration_region ?current_type_name_path ?inline_types_context
48664995 | Colon ->
48674996 Parser. next p;
48684997 parse_poly_type_expr ?current_type_name_path ?inline_types_context p
4998+ | Equal ->
4999+ Parser. err ~start_pos: p.start_pos ~end_pos: p.end_pos p
5000+ (Diagnostics. message ErrorMessages. record_type_field_missing_colon);
5001+ Parser. next p;
5002+ parse_poly_type_expr ?current_type_name_path ?inline_types_context p
48695003 | _ ->
48705004 Ast_helper.Typ. constr ~loc: name.loc ~attrs
48715005 {name with txt = Lident name.txt}
0 commit comments