@@ -150,6 +150,26 @@ module ErrorMessages = struct
150150 let multiple_inline_record_definitions_at_same_path =
151151 " Only one inline record definition is allowed per record field. This \
152152 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 ^ " _ : ...`"
153173end
154174
155175module InExternal = struct
@@ -398,8 +418,17 @@ let build_longident words =
398418 | [] -> assert false
399419 | hd :: tl -> List. fold_left (fun p s -> Longident. Ldot (p, s)) (Lident hd) tl
400420
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. *)
403432let recover_keyword_field_name_if_probably_field p ~mk_message :
404433 (string * Location. t ) option =
405434 if
@@ -408,13 +437,9 @@ let recover_keyword_field_name_if_probably_field p ~mk_message :
408437 Parser. next st;
409438 st.Parser. token = Colon )
410439 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
418443 Parser. next p;
419444 Some (recovered_field_name, loc))
420445 else None
@@ -1402,28 +1427,16 @@ and parse_record_pattern_row p =
14021427 if Token. is_keyword p.token then (
14031428 match
14041429 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
14081431 with
14091432 | Some (recovered_field_name , loc ) ->
14101433 Parser. expect Colon p;
14111434 let optional = parse_optional_label p in
14121435 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
14161437 Some (false , PatField {lid = field; x = pat; opt = optional})
14171438 | 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;
14271440 None )
14281441 else None
14291442
@@ -2974,10 +2987,7 @@ and parse_braced_or_record_expr p =
29742987 | token when Token. is_keyword token -> (
29752988 match
29762989 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
29812991 with
29822992 | Some (recovered_field_name , loc ) ->
29832993 Parser. expect Colon p;
@@ -3314,30 +3324,16 @@ and parse_record_expr_row p :
33143324 if Token. is_keyword p.token then (
33153325 match
33163326 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
33213328 with
33223329 | Some (recovered_field_name , loc ) ->
33233330 Parser. expect Colon p;
33243331 let optional = parse_optional_label p in
33253332 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
33293334 Some {lid = field; x = field_expr; opt = optional}
33303335 | 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;
33413337 None )
33423338 else None
33433339
@@ -4839,12 +4835,7 @@ and parse_field_declaration_region ?current_type_name_path ?inline_types_context
48394835 if Token. is_keyword p.token then (
48404836 match
48414837 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
48484839 with
48494840 | Some (recovered_field_name , name_loc ) ->
48504841 let optional = parse_optional_label p in
@@ -4856,18 +4847,7 @@ and parse_field_declaration_region ?current_type_name_path ?inline_types_context
48564847 let name = Location. mkloc recovered_field_name name_loc in
48574848 Some (Ast_helper.Type. field ~attrs ~loc ~mut ~optional name typ)
48584849 | 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;
48714851 None )
48724852 else (
48734853 if attrs <> [] then
0 commit comments