Skip to content

Commit

Permalink
improve error message for duplicate labels (#6415)
Browse files Browse the repository at this point in the history
  • Loading branch information
zth authored Sep 27, 2023
1 parent f755a1c commit ccea327
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

We've found a bug for you!
/.../fixtures/duplicate_labels_error.res:3:3-6

1 │ type rcrd = {
2 │ name: string,
3 │ name: int,
4 │ }
5 │

The field name is defined several times in the record rcrd. Fields can only be added once to a record.
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@
5 │ type t3 = {...t, ...t2}
6 │

Two labels are named x
The field x is defined several times in the record t3. Fields can only be added once to a record.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
type rcrd = {
name: string,
name: int,
}
18 changes: 10 additions & 8 deletions jscomp/ml/typedecl.ml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type native_repr_kind = Unboxed | Untagged
type error =
Repeated_parameter
| Duplicate_constructor of string
| Duplicate_label of string
| Duplicate_label of string * string option
| Recursive_abbrev of string
| Cycle_in_def of string * type_expr
| Definition_mismatch of type_expr * Includecore.type_mismatch list
Expand Down Expand Up @@ -207,17 +207,17 @@ let make_params env params =
in
List.map make_param params

let transl_labels env closed lbls =
let transl_labels ?recordName env closed lbls =
if !Config.bs_only then
match !Builtin_attributes.check_duplicated_labels lbls with
| None -> ()
| Some {loc;txt=name} -> raise (Error(loc,Duplicate_label name))
| Some {loc;txt=name} -> raise (Error(loc,Duplicate_label (name, recordName)))
else (
let all_labels = ref StringSet.empty in
List.iter
(fun {pld_name = {txt=name; loc}} ->
if StringSet.mem name !all_labels then
raise(Error(loc, Duplicate_label name));
raise(Error(loc, Duplicate_label (name, recordName)));
all_labels := StringSet.add name !all_labels)
lbls);
let mk {pld_name=name;pld_mutable=mut;pld_type=arg;pld_loc=loc;
Expand Down Expand Up @@ -501,7 +501,7 @@ let transl_declaration ~typeRecordAsObject env sdecl id =
{typ with ptyp_desc = Ptyp_constr ({txt = Lident "option"; loc=typ.ptyp_loc}, [typ])}
else typ in
{lbl with pld_type = typ }) in
let lbls, lbls' = transl_labels env true lbls in
let lbls, lbls' = transl_labels ~recordName:(sdecl.ptype_name.txt) env true lbls in
let lbls_opt = match Record_type_spread.has_type_spread lbls with
| true ->
let rec extract t = match t.desc with
Expand Down Expand Up @@ -545,7 +545,7 @@ let transl_declaration ~typeRecordAsObject env sdecl id =
| [] -> ()
| lbl::rest ->
let name = lbl.ld_id.name in
if StringSet.mem name seen then raise(Error(loc, Duplicate_label name));
if StringSet.mem name seen then raise(Error(loc, Duplicate_label (name, Some sdecl.ptype_name.txt)));
check_duplicates loc rest (StringSet.add name seen) in
(match lbls_opt with
| Some (lbls, lbls') ->
Expand Down Expand Up @@ -1998,8 +1998,10 @@ let report_error ppf = function
fprintf ppf "A type parameter occurs several times"
| Duplicate_constructor s ->
fprintf ppf "Two constructors are named %s" s
| Duplicate_label s ->
fprintf ppf "Two labels are named %s" s
| Duplicate_label (s, None) ->
fprintf ppf "The field @{<info>%s@} is defined several times in this record. Fields can only be added once to a record." s
| Duplicate_label (s, Some recordName) ->
fprintf ppf "The field @{<info>%s@} is defined several times in the record @{<info>%s@}. Fields can only be added once to a record." s recordName
| Recursive_abbrev s ->
fprintf ppf "The type abbreviation %s is cyclic" s
| Cycle_in_def (s, ty) ->
Expand Down

0 comments on commit ccea327

Please sign in to comment.