@@ -150,6 +150,26 @@ module ErrorMessages = struct
150
150
let multiple_inline_record_definitions_at_same_path =
151
151
" Only one inline record definition is allowed per record field. This \
152
152
defines more than one inline record."
153
+
154
+ let keyword_field_in_expr keyword_txt =
155
+ " Cannot use keyword `"
156
+ ^ keyword_txt
157
+ ^ " ` as a record field name. Suggestion: rename it (e.g. `"
158
+ ^ keyword_txt ^ " _`)"
159
+
160
+ let keyword_field_in_pattern keyword_txt =
161
+ " Cannot use keyword `"
162
+ ^ keyword_txt
163
+ ^ " ` here. Keywords are not allowed as record field names."
164
+
165
+ let keyword_field_in_type keyword_txt =
166
+ " Cannot use keyword `"
167
+ ^ keyword_txt
168
+ ^ " ` as a record field name. Suggestion: rename it (e.g. `"
169
+ ^ keyword_txt
170
+ ^ " _`)\n If you need the field to be \" "
171
+ ^ keyword_txt ^ " \" at runtime, annotate the field: `@as(\" "
172
+ ^ keyword_txt ^ " \" ) " ^ keyword_txt ^ " _ : ...`"
153
173
end
154
174
155
175
module InExternal = struct
@@ -398,8 +418,17 @@ let build_longident words =
398
418
| [] -> assert false
399
419
| hd :: tl -> List. fold_left (fun p s -> Longident. Ldot (p, s)) (Lident hd) tl
400
420
401
- (* Recovers a keyword used as field name if it's probable that it's a full
402
- field name (not punning etc), by checking if there's a colon after it. *)
421
+ (* Emit a keyword-as-field diagnostic for the current token using a context-specific
422
+ message builder. *)
423
+ let emit_keyword_field_error (p : Parser.t ) ~mk_message =
424
+ let keyword_txt = Token. to_string p.token in
425
+ let keyword_start = p.Parser. start_pos in
426
+ let keyword_end = p.Parser. end_pos in
427
+ Parser. err ~start_pos: keyword_start ~end_pos: keyword_end p
428
+ (Diagnostics. message (mk_message keyword_txt))
429
+
430
+ (* Recovers a keyword used as field name if it's probable that it's a full
431
+ field name (not punning etc), by checking if there's a colon after it. *)
403
432
let recover_keyword_field_name_if_probably_field p ~mk_message :
404
433
(string * Location. t ) option =
405
434
if
@@ -408,13 +437,9 @@ let recover_keyword_field_name_if_probably_field p ~mk_message :
408
437
Parser. next st;
409
438
st.Parser. token = Colon )
410
439
then (
411
- let keyword_txt = Token. to_string p.token in
412
- let keyword_start = p.Parser. start_pos in
413
- let keyword_end = p.Parser. end_pos in
414
- Parser. err ~start_pos: keyword_start ~end_pos: keyword_end p
415
- (Diagnostics. message (mk_message keyword_txt));
416
- let loc = mk_loc keyword_start keyword_end in
417
- let recovered_field_name = keyword_txt ^ " _" in
440
+ emit_keyword_field_error p ~mk_message ;
441
+ let loc = mk_loc p.Parser. start_pos p.Parser. end_pos in
442
+ let recovered_field_name = Token. to_string p.token ^ " _" in
418
443
Parser. next p;
419
444
Some (recovered_field_name, loc))
420
445
else None
@@ -1402,28 +1427,16 @@ and parse_record_pattern_row p =
1402
1427
if Token. is_keyword p.token then (
1403
1428
match
1404
1429
recover_keyword_field_name_if_probably_field p
1405
- ~mk_message: (fun keyword_txt ->
1406
- " Cannot use keyword `" ^ keyword_txt
1407
- ^ " ` here. Keywords are not allowed as record field names." )
1430
+ ~mk_message: ErrorMessages. keyword_field_in_pattern
1408
1431
with
1409
1432
| Some (recovered_field_name , loc ) ->
1410
1433
Parser. expect Colon p;
1411
1434
let optional = parse_optional_label p in
1412
1435
let pat = parse_pattern p in
1413
- let field =
1414
- Location. mkloc (Longident. Lident recovered_field_name) loc
1415
- in
1436
+ let field = Location. mkloc (Longident. Lident recovered_field_name) loc in
1416
1437
Some (false , PatField {lid = field; x = pat; opt = optional})
1417
1438
| None ->
1418
- let keyword_txt = Token. to_string p.token in
1419
- let keyword_start = p.Parser. start_pos in
1420
- let keyword_end = p.Parser. end_pos in
1421
- let message =
1422
- " Cannot use keyword `" ^ keyword_txt
1423
- ^ " ` here. Keywords are not allowed as record field names."
1424
- in
1425
- Parser. err ~start_pos: keyword_start ~end_pos: keyword_end p
1426
- (Diagnostics. message message);
1439
+ emit_keyword_field_error p ~mk_message: ErrorMessages. keyword_field_in_pattern;
1427
1440
None )
1428
1441
else None
1429
1442
@@ -2974,10 +2987,7 @@ and parse_braced_or_record_expr p =
2974
2987
| token when Token. is_keyword token -> (
2975
2988
match
2976
2989
recover_keyword_field_name_if_probably_field p
2977
- ~mk_message: (fun keyword_txt ->
2978
- " Cannot use keyword `" ^ keyword_txt
2979
- ^ " ` as a record field name. Suggestion: rename it (e.g. `"
2980
- ^ keyword_txt ^ " _`)" )
2990
+ ~mk_message: ErrorMessages. keyword_field_in_expr
2981
2991
with
2982
2992
| Some (recovered_field_name , loc ) ->
2983
2993
Parser. expect Colon p;
@@ -3314,30 +3324,16 @@ and parse_record_expr_row p :
3314
3324
if Token. is_keyword p.token then (
3315
3325
match
3316
3326
recover_keyword_field_name_if_probably_field p
3317
- ~mk_message: (fun keyword_txt ->
3318
- " Cannot use keyword `" ^ keyword_txt
3319
- ^ " ` as a record field name. Suggestion: rename it (e.g. `"
3320
- ^ keyword_txt ^ " _`)" )
3327
+ ~mk_message: ErrorMessages. keyword_field_in_expr
3321
3328
with
3322
3329
| Some (recovered_field_name , loc ) ->
3323
3330
Parser. expect Colon p;
3324
3331
let optional = parse_optional_label p in
3325
3332
let field_expr = parse_expr p in
3326
- let field =
3327
- Location. mkloc (Longident. Lident recovered_field_name) loc
3328
- in
3333
+ let field = Location. mkloc (Longident. Lident recovered_field_name) loc in
3329
3334
Some {lid = field; x = field_expr; opt = optional}
3330
3335
| None ->
3331
- let keyword_txt = Token. to_string p.token in
3332
- let keyword_start = p.Parser. start_pos in
3333
- let keyword_end = p.Parser. end_pos in
3334
- let message =
3335
- " Cannot use keyword `" ^ keyword_txt
3336
- ^ " ` as a record field name. Suggestion: rename it (e.g. `"
3337
- ^ keyword_txt ^ " _`)"
3338
- in
3339
- Parser. err ~start_pos: keyword_start ~end_pos: keyword_end p
3340
- (Diagnostics. message message);
3336
+ emit_keyword_field_error p ~mk_message: ErrorMessages. keyword_field_in_expr;
3341
3337
None )
3342
3338
else None
3343
3339
@@ -4839,12 +4835,7 @@ and parse_field_declaration_region ?current_type_name_path ?inline_types_context
4839
4835
if Token. is_keyword p.token then (
4840
4836
match
4841
4837
recover_keyword_field_name_if_probably_field p
4842
- ~mk_message: (fun keyword_txt ->
4843
- " Cannot use keyword `" ^ keyword_txt
4844
- ^ " ` as a record field name. Suggestion: rename it (e.g. `"
4845
- ^ keyword_txt ^ " _`)\n " ^ " If you need the field to be \" "
4846
- ^ keyword_txt ^ " \" at runtime, annotate the field: `@as(\" "
4847
- ^ keyword_txt ^ " \" ) " ^ keyword_txt ^ " _ : ...`" )
4838
+ ~mk_message: ErrorMessages. keyword_field_in_type
4848
4839
with
4849
4840
| Some (recovered_field_name , name_loc ) ->
4850
4841
let optional = parse_optional_label p in
@@ -4856,18 +4847,7 @@ and parse_field_declaration_region ?current_type_name_path ?inline_types_context
4856
4847
let name = Location. mkloc recovered_field_name name_loc in
4857
4848
Some (Ast_helper.Type. field ~attrs ~loc ~mut ~optional name typ)
4858
4849
| None ->
4859
- let keyword_txt = Token. to_string p.token in
4860
- let keyword_start = p.Parser. start_pos in
4861
- let keyword_end = p.Parser. end_pos in
4862
- let message =
4863
- " Cannot use keyword `" ^ keyword_txt
4864
- ^ " ` as a record field name. Suggestion: rename it (e.g. `"
4865
- ^ keyword_txt ^ " _`)\n " ^ " If you need the field to be \" "
4866
- ^ keyword_txt ^ " \" at runtime, annotate the field: `@as(\" "
4867
- ^ keyword_txt ^ " \" ) " ^ keyword_txt ^ " _ : ...`"
4868
- in
4869
- Parser. err ~start_pos: keyword_start ~end_pos: keyword_end p
4870
- (Diagnostics. message message);
4850
+ emit_keyword_field_error p ~mk_message: ErrorMessages. keyword_field_in_type;
4871
4851
None )
4872
4852
else (
4873
4853
if attrs <> [] then
0 commit comments