Skip to content

Commit 40d5e14

Browse files
committed
Clarify tag/as conflict error message by using field name from type instead of only showing runtime name
1 parent 5c5f2bd commit 40d5e14

File tree

3 files changed

+18
-15
lines changed

3 files changed

+18
-15
lines changed

compiler/ml/ast_untagged_variants.ml

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ type error =
5757
| Duplicated_bs_as
5858
| InvalidVariantTagAnnotation
5959
| InvalidUntaggedVariantDefinition of untagged_error
60-
| TagFieldNameConflict of string * string
60+
| TagFieldNameConflict of string * string * string
6161
exception Error of Location.t * error
6262

6363
let report_error ppf =
@@ -91,11 +91,12 @@ let report_error ppf =
9191
| DuplicateLiteral s -> "Duplicate literal " ^ s ^ "."
9292
| ConstructorMoreThanOneArg name ->
9393
"Constructor " ^ name ^ " has more than one argument.")
94-
| TagFieldNameConflict (constructor_name, field_name) ->
94+
| TagFieldNameConflict (constructor_name, field_name, runtime_value) ->
9595
fprintf ppf
96-
"Constructor %s: the @tag name \"%s\" conflicts with inline record field \
97-
\"%s\". Use a different @tag name or rename the field."
98-
constructor_name field_name field_name
96+
"Constructor %s: the @tag name \"%s\" conflicts with the runtime value \
97+
of inline record field \"%s\". Use a different @tag name or rename the \
98+
field."
99+
constructor_name runtime_value field_name
99100

100101
(* Type of the runtime representation of an untagged block (case with payoad) *)
101102
type block_type =
@@ -471,28 +472,30 @@ let names_from_type_variant ?(is_untagged_def = false) ~env
471472
let check_tag_field_conflicts (cstrs : Types.constructor_declaration list) =
472473
List.iter
473474
(fun (cstr : Types.constructor_declaration) ->
474-
(* Get the effective tag name - either explicit @tag or constructor name *)
475-
let tag_name =
475+
let constructor_name = Ident.name cstr.cd_id in
476+
let effective_tag_name =
476477
match process_tag_name cstr.cd_attributes with
477478
| Some explicit_tag -> explicit_tag
478-
| None -> Ident.name cstr.cd_id (* Default to constructor name *)
479+
| None -> constructor_name
479480
in
480481
match cstr.cd_args with
481482
| Cstr_record fields ->
482483
List.iter
483484
(fun (field : Types.label_declaration) ->
484-
(* Get the effective field name in JavaScript output *)
485+
let field_name = Ident.name field.ld_id in
485486
let effective_field_name =
486487
match process_tag_type field.ld_attributes with
487-
| Some (String as_name) -> as_name (* Use @as name if present *)
488-
| _ -> Ident.name field.ld_id (* Otherwise use field name *)
488+
| Some (String as_name) -> as_name
489+
(* @as payload types other than string have no effect on record fields *)
490+
| Some _ | None -> field_name
489491
in
490492
(* Check if effective field name conflicts with tag *)
491-
if effective_field_name = tag_name then
493+
if effective_field_name = effective_tag_name then
492494
raise
493495
(Error
494496
( cstr.cd_loc,
495-
TagFieldNameConflict (Ident.name cstr.cd_id, tag_name) )))
497+
TagFieldNameConflict
498+
(constructor_name, field_name, effective_field_name) )))
496499
fields
497500
| _ -> ())
498501
cstrs

tests/build_tests/super_errors/expected/variant_tag_overlaps_with_field.res.expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@
77
3 │
88
4 │ let cat = Cat({name: "my cat"})
99

10-
Constructor Cat: the @tag name "name" conflicts with inline record field "name". Use a different @tag name or rename the field.
10+
Constructor Cat: the @tag name "name" conflicts with the runtime value of inline record field "name". Use a different @tag name or rename the field.

tests/build_tests/super_errors/expected/variant_tag_overlaps_with_field_as.res.expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@
77
3 │
88
4 │ let cat = Cat({catName: "my cat"})
99

10-
Constructor Cat: the @tag name "name" conflicts with inline record field "name". Use a different @tag name or rename the field.
10+
Constructor Cat: the @tag name "name" conflicts with the runtime value of inline record field "catName". Use a different @tag name or rename the field.

0 commit comments

Comments
 (0)