@@ -57,6 +57,7 @@ type error =
5757 | Duplicated_bs_as
5858 | InvalidVariantTagAnnotation
5959 | InvalidUntaggedVariantDefinition of untagged_error
60+ | TagFieldNameConflict of string * string
6061exception Error of Location .t * error
6162
6263let report_error ppf =
@@ -90,6 +91,11 @@ let report_error ppf =
9091 | DuplicateLiteral s -> " Duplicate literal " ^ s ^ " ."
9192 | ConstructorMoreThanOneArg name ->
9293 " Constructor " ^ name ^ " has more than one argument." )
94+ | TagFieldNameConflict (constructor_name , field_name ) ->
95+ fprintf ppf
96+ " Constructor %s: the @tag name \" %s\" conflicts with inline record field \" %s\" . \
97+ Use a different @tag name or rename the field."
98+ constructor_name field_name field_name
9399
94100(* Type of the runtime representation of an untagged block (case with payoad) *)
95101type block_type =
@@ -462,12 +468,27 @@ let names_from_type_variant ?(is_untagged_def = false) ~env
462468 let blocks = Ext_array. reverse_of_list blocks in
463469 Some {consts; blocks}
464470
471+ let check_tag_field_conflicts (cstrs : Types.constructor_declaration list ) =
472+ List. iter (fun (cstr : Types.constructor_declaration ) ->
473+ match process_tag_name cstr.cd_attributes with
474+ | Some tag_name -> (
475+ match cstr.cd_args with
476+ | Cstr_record fields ->
477+ List. iter (fun (field : Types.label_declaration ) ->
478+ if Ident. name field.ld_id = tag_name then
479+ raise (Error (cstr.cd_loc, TagFieldNameConflict (Ident. name cstr.cd_id, tag_name)))
480+ ) fields
481+ | _ -> () )
482+ | None -> ()
483+ ) cstrs
484+
465485type well_formedness_check = {
466486 is_untagged_def : bool ;
467487 cstrs : Types .constructor_declaration list ;
468488}
469489
470490let check_well_formed ~env {is_untagged_def; cstrs} =
491+ check_tag_field_conflicts cstrs;
471492 ignore (names_from_type_variant ~env ~is_untagged_def cstrs)
472493
473494let has_undefined_literal attrs = process_tag_type attrs = Some Undefined
0 commit comments