diff --git a/CHANGELOG.md b/CHANGELOG.md index a020c478be..90105deae9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ - Fix broken formatting in uncurried mode for functions with _ placeholder args. https://github.com/rescript-lang/rescript-compiler/pull/6148 - Fix issue where spreading record types with optional labels would not have their labels preserved as optional. https://github.com/rescript-lang/rescript-compiler/pull/6154 +- Fix error location to be the type with the spreads when spreading record types with duplicate labels. https://github.com/rescript-lang/rescript-compiler/pull/6157 # 11.0.0-alpha.3 diff --git a/jscomp/build_tests/super_errors/expected/record_type_spreads.res.expected b/jscomp/build_tests/super_errors/expected/record_type_spreads.res.expected new file mode 100644 index 0000000000..e1685b75c5 --- /dev/null +++ b/jscomp/build_tests/super_errors/expected/record_type_spreads.res.expected @@ -0,0 +1,10 @@ + + We've found a bug for you! + /.../fixtures/record_type_spreads.res:5:1-23 + + 3 │ type t2 = {x: string, y: float} + 4 │ + 5 │ type t3 = {...t, ...t2} + 6 │ + + Two labels are named x \ No newline at end of file diff --git a/jscomp/build_tests/super_errors/fixtures/record_type_spreads.res b/jscomp/build_tests/super_errors/fixtures/record_type_spreads.res new file mode 100644 index 0000000000..7f0a675600 --- /dev/null +++ b/jscomp/build_tests/super_errors/fixtures/record_type_spreads.res @@ -0,0 +1,5 @@ +type t = {x: int, y: string} + +type t2 = {x: string, y: float} + +type t3 = {...t, ...t2} diff --git a/jscomp/ml/typedecl.ml b/jscomp/ml/typedecl.ml index b1cd3190e1..e564840266 100644 --- a/jscomp/ml/typedecl.ml +++ b/jscomp/ml/typedecl.ml @@ -463,15 +463,15 @@ let transl_declaration ~typeRecordAsObject env sdecl id = in process_lbls ([], []) lbls lbls' | _ -> Some (lbls, lbls') in - let rec check_duplicates (lbls : Typedtree.label_declaration list) seen = match lbls with + let rec check_duplicates loc (lbls : Typedtree.label_declaration list) seen = match lbls with | [] -> () | lbl::rest -> let name = lbl.ld_id.name in - if StringSet.mem name seen then raise(Error(lbl.ld_loc, Duplicate_label name)); - check_duplicates rest (StringSet.add name seen) in + if StringSet.mem name seen then raise(Error(loc, Duplicate_label name)); + check_duplicates loc rest (StringSet.add name seen) in (match lbls_opt with | Some (lbls, lbls') -> - check_duplicates lbls StringSet.empty; + check_duplicates sdecl.ptype_loc lbls StringSet.empty; let optionalLabels = Ext_list.filter_map lbls (fun lbl -> if has_optional lbl.ld_attributes then Some lbl.ld_name.txt else None)