From 5de3a96a40deba8a9013a7a021a925e97e9a2e95 Mon Sep 17 00:00:00 2001 From: Christoph Knittel Date: Fri, 30 Oct 2026 11:40:50 +0000 Subject: [PATCH 1/4] Show signature mismatches as the actual and expected declaration, each under its location MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Why: A signature mismatch printed every enclosing module in full, then the two declarations, then their locations as "file:line:" lines with a label on the next line that read like headings with nothing under them, and the reasons without a break. Which text was where had to be matched up by hand, and declarations that read the same looked like a declaration not including itself. The type checker's errors separate their parts with blank lines and indent the content under a lead-in. Includemod.report_error now leaves out a module or module type comparison when an item inside it follows, so that only the items that differ are printed, each after a line naming where it is: "In module P:", "In module type P.T:", "In the result of functor P:", "In the parameter X of functor P:", or "At position ..." otherwise, once for items at the same position. Missing items are listed in the order of the expected signature, and in a functor's parameter, where inclusion is reversed, the implementation's side is still the actual declaration. Diagnostic modified (type declaration in an interface): Example: // Foo.res type t = {a: int, b: int} // Foo.resi type t = {x: int, y: int} Before (diagnostic): The implementation Foo.res does not match the interface foo.cmi: Type declarations do not match: type t = {a: int, b: int} is not included in type t = {x: int, y: int} Foo.resi:1:1-25: Expected declaration Foo.res:1:1-25: Actual declaration Fields number 1 have different names, a and x. After (diagnostic): The implementation Foo.res does not match the interface foo.cmi: Actual declaration (Foo.res:1:1-25): type t = {a: int, b: int} Expected declaration (Foo.resi:1:1-25): type t = {x: int, y: int} Fields number 1 have different names, a and x. Diagnostic modified (value in a nested module): Example: // Foo.res module Inner = { let value = "not an int" } // Foo.resi module Inner: { let value: int } Before (diagnostic): In module Inner: Modules do not match: { let value: string } is not included in { let value: int } In module Inner: Values do not match: let value: string is not included in let value: int Foo.resi:2:3-16: Expected declaration Foo.res:2:7-11: Actual declaration After (diagnostic): In module Inner: Actual declaration (Foo.res:2:7-11): let value: string Expected declaration (Foo.resi:2:3-16): let value: int Diagnostic modified (functor result): Example: module type S = { type t } module M: { module F: (X: S) => S with type t = X.t } = { module F = (X: S) => { type t = int } } Before (diagnostic): Signature mismatch: Modules do not match: … In module F: Modules do not match: … At position module F: (X) => Modules do not match: … At position module F: (X) => Type declarations do not match: type t = int is not included in type t = X.t functor_signature_mismatch.res:6:36: Expected declaration functor_signature_mismatch.res:9:5-16: Actual declaration After (diagnostic): Signature mismatch: In the result of functor F: Actual declaration (functor_signature_mismatch.res:9:5-16): type t = int Expected declaration (functor_signature_mismatch.res:6:36): type t = X.t Diagnostic modified (functor parameter): Example: module M: { module F: (X: {let a: int}) => {} } = { module F = (X: {let a: string}) => {} } Before (diagnostic): Signature mismatch: Modules do not match: … the module, then the functor, each pair printed in full At position module F: (X: ) => ... Values do not match: let a: int is not included in let a: string inclusion_layout_functor_parameter.res:12:7-19: Expected declaration inclusion_layout_functor_parameter.res:6:7-16: Actual declaration After (diagnostic): In the parameter X of functor F: Actual declaration (inclusion_layout_functor_parameter.res:12:7-19): let a: string Expected declaration (inclusion_layout_functor_parameter.res:6:7-16): let a: int Diagnostic modified (missing values): Example: module M: { module N: { let a: int let b: string } } = { module N = {} } Before (diagnostic): Signature mismatch: Modules do not match: … the module, then module N, each pair printed in full In module N: The value `b` is required but not provided inclusion_layout_missing_values.res:5:5-17: Expected declaration In module N: The value `a` is required but not provided inclusion_layout_missing_values.res:4:5-14: Expected declaration After (diagnostic): In module N: The value `a` is required but not provided. Expected declaration (inclusion_layout_missing_values.res:4:5-14): let a: int The value `b` is required but not provided. Expected declaration (inclusion_layout_missing_values.res:5:5-17): let b: string Diagnostic modified (runtime representation reason): Before (diagnostic): Their runtime representations differ: the first declaration states values whose typeof is "object", the second declaration states values whose typeof is "string". After (diagnostic): Their runtime representations differ: The actual declaration states values whose typeof is "object". The expected declaration states values whose typeof is "string". Subst.extension_constructor dropped the location of an extension constructor when writing a .cmi, unlike every other declaration. It keeps it now, so the expected side of an extension mismatch has a position, and reanalyze also records a reference to an exception declared in an interface. Diagnostic modified (extension constructor declared in an interface): Example: // Foo.res type t += Boom(string) // Foo.resi type t += Boom(int) Before (diagnostic): Foo.res: Expected declaration After (diagnostic): Expected declaration (Foo.resi:4:3-13): type t += Boom(int) Review: Is anything dropped that was useful? The enclosing modules printed in full repeated the items below them; the path line names where the items are. A big part was printed as "..." for the same reason, so the size check is gone. Review: Why "actual" and "expected" and not "implementation" and "interface"? The same errors are reported for module type constraints and functor arguments within one file, where there is no interface. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Kbf3gLpf7RN1MiRcubPgRn Signed-off-by: Christoph Knittel --- changes/signature-mismatch-layout.polish.md | 2 + compiler/ml/includecore.ml | 23 +- compiler/ml/includemod.ml | 215 ++++++++++-------- compiler/ml/includemod.mli | 3 +- compiler/ml/subst.ml | 2 +- compiler/ml/typemod.ml | 10 +- .../deadcode/expected/deadcode.txt | 2 + .../expected/OptionalImplIntf.res.expected | 19 +- .../OptionalInlineImplIntf.res.expected | 19 +- .../expected/RecordInclusion.res.expected | 12 +- .../expected/UntaggedImplIntf.res.expected | 21 +- .../functor_apply_arg_mismatch.res.expected | 14 +- .../functor_signature_mismatch.res.expected | 45 +--- ...onstructor_signature_mismatch.res.expected | 12 +- ...tension_constructors_mismatch.res.expected | 22 +- .../include_missing_field.res.expected | 17 +- ...nclude_modtype_infos_mismatch.res.expected | 43 +--- .../include_modtype_permutation.res.expected | 28 +-- ...include_module_types_mismatch.res.expected | 27 +-- .../include_type_decl_mismatch.res.expected | 20 +- .../include_value_type_mismatch.res.expected | 19 +- ...sion_layout_functor_parameter.res.expected | 22 ++ ...clusion_layout_missing_values.res.expected | 24 ++ .../inclusion_layout_module_kind.res.expected | 30 +++ ...ion_layout_nested_module_type.res.expected | 22 ++ ...ine_bigint_signature_mismatch.res.expected | 22 +- ...dule_sig_value_arity_mismatch.res.expected | 21 +- ...ig_value_arity_mismatch_alias.res.expected | 21 +- ...g_value_arity_mismatch_nested.res.expected | 21 +- ..._value_arity_mismatch_reverse.res.expected | 21 +- ...ot_undefined_functor_argument.res.expected | 23 +- ...t_undefined_functor_parameter.res.expected | 24 +- .../object_manifest_set_mismatch.res.expected | 20 +- ...object_private_row_grants_set.res.expected | 20 +- ..._value_signature_set_mismatch.res.expected | 20 +- ...otation_interface_over_record.res.expected | 24 +- ..._decl_function_arity_mismatch.res.expected | 20 +- .../variant_payload_tag_mismatch.res.expected | 12 +- .../expected/with_mismatch.res.expected | 12 +- .../inclusion_layout_functor_parameter.res | 15 ++ .../inclusion_layout_missing_values.res | 9 + .../fixtures/inclusion_layout_module_kind.res | 15 ++ .../inclusion_layout_nested_module_type.res | 14 ++ .../Cross_external_import_attrs.expected | 12 +- .../Cross_external_payload_name.expected | 12 +- .../Cross_external_spec_mismatch.expected | 12 +- ...t_undefined_option_implementation.expected | 15 +- ...oss_private_abbreviation_mismatch.expected | 12 +- ...private_variant_manifest_mismatch.expected | 12 +- ...e_annotation_claimed_by_interface.expected | 15 +- ...ntime_annotation_functor_argument.expected | 16 +- ...ss_runtime_annotation_hidden_base.expected | 15 +- ...time_annotation_hidden_superclass.expected | 15 +- .../Iface_constraint_mismatch.expected | 13 +- .../Iface_extension_constructors.expected | 12 +- .../Iface_field_arity_mismatch.expected | 11 +- .../Iface_field_mutable_mismatch.expected | 11 +- .../Iface_field_names_mismatch.expected | 11 +- .../Iface_field_optional_mismatch.expected | 11 +- .../Iface_immediate_mismatch.expected | 13 +- .../expected/Iface_kind_mismatch.expected | 11 +- .../expected/Iface_manifest_mismatch.expected | 12 +- .../expected/Iface_missing_value.expected | 8 +- .../expected/Iface_modtype_infos.expected | 31 +-- .../expected/Iface_module_types.expected | 21 +- .../expected/Iface_privacy_mismatch.expected | 11 +- ...ce_record_representation_mismatch.expected | 13 +- .../expected/Iface_tag_name_mismatch.expected | 11 +- .../expected/Iface_type_decl_record.expected | 11 +- .../expected/Iface_type_decl_variant.expected | 11 +- .../Iface_unboxed_variant_mismatch.expected | 13 +- .../Iface_value_arity_mismatch.expected | 13 +- .../Iface_value_descriptions.expected | 12 +- .../expected/Iface_variance_mismatch.expected | 11 +- .../Iface_variant_extra_constructor.expected | 13 +- ...e_variant_representation_mismatch.expected | 11 +- .../Smoke_interface_mismatch.expected | 11 +- 77 files changed, 652 insertions(+), 797 deletions(-) create mode 100644 changes/signature-mismatch-layout.polish.md create mode 100644 tests/build_tests/super_errors/expected/inclusion_layout_functor_parameter.res.expected create mode 100644 tests/build_tests/super_errors/expected/inclusion_layout_missing_values.res.expected create mode 100644 tests/build_tests/super_errors/expected/inclusion_layout_module_kind.res.expected create mode 100644 tests/build_tests/super_errors/expected/inclusion_layout_nested_module_type.res.expected create mode 100644 tests/build_tests/super_errors/fixtures/inclusion_layout_functor_parameter.res create mode 100644 tests/build_tests/super_errors/fixtures/inclusion_layout_missing_values.res create mode 100644 tests/build_tests/super_errors/fixtures/inclusion_layout_module_kind.res create mode 100644 tests/build_tests/super_errors/fixtures/inclusion_layout_nested_module_type.res diff --git a/changes/signature-mismatch-layout.polish.md b/changes/signature-mismatch-layout.polish.md new file mode 100644 index 00000000000..045431d14d5 --- /dev/null +++ b/changes/signature-mismatch-layout.polish.md @@ -0,0 +1,2 @@ +- Show a signature mismatch as the actual and the expected declaration, each under its location, with only the items that differ and the module path to them. +- Keep the location of an extension constructor or exception declared in an interface, so that errors and reanalyze point to it. diff --git a/compiler/ml/includecore.ml b/compiler/ml/includecore.ml index 99414e90784..62526016a0f 100644 --- a/compiler/ml/includecore.ml +++ b/compiler/ml/includecore.ml @@ -225,22 +225,29 @@ let report_type_mismatch0 first second decl ppf err = | Record_representation (_rep1, _rep2) -> pr "Their internal representations differ" | Unboxed_representation b -> - pr "Their internal representations differ:@ %s %s %s" - (if b then second else first) + pr "@[Their internal representations differ:@,%s %s %s@]" + (String.capitalize_ascii (if b then second else first)) decl "uses unboxed representation" - | Immediate -> pr "%s is not an immediate type" first + | Immediate -> pr "%s %s is not an immediate type" first decl | Tag_name -> pr "Their @tag annotations differ" | Variant_representation s -> pr "The internal representations for case %s are not equal" (Ident.name s) | Not_undefined -> pr - "Their runtime representations differ:@ %s %s is @notUndefined,@ but %s \ - %s can hold undefined" - second decl first decl + "@[Their runtime representations differ:@,\ + %s %s is @notUndefined,@,\ + but %s %s can hold undefined@]" + (String.capitalize_ascii second) + decl first decl | Runtime_annotation (declared1, declared2) -> pr - "Their runtime representations differ:@ %s %s states %s,@ %s %s states %s" - first decl declared1 second decl declared2 + "@[Their runtime representations differ:@,\ + %s %s states %s.@,\ + %s %s states %s@]" + (String.capitalize_ascii first) + decl declared1 + (String.capitalize_ascii second) + decl declared2 let report_type_mismatch first second decl ppf = List.iter (fun err -> diff --git a/compiler/ml/includemod.ml b/compiler/ml/includemod.ml index e3f7fcc5682..79a5d8d326d 100644 --- a/compiler/ml/includemod.ml +++ b/compiler/ml/includemod.ml @@ -20,7 +20,8 @@ open Typedtree open Types type symptom = - | Missing_field of Ident.t * Location.t * string (* kind *) + | Missing_field of Ident.t * Location.t * string * signature_item + (** The name, location, kind and declaration of an expected item *) | Value_descriptions of Ident.t * value_description * value_description | Type_declarations of Ident.t @@ -331,7 +332,8 @@ and signatures ~loc env cxt subst sig1 sig2 = (* see PR#5098 *) simplify_structure_coercion cc id_pos_list runtime_fields else Tcoerce_structure (cc, id_pos_list, runtime_fields) - | _ -> raise (Error unpaired)) + (* In the order of the expected signature *) + | _ -> raise (Error (List.rev unpaired))) | item2 :: rem -> ( let id2, loc, name2 = item_ident_name item2 in let name2, report = @@ -357,7 +359,7 @@ and signatures ~loc env cxt subst sig1 sig2 = | exception Not_found -> let unpaired = if report then - (cxt, env, Missing_field (id2, loc, kind_of_field_desc name2)) + (cxt, env, Missing_field (id2, loc, kind_of_field_desc name2, item2)) :: unpaired else unpaired in @@ -485,12 +487,21 @@ let modtypes env m1 m2 = open Format open Printtyp -let show_loc msg ppf loc = - fprintf ppf "@\n@[<2>%a:@ %s@]" Location.print_loc loc msg +(* A declaration under a label naming its side and its location *) +let show_declaration label loc pp ppf x = + fprintf ppf "@[%s (%a):@,%a@]" label Location.print_loc loc pp x -let show_locs ppf (loc1, loc2) = - show_loc "Expected declaration" ppf loc2; - show_loc "Actual declaration" ppf loc1 +(* [x1] is included in [x2]. In a functor's parameter, where inclusion goes + the other way, [swapped] is true and [x2] is the actual declaration. *) +let show_declarations ~swapped pp ppf (x1, loc1, x2, loc2) = + let (actual, actual_loc), (expected, expected_loc) = + if swapped then ((x2, loc2), (x1, loc1)) else ((x1, loc1), (x2, loc2)) + in + fprintf ppf "%a@,@,%a" + (show_declaration "Actual declaration" actual_loc pp) + actual + (show_declaration "Expected declaration" expected_loc pp) + expected let find_arity_mismatch env ty1 ty2 = let rec loop seen ty1 ty2 = @@ -535,47 +546,50 @@ let show_arity_mismatch env ppf (d1 : value_description) if n = 1 then "1 argument" else string_of_int n ^ " arguments" in fprintf ppf - "@\n\ + "@,\ + @,\ @[The implementation contains a function taking %s where the interface \ expects one taking %s.@]" (args n1) (args n2) | _ -> () -let include_symptom env ppf = function - | Missing_field (id, loc, kind) -> - fprintf ppf "The %s `%a` is required but not provided" kind ident id; - show_loc "Expected declaration" ppf loc +let include_symptom ~swapped env ppf = function + | Missing_field (id, loc, kind, item) -> + fprintf ppf "The %s `%a` is required but not provided.@,@,%a" kind ident id + (show_declaration + (if swapped then "Actual declaration" else "Expected declaration") + loc signature) + [item] | Value_descriptions (id, d1, d2) -> - fprintf ppf - "@[Values do not match:@ %a@;<1 -2>is not included in@ %a@]" - (value_description id) d1 (value_description id) d2; - show_arity_mismatch env ppf d1 d2; - show_locs ppf (d1.val_loc, d2.val_loc) + show_declarations ~swapped (value_description id) ppf + (d1, d1.val_loc, d2, d2.val_loc); + if swapped then show_arity_mismatch env ppf d2 d1 + else show_arity_mismatch env ppf d1 d2 | Type_declarations (id, d1, d2, errs) -> - fprintf ppf "@[@[%s:@;<1 2>%a@ %s@;<1 2>%a@]%a%a@]" - "Type declarations do not match" (type_declaration id) d1 - "is not included in" (type_declaration id) d2 show_locs - (d1.type_loc, d2.type_loc) - (Includecore.report_type_mismatch "the first" "the second" "declaration") - errs + show_declarations ~swapped (type_declaration id) ppf + (d1, d1.type_loc, d2, d2.type_loc); + if List.exists (fun err -> err <> Includecore.Manifest) errs then + let first, second = + if swapped then ("the expected", "the actual") + else ("the actual", "the expected") + in + fprintf ppf "@,%a" + (Includecore.report_type_mismatch first second "declaration") + errs | Extension_constructors (id, x1, x2) -> - fprintf ppf - "@[Extension declarations do not match:@ %a@;\ - <1 -2>is not included in@ %a@]" - (extension_constructor id) x1 (extension_constructor id) x2; - show_locs ppf (x1.ext_loc, x2.ext_loc) + show_declarations ~swapped (extension_constructor id) ppf + (x1, x1.ext_loc, x2, x2.ext_loc) | Module_types (mty1, mty2) -> + let actual, expected = if swapped then (mty2, mty1) else (mty1, mty2) in fprintf ppf - "@[Modules do not match:@ %a@;<1 -2>is not included in@ %a@]" - modtype mty1 modtype mty2 + "@[Actual module type:@,%a@]@,@,@[Expected module type:@,%a@]" + modtype actual modtype expected | Modtype_infos (id, d1, d2) -> - fprintf ppf - "@[Module type declarations do not match:@ %a@;\ - <1 -2>does not match@ %a@]" - (modtype_declaration id) d1 (modtype_declaration id) d2 + show_declarations ~swapped (modtype_declaration id) ppf + (d1, d1.mtd_loc, d2, d2.mtd_loc) | Modtype_permutation -> fprintf ppf "Illegal permutation of structure fields" | Interface_mismatch (impl_name, intf_name) -> - fprintf ppf "@[The implementation %s@ does not match the interface %s:" + fprintf ppf "@[The implementation %s@ does not match the interface %s:@]" impl_name intf_name | Unbound_modtype_path path -> fprintf ppf "Unbound module type %a" Printtyp.path path @@ -603,75 +617,84 @@ and argname x = let s = Ident.name x in if s = "*" then "" else s -let path_of_context = function +(* The path of the modules a context goes through, outermost first *) +let path_of_modules = function | Module id :: rem -> let rec subm path = function - | [] -> path + | [] -> Some path | Module id :: rem -> subm (Pdot (path, Ident.name id, -1)) rem - | _ -> assert false + | (Modtype _ | Arg _ | Body _) :: _ -> None in subm (Pident id) rem - | _ -> assert false + | (Modtype _ | Arg _ | Body _) :: _ | [] -> None +(* Where in the module an error is, as a line before it. [cxt] is outermost + first. A module type or a functor's result at the end of a module path is + named in words; any other position is shown as a module type with . *) let context ppf cxt = + let split_last l = + match List.rev l with + | last :: rev_init -> Some (List.rev rev_init, last) + | [] -> None + in if cxt = [] then () - else if - List.for_all - (function - | Module _ -> true - | _ -> false) - cxt - then fprintf ppf "In module %a:@ " path (path_of_context cxt) - else fprintf ppf "@[At position@ %a@]@ " context cxt - -let include_err ppf (cxt, env, err) = - Printtyp.wrap_printing_env env (fun () -> - fprintf ppf "@[%a%a@]" context (List.rev cxt) (include_symptom env) err) - -let error_size = 400 (* in heap words *) - -(* An error part is big when its heap representation exceeds - [error_size] words. Each distinct reachable block counts its header - and fields; a block without scannable fields (string, float, custom) or a - closure counts its header only. String contents are excluded so that the - decision is independent of source file names stored in locations. The walk - stops as soon as the limit is exceeded, which bounds the visited list. *) -let is_big obj = - let size = ref 0 in - let visited = ref [] in - let exception Big in - let rec walk (o : Obj.t) = - if Obj.is_block o && not (List.memq o !visited) then ( - visited := o :: !visited; - let tag = Obj.tag o in - let scan = - tag < Obj.no_scan_tag && tag <> Obj.closure_tag && tag <> Obj.infix_tag - in - size := !size + if scan then 1 + Obj.size o else 1; - if !size > error_size then raise_notrace Big; - if scan then - for i = 0 to Obj.size o - 1 do - walk (Obj.field o i) - done) + else + match (path_of_modules cxt, split_last cxt) with + | Some p, _ -> fprintf ppf "In module %a:@,@," path p + | None, Some ([], Modtype id) -> + fprintf ppf "In module type %a:@,@," ident id + | None, Some (modules, Modtype id) -> ( + match path_of_modules modules with + | Some p -> fprintf ppf "In module type %a.%a:@,@," path p ident id + | None -> fprintf ppf "@[At position@ %a@]@,@," context cxt) + | None, Some (modules, Body _) -> ( + match path_of_modules modules with + | Some p -> fprintf ppf "In the result of functor %a:@,@," path p + | None -> fprintf ppf "@[At position@ %a@]@,@," context cxt) + | None, Some (modules, Arg x) -> ( + match path_of_modules modules with + | Some p -> + fprintf ppf "In the parameter %a of functor %a:@,@," ident x path p + | None -> fprintf ppf "@[At position@ %a@]@,@," context cxt) + | None, _ -> fprintf ppf "@[At position@ %a@]@,@," context cxt + +let include_err ~show_context ppf (cxt, env, err) = + (* Inclusion is reversed in each functor parameter on the way *) + let swapped = + List.length + (List.filter + (function + | Arg _ -> true + | Module _ | Modtype _ | Body _ -> false) + cxt) + mod 2 + = 1 in - try - walk (Obj.repr obj); - false - with Big -> true - + Printtyp.wrap_printing_env env (fun () -> + fprintf ppf "@[%a%a@]" + (fun ppf cxt -> if show_context then context ppf cxt) + (List.rev cxt) + (include_symptom ~swapped env) + err) + +(* An error is a path of symptoms from the whole module down to the items that + differ. The modules on the way are left out, as the items at the end say + what differs, each under the position it is at. *) let report_error ppf errs = - if errs = [] then () - else - let errs, err = Ext_list.split_at_last errs in - let pe = ref true in - let include_err' ppf ((_, _, obj) as err) = - if not (is_big obj) then fprintf ppf "%a@ " include_err err - else if !pe then ( - fprintf ppf "...@ "; - pe := false) - in - let print_errs ppf = List.iter (include_err' ppf) in - fprintf ppf "@[%a%a@]" print_errs errs include_err err + let rec shown = function + | [] -> [] + | [err] -> [err] + | (_, _, (Module_types _ | Modtype_infos _)) :: rest -> shown rest + | err :: rest -> err :: shown rest + in + let rec print ppf previous_cxt = function + | [] -> () + | ((cxt, _, _) as err) :: rest -> + if previous_cxt <> None then fprintf ppf "@,@,"; + include_err ~show_context:(previous_cxt <> Some cxt) ppf err; + print ppf (Some cxt) rest + in + fprintf ppf "@[%a@]" (fun ppf errs -> print ppf None errs) (shown errs) let better_candidate_loc (x : error list) = match x with @@ -679,7 +702,7 @@ let better_candidate_loc (x : error list) = match descr with | Value_descriptions (_, d1, _) -> Some d1.val_loc | Type_declarations (_, tdcl1, _, _) -> Some tdcl1.type_loc - | Missing_field (_, loc, _) -> Some loc + | Missing_field (_, loc, _, _) -> Some loc | _ -> None) | _ -> None diff --git a/compiler/ml/includemod.mli b/compiler/ml/includemod.mli index 9399f2b63a9..83cf0765aa1 100644 --- a/compiler/ml/includemod.mli +++ b/compiler/ml/includemod.mli @@ -38,7 +38,8 @@ val type_declarations : val print_coercion : formatter -> module_coercion -> unit type symptom = - | Missing_field of Ident.t * Location.t * string (* kind *) + | Missing_field of Ident.t * Location.t * string * signature_item + (** The name, location, kind and declaration of an expected item *) | Value_descriptions of Ident.t * value_description * value_description | Type_declarations of Ident.t diff --git a/compiler/ml/subst.ml b/compiler/ml/subst.ml index ea599a6df96..ff62839a2bc 100644 --- a/compiler/ml/subst.ml +++ b/compiler/ml/subst.ml @@ -304,7 +304,7 @@ let extension_constructor s ext = ext_ret_type = may_map (typexp_rec s) ext.ext_ret_type; ext_private = ext.ext_private; ext_attributes = attrs s ext.ext_attributes; - ext_loc = (if s.for_saving then Location.none else ext.ext_loc); + ext_loc = loc s ext.ext_loc; ext_is_exception = ext.ext_is_exception; }) diff --git a/compiler/ml/typemod.ml b/compiler/ml/typemod.ml index 352e283c349..5f9fc41d15b 100644 --- a/compiler/ml/typemod.ml +++ b/compiler/ml/typemod.ml @@ -1858,7 +1858,7 @@ let report_error ppf = function | Cannot_apply mty -> fprintf ppf "@[This module is not a functor; it has type@ %a@]" modtype mty | Not_included errs -> - fprintf ppf "@[Signature mismatch:@ %a@]" Includemod.report_error errs + fprintf ppf "@[Signature mismatch:@,@,%a@]" Includemod.report_error errs | Cannot_eliminate_dependency mty -> fprintf ppf "@[This functor has type@ %a@ The parameter cannot be eliminated in the \ @@ -1874,12 +1874,16 @@ let report_error ppf = function | With_mismatch (lid, explanation) -> fprintf ppf "@[@[In this `with' constraint, the new definition of %a@ does not \ - match its original definition@ in the constrained signature:@]@ %a@]" + match its original definition@ in the constrained signature:@]@,\ + @,\ + %a@]" longident lid Includemod.report_error explanation | With_makes_applicative_functor_ill_typed (lid, path, explanation) -> fprintf ppf "@[@[This `with' constraint on %a makes the applicative functor @ \ - type %s ill-typed in the constrained signature:@]@ %a@]" + type %s ill-typed in the constrained signature:@]@,\ + @,\ + %a@]" longident lid (Path.name path) Includemod.report_error explanation | With_changes_module_alias (lid, id, path) -> fprintf ppf diff --git a/tests/analysis_tests/tests-reanalyze/deadcode/expected/deadcode.txt b/tests/analysis_tests/tests-reanalyze/deadcode/expected/deadcode.txt index 31a01159cde..19aa5046672 100644 --- a/tests/analysis_tests/tests-reanalyze/deadcode/expected/deadcode.txt +++ b/tests/analysis_tests/tests-reanalyze/deadcode/expected/deadcode.txt @@ -1463,6 +1463,8 @@ addDeclaration_ Value +test Shadow.res:11:6 path:+Shadow.M addDeclaration_ Value +test Shadow.res:9:6 path:+Shadow.M Scanning TestDeadExn.cmt Source:TestDeadExn.res + add_value_reference TestDeadExn.res:1:12 --> DeadExn.resi:2:0 + add_type_reference TestDeadExn.res:1:12 --> DeadExn.resi:2:0 Scanning TestEmitInnerModules.cmt Source:TestEmitInnerModules.res addDeclaration_ Value +x TestEmitInnerModules.res:3:6 path:+TestEmitInnerModules.Inner addDeclaration_ Value +y TestEmitInnerModules.res:5:6 path:+TestEmitInnerModules.Inner diff --git a/tests/build_tests/super_errors/expected/OptionalImplIntf.res.expected b/tests/build_tests/super_errors/expected/OptionalImplIntf.res.expected index fc2ba80ba75..26f6bde7240 100644 --- a/tests/build_tests/super_errors/expected/OptionalImplIntf.res.expected +++ b/tests/build_tests/super_errors/expected/OptionalImplIntf.res.expected @@ -10,20 +10,11 @@ 6 │ Signature mismatch: - Modules do not match: - { - type t = {x: int} - } - is not included in - { - type t = {x?: int} - } - Type declarations do not match: + + Actual declaration (/.../fixtures/OptionalImplIntf.res:4:3-19): type t = {x: int} - is not included in + + Expected declaration (/.../fixtures/OptionalImplIntf.res:2:3-20): type t = {x?: int} - /.../fixtures/OptionalImplIntf.res:2:3-20: - Expected declaration - /.../fixtures/OptionalImplIntf.res:4:3-19: - Actual declaration + The optional attribute of field x is different. \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/OptionalInlineImplIntf.res.expected b/tests/build_tests/super_errors/expected/OptionalInlineImplIntf.res.expected index 5cf4df5ff69..c3734353b54 100644 --- a/tests/build_tests/super_errors/expected/OptionalInlineImplIntf.res.expected +++ b/tests/build_tests/super_errors/expected/OptionalInlineImplIntf.res.expected @@ -10,20 +10,11 @@ 6 │ Signature mismatch: - Modules do not match: - { - type t = A({x: int}) - } - is not included in - { - type t = A({x?: int}) - } - Type declarations do not match: + + Actual declaration (/.../fixtures/OptionalInlineImplIntf.res:4:3-22): type t = A({x: int}) - is not included in + + Expected declaration (/.../fixtures/OptionalInlineImplIntf.res:2:3-23): type t = A({x?: int}) - /.../fixtures/OptionalInlineImplIntf.res:2:3-23: - Expected declaration - /.../fixtures/OptionalInlineImplIntf.res:4:3-22: - Actual declaration + The optional attribute of field x is different. \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/RecordInclusion.res.expected b/tests/build_tests/super_errors/expected/RecordInclusion.res.expected index 19232b76607..9729e2201ef 100644 --- a/tests/build_tests/super_errors/expected/RecordInclusion.res.expected +++ b/tests/build_tests/super_errors/expected/RecordInclusion.res.expected @@ -10,13 +10,11 @@ 6 │ Signature mismatch: - ... - Type declarations do not match: + + Actual declaration (/.../fixtures/RecordInclusion.res:4:3-58): type t<'a, 'b, 'c> = {x: int, y: list<('a, 'c)>, z: int} - is not included in + + Expected declaration (/.../fixtures/RecordInclusion.res:2:3-58): type t<'a, 'b, 'c> = {x: int, y: list<('a, 'b)>, z: int} - /.../fixtures/RecordInclusion.res:2:3-58: - Expected declaration - /.../fixtures/RecordInclusion.res:4:3-58: - Actual declaration + The types for field y are not equal. \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/UntaggedImplIntf.res.expected b/tests/build_tests/super_errors/expected/UntaggedImplIntf.res.expected index cd7098b36e9..f9dabbfdb34 100644 --- a/tests/build_tests/super_errors/expected/UntaggedImplIntf.res.expected +++ b/tests/build_tests/super_errors/expected/UntaggedImplIntf.res.expected @@ -10,21 +10,12 @@ 6 │ Signature mismatch: - Modules do not match: - { - type t = @as(null) A - } - is not included in - { - @unboxed type t = @as(null) A - } - Type declarations do not match: + + Actual declaration (/.../fixtures/UntaggedImplIntf.res:4:3-24): type t = @as(null) A - is not included in + + Expected declaration (/.../fixtures/UntaggedImplIntf.res:2:12-33): @unboxed type t = @as(null) A - /.../fixtures/UntaggedImplIntf.res:2:12-33: - Expected declaration - /.../fixtures/UntaggedImplIntf.res:4:3-24: - Actual declaration + Their internal representations differ: - the second declaration uses unboxed representation. \ No newline at end of file + The expected declaration uses unboxed representation. \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/functor_apply_arg_mismatch.res.expected b/tests/build_tests/super_errors/expected/functor_apply_arg_mismatch.res.expected index d027d93b243..18625c79b01 100644 --- a/tests/build_tests/super_errors/expected/functor_apply_arg_mismatch.res.expected +++ b/tests/build_tests/super_errors/expected/functor_apply_arg_mismatch.res.expected @@ -9,12 +9,8 @@ 15 │ Signature mismatch: - Modules do not match: - { - let unrelated: string - } - is not included in - HasFoo - The value `foo` is required but not provided - /.../fixtures/functor_apply_arg_mismatch.res:2:3-14: - Expected declaration \ No newline at end of file + + The value `foo` is required but not provided. + + Expected declaration (/.../fixtures/functor_apply_arg_mismatch.res:2:3-14): + let foo: int \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/functor_signature_mismatch.res.expected b/tests/build_tests/super_errors/expected/functor_signature_mismatch.res.expected index 1be12f852e9..d732eb3baa2 100644 --- a/tests/build_tests/super_errors/expected/functor_signature_mismatch.res.expected +++ b/tests/build_tests/super_errors/expected/functor_signature_mismatch.res.expected @@ -12,42 +12,11 @@ 12 │ Signature mismatch: - Modules do not match: - { - module F: (X: S) => { - type t = int - } - } - is not included in - { - module F: (X: S) => { - type t = X.t - } - } - In module F: - Modules do not match: - (X: S) => { - type t = int - } - is not included in - (X: S) => { - type t = X.t - } - At position module F: (X) => - Modules do not match: - { - type t = int - } - is not included in - { - type t = X.t - } - At position module F: (X) => - Type declarations do not match: + + In the result of functor F: + + Actual declaration (/.../fixtures/functor_signature_mismatch.res:9:5-16): type t = int - is not included in - type t = X.t - /.../fixtures/functor_signature_mismatch.res:6:36: - Expected declaration - /.../fixtures/functor_signature_mismatch.res:9:5-16: - Actual declaration \ No newline at end of file + + Expected declaration (/.../fixtures/functor_signature_mismatch.res:6:36): + type t = X.t \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/gadt_constructor_signature_mismatch.res.expected b/tests/build_tests/super_errors/expected/gadt_constructor_signature_mismatch.res.expected index e9edddbcf49..d67ba3eef30 100644 --- a/tests/build_tests/super_errors/expected/gadt_constructor_signature_mismatch.res.expected +++ b/tests/build_tests/super_errors/expected/gadt_constructor_signature_mismatch.res.expected @@ -10,13 +10,11 @@ 6 │ Signature mismatch: - ... - Type declarations do not match: + + Actual declaration (/.../fixtures/gadt_constructor_signature_mismatch.res:4:3-56): type t<_> = Int(int): t | Str(string): t - is not included in + + Expected declaration (/.../fixtures/gadt_constructor_signature_mismatch.res:2:3-59): type t<_> = Int(int): t | Str(string): t - /.../fixtures/gadt_constructor_signature_mismatch.res:2:3-59: - Expected declaration - /.../fixtures/gadt_constructor_signature_mismatch.res:4:3-56: - Actual declaration + The types for constructor Str are not equal. \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/include_extension_constructors_mismatch.res.expected b/tests/build_tests/super_errors/expected/include_extension_constructors_mismatch.res.expected index 2866c6a589b..642c1812c3c 100644 --- a/tests/build_tests/super_errors/expected/include_extension_constructors_mismatch.res.expected +++ b/tests/build_tests/super_errors/expected/include_extension_constructors_mismatch.res.expected @@ -11,21 +11,9 @@ 8 │ Signature mismatch: - Modules do not match: - { - type t = .. - type t += E(string) - } - is not included in - { - type t = .. - type t += E(int) - } - Extension declarations do not match: + + Actual declaration (/.../fixtures/include_extension_constructors_mismatch.res:6:13-21): type t += E(string) - is not included in - type t += E(int) - /.../fixtures/include_extension_constructors_mismatch.res:3:13-18: - Expected declaration - /.../fixtures/include_extension_constructors_mismatch.res:6:13-21: - Actual declaration \ No newline at end of file + + Expected declaration (/.../fixtures/include_extension_constructors_mismatch.res:3:13-18): + type t += E(int) \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/include_missing_field.res.expected b/tests/build_tests/super_errors/expected/include_missing_field.res.expected index 82f498a3bfb..e082135a52b 100644 --- a/tests/build_tests/super_errors/expected/include_missing_field.res.expected +++ b/tests/build_tests/super_errors/expected/include_missing_field.res.expected @@ -10,15 +10,8 @@ 7 │ Signature mismatch: - Modules do not match: - { - let x: int - } - is not included in - { - let x: int - let y: string - } - The value `y` is required but not provided - /.../fixtures/include_missing_field.res:3:3-15: - Expected declaration \ No newline at end of file + + The value `y` is required but not provided. + + Expected declaration (/.../fixtures/include_missing_field.res:3:3-15): + let y: string \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/include_modtype_infos_mismatch.res.expected b/tests/build_tests/super_errors/expected/include_modtype_infos_mismatch.res.expected index 78cad63a33c..63ef07d880d 100644 --- a/tests/build_tests/super_errors/expected/include_modtype_infos_mismatch.res.expected +++ b/tests/build_tests/super_errors/expected/include_modtype_infos_mismatch.res.expected @@ -12,38 +12,11 @@ 10 │ Signature mismatch: - Modules do not match: - { - module type T = { - let x: string - } - } - is not included in - { - module type T = { - let x: int - } - } - Module type declarations do not match: - module type T = { - let x: string - } - does not match - module type T = { - let x: int - } - At position module type T = - Modules do not match: - { - let x: string - } - is not included in - { - let x: int - } - At position module type T = - Values do not match: let x: string is not included in let x: int - /.../fixtures/include_modtype_infos_mismatch.res:3:5-14: - Expected declaration - /.../fixtures/include_modtype_infos_mismatch.res:7:5-17: - Actual declaration \ No newline at end of file + + In module type T: + + Actual declaration (/.../fixtures/include_modtype_infos_mismatch.res:7:5-17): + let x: string + + Expected declaration (/.../fixtures/include_modtype_infos_mismatch.res:3:5-14): + let x: int \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/include_modtype_permutation.res.expected b/tests/build_tests/super_errors/expected/include_modtype_permutation.res.expected index 411931c5586..72d4be407da 100644 --- a/tests/build_tests/super_errors/expected/include_modtype_permutation.res.expected +++ b/tests/build_tests/super_errors/expected/include_modtype_permutation.res.expected @@ -12,29 +12,7 @@ 12 │ Signature mismatch: - Modules do not match: - { - module type T = { - let b: int - let a: int - } - } - is not included in - { - module type T = { - let a: int - let b: int - } - } - Module type declarations do not match: - module type T = { - let b: int - let a: int - } - does not match - module type T = { - let a: int - let b: int - } - At position module type T = + + In module type T: + Illegal permutation of structure fields \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/include_module_types_mismatch.res.expected b/tests/build_tests/super_errors/expected/include_module_types_mismatch.res.expected index 0542b97c800..5104390f11f 100644 --- a/tests/build_tests/super_errors/expected/include_module_types_mismatch.res.expected +++ b/tests/build_tests/super_errors/expected/include_module_types_mismatch.res.expected @@ -12,24 +12,11 @@ 14 │ Signature mismatch: - Modules do not match: - { - module M: { - let a: string - } - } - is not included in - Outer + In module M: - Modules do not match: - { - let a: string - } - is not included in - Inner - In module M: - Values do not match: let a: string is not included in let a: int - /.../fixtures/include_module_types_mismatch.res:2:3-12: - Expected declaration - /.../fixtures/include_module_types_mismatch.res:11:9: - Actual declaration \ No newline at end of file + + Actual declaration (/.../fixtures/include_module_types_mismatch.res:11:9): + let a: string + + Expected declaration (/.../fixtures/include_module_types_mismatch.res:2:3-12): + let a: int \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/include_type_decl_mismatch.res.expected b/tests/build_tests/super_errors/expected/include_type_decl_mismatch.res.expected index ab18329d62a..c633d6e963d 100644 --- a/tests/build_tests/super_errors/expected/include_type_decl_mismatch.res.expected +++ b/tests/build_tests/super_errors/expected/include_type_decl_mismatch.res.expected @@ -10,19 +10,9 @@ 6 │ Signature mismatch: - Modules do not match: - { - type t = string - } - is not included in - { - type t = int - } - Type declarations do not match: + + Actual declaration (/.../fixtures/include_type_decl_mismatch.res:4:3-17): type t = string - is not included in - type t = int - /.../fixtures/include_type_decl_mismatch.res:2:3-14: - Expected declaration - /.../fixtures/include_type_decl_mismatch.res:4:3-17: - Actual declaration \ No newline at end of file + + Expected declaration (/.../fixtures/include_type_decl_mismatch.res:2:3-14): + type t = int \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/include_value_type_mismatch.res.expected b/tests/build_tests/super_errors/expected/include_value_type_mismatch.res.expected index 3695d0f4c7c..0585c367ae3 100644 --- a/tests/build_tests/super_errors/expected/include_value_type_mismatch.res.expected +++ b/tests/build_tests/super_errors/expected/include_value_type_mismatch.res.expected @@ -10,16 +10,9 @@ 6 │ Signature mismatch: - Modules do not match: - { - let x: string - } - is not included in - { - let x: int - } - Values do not match: let x: string is not included in let x: int - /.../fixtures/include_value_type_mismatch.res:2:3-12: - Expected declaration - /.../fixtures/include_value_type_mismatch.res:4:7: - Actual declaration \ No newline at end of file + + Actual declaration (/.../fixtures/include_value_type_mismatch.res:4:7): + let x: string + + Expected declaration (/.../fixtures/include_value_type_mismatch.res:2:3-12): + let x: int \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/inclusion_layout_functor_parameter.res.expected b/tests/build_tests/super_errors/expected/inclusion_layout_functor_parameter.res.expected new file mode 100644 index 00000000000..d828b9fb19c --- /dev/null +++ b/tests/build_tests/super_errors/expected/inclusion_layout_functor_parameter.res.expected @@ -0,0 +1,22 @@ + + We've found a bug for you! + /.../fixtures/inclusion_layout_functor_parameter.res:9:5-15:1 + + 7 │ }, + 8 │ ) => {} + 9 │ } = { + 10 │  module F = ( + . │ ... + 14 │  ) => {} + 15 │ } + 16 │ + + Signature mismatch: + + In the parameter X of functor F: + + Actual declaration (/.../fixtures/inclusion_layout_functor_parameter.res:12:7-19): + let a: string + + Expected declaration (/.../fixtures/inclusion_layout_functor_parameter.res:6:7-16): + let a: int \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/inclusion_layout_missing_values.res.expected b/tests/build_tests/super_errors/expected/inclusion_layout_missing_values.res.expected new file mode 100644 index 00000000000..0b1507916c2 --- /dev/null +++ b/tests/build_tests/super_errors/expected/inclusion_layout_missing_values.res.expected @@ -0,0 +1,24 @@ + + We've found a bug for you! + /.../fixtures/inclusion_layout_missing_values.res:7:5-9:1 + + 5 │ let b: string + 6 │ } + 7 │ } = { + 8 │  module N = {} + 9 │ } + 10 │ + + Signature mismatch: + + In module N: + + The value `a` is required but not provided. + + Expected declaration (/.../fixtures/inclusion_layout_missing_values.res:4:5-14): + let a: int + + The value `b` is required but not provided. + + Expected declaration (/.../fixtures/inclusion_layout_missing_values.res:5:5-17): + let b: string \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/inclusion_layout_module_kind.res.expected b/tests/build_tests/super_errors/expected/inclusion_layout_module_kind.res.expected new file mode 100644 index 00000000000..355505c06dc --- /dev/null +++ b/tests/build_tests/super_errors/expected/inclusion_layout_module_kind.res.expected @@ -0,0 +1,30 @@ + + We've found a bug for you! + /.../fixtures/inclusion_layout_module_kind.res:11:5-15:1 + + 9 │ let b: int + 10 │ } + 11 │ } = { + 12 │  module F = { + 13 │  let b = 1 + 14 │  } + 15 │ } + 16 │ + + Signature mismatch: + + In module F: + + Actual module type: + { + let b: int + } + + Expected module type: + ( + X: { + let a: int + }, + ) => { + let b: int + } \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/inclusion_layout_nested_module_type.res.expected b/tests/build_tests/super_errors/expected/inclusion_layout_nested_module_type.res.expected new file mode 100644 index 00000000000..0f28b96c552 --- /dev/null +++ b/tests/build_tests/super_errors/expected/inclusion_layout_nested_module_type.res.expected @@ -0,0 +1,22 @@ + + We've found a bug for you! + /.../fixtures/inclusion_layout_nested_module_type.res:8:5-14:1 + + 6 │ } + 7 │ } + 8 │ } = { + 9 │  module N = { + . │ ... + 13 │  } + 14 │ } + 15 │ + + Signature mismatch: + + In module type N.T: + + Actual declaration (/.../fixtures/inclusion_layout_nested_module_type.res:11:7-19): + let v: string + + Expected declaration (/.../fixtures/inclusion_layout_nested_module_type.res:5:7-16): + let v: int \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/inline_bigint_signature_mismatch.res.expected b/tests/build_tests/super_errors/expected/inline_bigint_signature_mismatch.res.expected index 0f6d98a703d..2e85703c8f0 100644 --- a/tests/build_tests/super_errors/expected/inline_bigint_signature_mismatch.res.expected +++ b/tests/build_tests/super_errors/expected/inline_bigint_signature_mismatch.res.expected @@ -11,21 +11,9 @@ 8 │ Signature mismatch: - Modules do not match: - { - let pos: bigint - let neg: bigint - } - is not included in - { - @inline(12n) let pos: bigint - @inline(-5n) let neg: bigint - } - Values do not match: + + Actual declaration (/.../fixtures/inline_bigint_signature_mismatch.res:5:7-9): let pos: bigint - is not included in - @inline(12n) let pos: bigint - /.../fixtures/inline_bigint_signature_mismatch.res:2:3-30: - Expected declaration - /.../fixtures/inline_bigint_signature_mismatch.res:5:7-9: - Actual declaration \ No newline at end of file + + Expected declaration (/.../fixtures/inline_bigint_signature_mismatch.res:2:3-30): + @inline(12n) let pos: bigint \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/module_sig_value_arity_mismatch.res.expected b/tests/build_tests/super_errors/expected/module_sig_value_arity_mismatch.res.expected index d9ee4c1b9f7..d41786140d2 100644 --- a/tests/build_tests/super_errors/expected/module_sig_value_arity_mismatch.res.expected +++ b/tests/build_tests/super_errors/expected/module_sig_value_arity_mismatch.res.expected @@ -10,20 +10,11 @@ 6 │ Signature mismatch: - Modules do not match: - { - let f: int => int => int - } - is not included in - { - let f: (int, int) => int - } - Values do not match: + + Actual declaration (/.../fixtures/module_sig_value_arity_mismatch.res:4:7): let f: int => int => int - is not included in + + Expected declaration (/.../fixtures/module_sig_value_arity_mismatch.res:2:3-26): let f: (int, int) => int - The implementation contains a function taking 1 argument where the interface expects one taking 2 arguments. - /.../fixtures/module_sig_value_arity_mismatch.res:2:3-26: - Expected declaration - /.../fixtures/module_sig_value_arity_mismatch.res:4:7: - Actual declaration \ No newline at end of file + + The implementation contains a function taking 1 argument where the interface expects one taking 2 arguments. \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/module_sig_value_arity_mismatch_alias.res.expected b/tests/build_tests/super_errors/expected/module_sig_value_arity_mismatch_alias.res.expected index 66c4d574fbe..5354b74ea2d 100644 --- a/tests/build_tests/super_errors/expected/module_sig_value_arity_mismatch_alias.res.expected +++ b/tests/build_tests/super_errors/expected/module_sig_value_arity_mismatch_alias.res.expected @@ -10,20 +10,11 @@ 8 │ Signature mismatch: - Modules do not match: - { - let f: curried - } - is not included in - { - let f: (int, int) => int - } - Values do not match: + + Actual declaration (/.../fixtures/module_sig_value_arity_mismatch_alias.res:6:7): let f: curried - is not included in + + Expected declaration (/.../fixtures/module_sig_value_arity_mismatch_alias.res:4:3-26): let f: (int, int) => int - The implementation contains a function taking 1 argument where the interface expects one taking 2 arguments. - /.../fixtures/module_sig_value_arity_mismatch_alias.res:4:3-26: - Expected declaration - /.../fixtures/module_sig_value_arity_mismatch_alias.res:6:7: - Actual declaration \ No newline at end of file + + The implementation contains a function taking 1 argument where the interface expects one taking 2 arguments. \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/module_sig_value_arity_mismatch_nested.res.expected b/tests/build_tests/super_errors/expected/module_sig_value_arity_mismatch_nested.res.expected index 6e4e8fe2a49..4b97b7168d0 100644 --- a/tests/build_tests/super_errors/expected/module_sig_value_arity_mismatch_nested.res.expected +++ b/tests/build_tests/super_errors/expected/module_sig_value_arity_mismatch_nested.res.expected @@ -10,20 +10,11 @@ 6 │ Signature mismatch: - Modules do not match: - { - let f: int => int => int => int - } - is not included in - { - let f: int => (int, int) => int - } - Values do not match: + + Actual declaration (/.../fixtures/module_sig_value_arity_mismatch_nested.res:4:7): let f: int => int => int => int - is not included in + + Expected declaration (/.../fixtures/module_sig_value_arity_mismatch_nested.res:2:3-33): let f: int => (int, int) => int - The implementation contains a function taking 1 argument where the interface expects one taking 2 arguments. - /.../fixtures/module_sig_value_arity_mismatch_nested.res:2:3-33: - Expected declaration - /.../fixtures/module_sig_value_arity_mismatch_nested.res:4:7: - Actual declaration \ No newline at end of file + + The implementation contains a function taking 1 argument where the interface expects one taking 2 arguments. \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/module_sig_value_arity_mismatch_reverse.res.expected b/tests/build_tests/super_errors/expected/module_sig_value_arity_mismatch_reverse.res.expected index bdc204b1021..b9968ea4d20 100644 --- a/tests/build_tests/super_errors/expected/module_sig_value_arity_mismatch_reverse.res.expected +++ b/tests/build_tests/super_errors/expected/module_sig_value_arity_mismatch_reverse.res.expected @@ -10,20 +10,11 @@ 6 │ Signature mismatch: - Modules do not match: - { - let f: (int, int) => int - } - is not included in - { - let f: int => int => int - } - Values do not match: + + Actual declaration (/.../fixtures/module_sig_value_arity_mismatch_reverse.res:4:7): let f: (int, int) => int - is not included in + + Expected declaration (/.../fixtures/module_sig_value_arity_mismatch_reverse.res:2:3-26): let f: int => int => int - The implementation contains a function taking 2 arguments where the interface expects one taking 1 argument. - /.../fixtures/module_sig_value_arity_mismatch_reverse.res:2:3-26: - Expected declaration - /.../fixtures/module_sig_value_arity_mismatch_reverse.res:4:7: - Actual declaration \ No newline at end of file + + The implementation contains a function taking 2 arguments where the interface expects one taking 1 argument. \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/not_undefined_functor_argument.res.expected b/tests/build_tests/super_errors/expected/not_undefined_functor_argument.res.expected index 885a441f148..faaa875e651 100644 --- a/tests/build_tests/super_errors/expected/not_undefined_functor_argument.res.expected +++ b/tests/build_tests/super_errors/expected/not_undefined_functor_argument.res.expected @@ -10,22 +10,13 @@ 12 │ Signature mismatch: - Modules do not match: - { - type t = option - } - is not included in - { - type t - } - Type declarations do not match: + + Actual declaration (/.../fixtures/not_undefined_functor_argument.res:10:3-22): type t = option - is not included in + + Expected declaration (/.../fixtures/not_undefined_functor_argument.res:3:19-24): type t - /.../fixtures/not_undefined_functor_argument.res:3:19-24: - Expected declaration - /.../fixtures/not_undefined_functor_argument.res:10:3-22: - Actual declaration + Their runtime representations differ: - the second declaration is @notUndefined, - but the first declaration can hold undefined. \ No newline at end of file + The expected declaration is @notUndefined, + but the actual declaration can hold undefined. \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/not_undefined_functor_parameter.res.expected b/tests/build_tests/super_errors/expected/not_undefined_functor_parameter.res.expected index 12957f65488..ab95c1bddf5 100644 --- a/tests/build_tests/super_errors/expected/not_undefined_functor_parameter.res.expected +++ b/tests/build_tests/super_errors/expected/not_undefined_functor_parameter.res.expected @@ -11,19 +11,13 @@ 12 │ Signature mismatch: - Modules do not match: - { - type t = X.t - } - is not included in - { - type t - } - Type declarations do not match: type t = X.t is not included in type t - /.../fixtures/not_undefined_functor_parameter.res:7:19-24: - Expected declaration - /.../fixtures/not_undefined_functor_parameter.res:9:5-16: - Actual declaration + + Actual declaration (/.../fixtures/not_undefined_functor_parameter.res:9:5-16): + type t = X.t + + Expected declaration (/.../fixtures/not_undefined_functor_parameter.res:7:19-24): + type t + Their runtime representations differ: - the second declaration is @notUndefined, - but the first declaration can hold undefined. \ No newline at end of file + The expected declaration is @notUndefined, + but the actual declaration can hold undefined. \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/object_manifest_set_mismatch.res.expected b/tests/build_tests/super_errors/expected/object_manifest_set_mismatch.res.expected index a03eab7d9e0..b766c08dbe4 100644 --- a/tests/build_tests/super_errors/expected/object_manifest_set_mismatch.res.expected +++ b/tests/build_tests/super_errors/expected/object_manifest_set_mismatch.res.expected @@ -10,19 +10,9 @@ 9 │ Signature mismatch: - Modules do not match: - { - type t = {@set "x": int} - } - is not included in - { - type t = {"x": int} - } - Type declarations do not match: + + Actual declaration (/.../fixtures/object_manifest_set_mismatch.res:7:3-26): type t = {@set "x": int} - is not included in - type t = {"x": int} - /.../fixtures/object_manifest_set_mismatch.res:5:3-21: - Expected declaration - /.../fixtures/object_manifest_set_mismatch.res:7:3-26: - Actual declaration \ No newline at end of file + + Expected declaration (/.../fixtures/object_manifest_set_mismatch.res:5:3-21): + type t = {"x": int} \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/object_private_row_grants_set.res.expected b/tests/build_tests/super_errors/expected/object_private_row_grants_set.res.expected index c1663dca912..7fbbe6e81d3 100644 --- a/tests/build_tests/super_errors/expected/object_private_row_grants_set.res.expected +++ b/tests/build_tests/super_errors/expected/object_private_row_grants_set.res.expected @@ -10,19 +10,9 @@ 10 │ Signature mismatch: - Modules do not match: - { - type t = private {.."x": int} - } - is not included in - { - type t = private {..@set "x": int} - } - Type declarations do not match: + + Actual declaration (/.../fixtures/object_private_row_grants_set.res:8:3-31): type t = private {.."x": int} - is not included in - type t = private {..@set "x": int} - /.../fixtures/object_private_row_grants_set.res:6:3-36: - Expected declaration - /.../fixtures/object_private_row_grants_set.res:8:3-31: - Actual declaration \ No newline at end of file + + Expected declaration (/.../fixtures/object_private_row_grants_set.res:6:3-36): + type t = private {..@set "x": int} \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/object_value_signature_set_mismatch.res.expected b/tests/build_tests/super_errors/expected/object_value_signature_set_mismatch.res.expected index 3f040ccf3c4..7751e19fab6 100644 --- a/tests/build_tests/super_errors/expected/object_value_signature_set_mismatch.res.expected +++ b/tests/build_tests/super_errors/expected/object_value_signature_set_mismatch.res.expected @@ -10,19 +10,9 @@ 11 │ Signature mismatch: - Modules do not match: - { - let v: {@set "x": int} - } - is not included in - { - let v: {"x": int} - } - Values do not match: + + Actual declaration (/.../fixtures/object_value_signature_set_mismatch.res:9:7): let v: {@set "x": int} - is not included in - let v: {"x": int} - /.../fixtures/object_value_signature_set_mismatch.res:7:3-19: - Expected declaration - /.../fixtures/object_value_signature_set_mismatch.res:9:7: - Actual declaration \ No newline at end of file + + Expected declaration (/.../fixtures/object_value_signature_set_mismatch.res:7:3-19): + let v: {"x": int} \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/runtime_annotation_interface_over_record.res.expected b/tests/build_tests/super_errors/expected/runtime_annotation_interface_over_record.res.expected index bc348898f4f..51420072afc 100644 --- a/tests/build_tests/super_errors/expected/runtime_annotation_interface_over_record.res.expected +++ b/tests/build_tests/super_errors/expected/runtime_annotation_interface_over_record.res.expected @@ -10,19 +10,13 @@ 6 │ Signature mismatch: - Modules do not match: - { - type t = {y: int} - } - is not included in - { - type t - } - Type declarations do not match: type t = {y: int} is not included in type t - /.../fixtures/runtime_annotation_interface_over_record.res:2:21-26: - Expected declaration - /.../fixtures/runtime_annotation_interface_over_record.res:4:3-19: - Actual declaration + + Actual declaration (/.../fixtures/runtime_annotation_interface_over_record.res:4:3-19): + type t = {y: int} + + Expected declaration (/.../fixtures/runtime_annotation_interface_over_record.res:2:21-26): + type t + Their runtime representations differ: - the first declaration states values whose typeof is "object", - the second declaration states values whose typeof is "string". \ No newline at end of file + The actual declaration states values whose typeof is "object". + The expected declaration states values whose typeof is "string". \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/type_decl_function_arity_mismatch.res.expected b/tests/build_tests/super_errors/expected/type_decl_function_arity_mismatch.res.expected index b1a9e86062a..030e0ef4c68 100644 --- a/tests/build_tests/super_errors/expected/type_decl_function_arity_mismatch.res.expected +++ b/tests/build_tests/super_errors/expected/type_decl_function_arity_mismatch.res.expected @@ -10,19 +10,9 @@ 6 │ Signature mismatch: - Modules do not match: - { - type t = int => int => int - } - is not included in - { - type t = (int, int) => int - } - Type declarations do not match: + + Actual declaration (/.../fixtures/type_decl_function_arity_mismatch.res:4:3-28): type t = int => int => int - is not included in - type t = (int, int) => int - /.../fixtures/type_decl_function_arity_mismatch.res:2:3-28: - Expected declaration - /.../fixtures/type_decl_function_arity_mismatch.res:4:3-28: - Actual declaration \ No newline at end of file + + Expected declaration (/.../fixtures/type_decl_function_arity_mismatch.res:2:3-28): + type t = (int, int) => int \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/variant_payload_tag_mismatch.res.expected b/tests/build_tests/super_errors/expected/variant_payload_tag_mismatch.res.expected index e012335ef19..94b27671e85 100644 --- a/tests/build_tests/super_errors/expected/variant_payload_tag_mismatch.res.expected +++ b/tests/build_tests/super_errors/expected/variant_payload_tag_mismatch.res.expected @@ -12,13 +12,11 @@ 10 │ Console.log( Signature mismatch: - ... - Type declarations do not match: + + Actual declaration (/.../fixtures/variant_payload_tag_mismatch.res:6:3-56): type t = @as("C") A({x: int}) | @as("A") C({x: int}) - is not included in + + Expected declaration (/.../fixtures/variant_payload_tag_mismatch.res:3:3-36): type t = A({x: int}) | C({x: int}) - /.../fixtures/variant_payload_tag_mismatch.res:3:3-36: - Expected declaration - /.../fixtures/variant_payload_tag_mismatch.res:6:3-56: - Actual declaration + The internal representations for case A are not equal. \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/with_mismatch.res.expected b/tests/build_tests/super_errors/expected/with_mismatch.res.expected index 6f5e2b47130..8e76ff2edeb 100644 --- a/tests/build_tests/super_errors/expected/with_mismatch.res.expected +++ b/tests/build_tests/super_errors/expected/with_mismatch.res.expected @@ -9,11 +9,9 @@ In this `with' constraint, the new definition of t does not match its original definition in the constrained signature: - Type declarations do not match: + + Actual declaration (/.../fixtures/with_mismatch.res:5:29): type t = string - is not included in - type t = int - /.../fixtures/with_mismatch.res:2:3-14: - Expected declaration - /.../fixtures/with_mismatch.res:5:29: - Actual declaration \ No newline at end of file + + Expected declaration (/.../fixtures/with_mismatch.res:2:3-14): + type t = int \ No newline at end of file diff --git a/tests/build_tests/super_errors/fixtures/inclusion_layout_functor_parameter.res b/tests/build_tests/super_errors/fixtures/inclusion_layout_functor_parameter.res new file mode 100644 index 00000000000..5eebab34f7e --- /dev/null +++ b/tests/build_tests/super_errors/fixtures/inclusion_layout_functor_parameter.res @@ -0,0 +1,15 @@ +// A difference in a functor's parameter is shown at its position in the +// functor's type +module M: { + module F: ( + X: { + let a: int + }, + ) => {} +} = { + module F = ( + X: { + let a: string + }, + ) => {} +} diff --git a/tests/build_tests/super_errors/fixtures/inclusion_layout_missing_values.res b/tests/build_tests/super_errors/fixtures/inclusion_layout_missing_values.res new file mode 100644 index 00000000000..152306de135 --- /dev/null +++ b/tests/build_tests/super_errors/fixtures/inclusion_layout_missing_values.res @@ -0,0 +1,9 @@ +// Several missing values of one module are listed under its position once +module M: { + module N: { + let a: int + let b: string + } +} = { + module N = {} +} diff --git a/tests/build_tests/super_errors/fixtures/inclusion_layout_module_kind.res b/tests/build_tests/super_errors/fixtures/inclusion_layout_module_kind.res new file mode 100644 index 00000000000..f8e7d0583de --- /dev/null +++ b/tests/build_tests/super_errors/fixtures/inclusion_layout_module_kind.res @@ -0,0 +1,15 @@ +// A module where a functor is expected has no declarations to compare: the +// module types are shown +module M: { + module F: ( + X: { + let a: int + }, + ) => { + let b: int + } +} = { + module F = { + let b = 1 + } +} diff --git a/tests/build_tests/super_errors/fixtures/inclusion_layout_nested_module_type.res b/tests/build_tests/super_errors/fixtures/inclusion_layout_nested_module_type.res new file mode 100644 index 00000000000..318a5409d48 --- /dev/null +++ b/tests/build_tests/super_errors/fixtures/inclusion_layout_nested_module_type.res @@ -0,0 +1,14 @@ +// A difference in a module type inside a module is named by its path +module M: { + module N: { + module type T = { + let v: int + } + } +} = { + module N = { + module type T = { + let v: string + } + } +} diff --git a/tests/build_tests/super_errors_multi/expected/Cross_external_import_attrs.expected b/tests/build_tests/super_errors_multi/expected/Cross_external_import_attrs.expected index aec8dbdd994..7d4e69fb964 100644 --- a/tests/build_tests/super_errors_multi/expected/Cross_external_import_attrs.expected +++ b/tests/build_tests/super_errors_multi/expected/Cross_external_import_attrs.expected @@ -10,13 +10,11 @@ The implementation /.../fixtures/Cross_external_import_attrs/Importattrs.res does not match the interface /.../fixtures/Cross_external_import_attrs/importattrs.cmi: - Values do not match: + + Actual declaration (/.../fixtures/Cross_external_import_attrs/Importattrs.res:1:1-2:30): @val @module({from: "somepkg", with: {type_: "json", \"some-identifier": "nope"}}) external data: int = "default" - is not included in + + Expected declaration (/.../fixtures/Cross_external_import_attrs/Importattrs.resi:1:1-2:30): @val @module({from: "somepkg", with: {type_: "json", \"some-identifier": "yep"}}) external data: int = - "default" - /.../fixtures/Cross_external_import_attrs/Importattrs.resi:1:1-2:30: - Expected declaration - /.../fixtures/Cross_external_import_attrs/Importattrs.res:1:1-2:30: - Actual declaration \ No newline at end of file + "default" \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_external_payload_name.expected b/tests/build_tests/super_errors_multi/expected/Cross_external_payload_name.expected index 3e9460a6c95..40614fcc922 100644 --- a/tests/build_tests/super_errors_multi/expected/Cross_external_payload_name.expected +++ b/tests/build_tests/super_errors_multi/expected/Cross_external_payload_name.expected @@ -8,11 +8,9 @@ The implementation /.../fixtures/Cross_external_payload_name/Payload.res does not match the interface /.../fixtures/Cross_external_payload_name/payload.cmi: - Values do not match: + + Actual declaration (/.../fixtures/Cross_external_payload_name/Payload.res:1:1-39): @val("foo") external f: int => int = "" - is not included in - @val("bar") external f: int => int = "" - /.../fixtures/Cross_external_payload_name/Payload.resi:1:1-39: - Expected declaration - /.../fixtures/Cross_external_payload_name/Payload.res:1:1-39: - Actual declaration \ No newline at end of file + + Expected declaration (/.../fixtures/Cross_external_payload_name/Payload.resi:1:1-39): + @val("bar") external f: int => int = "" \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_external_spec_mismatch.expected b/tests/build_tests/super_errors_multi/expected/Cross_external_spec_mismatch.expected index e1c5e7ec516..b2e7f1072bd 100644 --- a/tests/build_tests/super_errors_multi/expected/Cross_external_spec_mismatch.expected +++ b/tests/build_tests/super_errors_multi/expected/Cross_external_spec_mismatch.expected @@ -8,11 +8,9 @@ The implementation /.../fixtures/Cross_external_spec_mismatch/Specmismatch.res does not match the interface /.../fixtures/Cross_external_spec_mismatch/specmismatch.cmi: - Values do not match: + + Actual declaration (/.../fixtures/Cross_external_spec_mismatch/Specmismatch.res:1:1-46): @val @module("m") external f: int => int = "f" - is not included in - @val external f: int => int = "f" - /.../fixtures/Cross_external_spec_mismatch/Specmismatch.resi:1:1-33: - Expected declaration - /.../fixtures/Cross_external_spec_mismatch/Specmismatch.res:1:1-46: - Actual declaration \ No newline at end of file + + Expected declaration (/.../fixtures/Cross_external_spec_mismatch/Specmismatch.resi:1:1-33): + @val external f: int => int = "f" \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_not_undefined_option_implementation.expected b/tests/build_tests/super_errors_multi/expected/Cross_not_undefined_option_implementation.expected index efc27a4df36..eedd19ea8ce 100644 --- a/tests/build_tests/super_errors_multi/expected/Cross_not_undefined_option_implementation.expected +++ b/tests/build_tests/super_errors_multi/expected/Cross_not_undefined_option_implementation.expected @@ -9,14 +9,13 @@ The implementation /.../fixtures/Cross_not_undefined_option_implementation/Hidden.res does not match the interface /.../fixtures/Cross_not_undefined_option_implementation/hidden.cmi: - Type declarations do not match: + + Actual declaration (/.../fixtures/Cross_not_undefined_option_implementation/Hidden.res:1:1-20): type t = option - is not included in + + Expected declaration (/.../fixtures/Cross_not_undefined_option_implementation/Hidden.resi:1:15-20): type t - /.../fixtures/Cross_not_undefined_option_implementation/Hidden.resi:1:15-20: - Expected declaration - /.../fixtures/Cross_not_undefined_option_implementation/Hidden.res:1:1-20: - Actual declaration + Their runtime representations differ: - the second declaration is @notUndefined, - but the first declaration can hold undefined. \ No newline at end of file + The expected declaration is @notUndefined, + but the actual declaration can hold undefined. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_private_abbreviation_mismatch.expected b/tests/build_tests/super_errors_multi/expected/Cross_private_abbreviation_mismatch.expected index 71730354d12..ee74ab2d9dc 100644 --- a/tests/build_tests/super_errors_multi/expected/Cross_private_abbreviation_mismatch.expected +++ b/tests/build_tests/super_errors_multi/expected/Cross_private_abbreviation_mismatch.expected @@ -10,11 +10,9 @@ The implementation /.../fixtures/Cross_private_abbreviation_mismatch/Priv.res does not match the interface /.../fixtures/Cross_private_abbreviation_mismatch/priv.cmi: - Type declarations do not match: + + Actual declaration (/.../fixtures/Cross_private_abbreviation_mismatch/Priv.res:3:1-10): type t = b - is not included in - type t = private a - /.../fixtures/Cross_private_abbreviation_mismatch/Priv.resi:2:1-18: - Expected declaration - /.../fixtures/Cross_private_abbreviation_mismatch/Priv.res:3:1-10: - Actual declaration \ No newline at end of file + + Expected declaration (/.../fixtures/Cross_private_abbreviation_mismatch/Priv.resi:2:1-18): + type t = private a \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_private_variant_manifest_mismatch.expected b/tests/build_tests/super_errors_multi/expected/Cross_private_variant_manifest_mismatch.expected index 2e76d32d92c..0615ae8ae32 100644 --- a/tests/build_tests/super_errors_multi/expected/Cross_private_variant_manifest_mismatch.expected +++ b/tests/build_tests/super_errors_multi/expected/Cross_private_variant_manifest_mismatch.expected @@ -9,11 +9,9 @@ The implementation /.../fixtures/Cross_private_variant_manifest_mismatch/Priv.res does not match the interface /.../fixtures/Cross_private_variant_manifest_mismatch/priv.cmi: - Type declarations do not match: + + Actual declaration (/.../fixtures/Cross_private_variant_manifest_mismatch/Priv.res:2:1-14): type w = A | B - is not included in - type w = v = private A | B - /.../fixtures/Cross_private_variant_manifest_mismatch/Priv.resi:2:1-26: - Expected declaration - /.../fixtures/Cross_private_variant_manifest_mismatch/Priv.res:2:1-14: - Actual declaration \ No newline at end of file + + Expected declaration (/.../fixtures/Cross_private_variant_manifest_mismatch/Priv.resi:2:1-26): + type w = v = private A | B \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_claimed_by_interface.expected b/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_claimed_by_interface.expected index 1a1ffd0059a..dd45d82f18d 100644 --- a/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_claimed_by_interface.expected +++ b/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_claimed_by_interface.expected @@ -8,14 +8,13 @@ The implementation /.../fixtures/Cross_runtime_annotation_claimed_by_interface/Claim.res does not match the interface /.../fixtures/Cross_runtime_annotation_claimed_by_interface/claim.cmi: - Type declarations do not match: + + Actual declaration (/.../fixtures/Cross_runtime_annotation_claimed_by_interface/Claim.res:1:1-23): type t = option - is not included in + + Expected declaration (/.../fixtures/Cross_runtime_annotation_claimed_by_interface/Claim.resi:1:19-24): type t - /.../fixtures/Cross_runtime_annotation_claimed_by_interface/Claim.resi:1:19-24: - Expected declaration - /.../fixtures/Cross_runtime_annotation_claimed_by_interface/Claim.res:1:1-23: - Actual declaration + Their runtime representations differ: - the first declaration states no runtime class or typeof, - the second declaration states values whose typeof is "string". \ No newline at end of file + The actual declaration states no runtime class or typeof. + The expected declaration states values whose typeof is "string". \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_functor_argument.expected b/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_functor_argument.expected index c2f47fb74b0..fc4d04a6955 100644 --- a/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_functor_argument.expected +++ b/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_functor_argument.expected @@ -9,15 +9,13 @@ 11 │ Signature mismatch: - ... - Type declarations do not match: + + Actual declaration (/.../fixtures/Cross_runtime_annotation_functor_argument/A_classes.res:2:20-44): type dog = A_classes.dog - is not included in + + Expected declaration (/.../fixtures/Cross_runtime_annotation_functor_argument/B_user.res:4:24-31): type dog - /.../fixtures/Cross_runtime_annotation_functor_argument/B_user.res:4:24-31: - Expected declaration - /.../fixtures/Cross_runtime_annotation_functor_argument/A_classes.res:2:20-44: - Actual declaration + Their runtime representations differ: - the first declaration states instances of Dog, a subclass of Animal, - the second declaration states instances of Dog. \ No newline at end of file + The actual declaration states instances of Dog, a subclass of Animal. + The expected declaration states instances of Dog. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_hidden_base.expected b/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_hidden_base.expected index 670eba8a7d9..7d0ac015db8 100644 --- a/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_hidden_base.expected +++ b/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_hidden_base.expected @@ -9,14 +9,13 @@ The implementation /.../fixtures/Cross_runtime_annotation_hidden_base/Classes.res does not match the interface /.../fixtures/Cross_runtime_annotation_hidden_base/classes.cmi: - Type declarations do not match: + + Actual declaration (/.../fixtures/Cross_runtime_annotation_hidden_base/Classes.res:2:20-44): type dog = private animal - is not included in + + Expected declaration (/.../fixtures/Cross_runtime_annotation_hidden_base/Classes.resi:2:20-44): type dog = private animal - /.../fixtures/Cross_runtime_annotation_hidden_base/Classes.resi:2:20-44: - Expected declaration - /.../fixtures/Cross_runtime_annotation_hidden_base/Classes.res:2:20-44: - Actual declaration + Their runtime representations differ: - the first declaration states instances of Dog, a subclass of Animal, - the second declaration states instances of Dog. \ No newline at end of file + The actual declaration states instances of Dog, a subclass of Animal. + The expected declaration states instances of Dog. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_hidden_superclass.expected b/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_hidden_superclass.expected index 484244fad91..8bd7a11dbd5 100644 --- a/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_hidden_superclass.expected +++ b/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_hidden_superclass.expected @@ -9,14 +9,13 @@ The implementation /.../fixtures/Cross_runtime_annotation_hidden_superclass/Classes.res does not match the interface /.../fixtures/Cross_runtime_annotation_hidden_superclass/classes.cmi: - Type declarations do not match: + + Actual declaration (/.../fixtures/Cross_runtime_annotation_hidden_superclass/Classes.res:2:20-44): type dog = private animal - is not included in + + Expected declaration (/.../fixtures/Cross_runtime_annotation_hidden_superclass/Classes.resi:2:20-27): type dog - /.../fixtures/Cross_runtime_annotation_hidden_superclass/Classes.resi:2:20-27: - Expected declaration - /.../fixtures/Cross_runtime_annotation_hidden_superclass/Classes.res:2:20-44: - Actual declaration + Their runtime representations differ: - the first declaration states instances of Dog, a subclass of Animal, - the second declaration states instances of Dog. \ No newline at end of file + The actual declaration states instances of Dog, a subclass of Animal. + The expected declaration states instances of Dog. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Iface_constraint_mismatch.expected b/tests/build_tests/super_errors_multi/expected/Iface_constraint_mismatch.expected index e8b71e2cadf..ccc1d7a9d6a 100644 --- a/tests/build_tests/super_errors_multi/expected/Iface_constraint_mismatch.expected +++ b/tests/build_tests/super_errors_multi/expected/Iface_constraint_mismatch.expected @@ -8,13 +8,12 @@ The implementation /.../fixtures/Iface_constraint_mismatch/Foo.res does not match the interface /.../fixtures/Iface_constraint_mismatch/foo.cmi: - Type declarations do not match: + + Actual declaration (/.../fixtures/Iface_constraint_mismatch/Foo.res:1:1-35): type t<'a> = 'a - constraint 'a = int - is not included in + constraint 'a = int + + Expected declaration (/.../fixtures/Iface_constraint_mismatch/Foo.resi:1:1-10): type t<'a> - /.../fixtures/Iface_constraint_mismatch/Foo.resi:1:1-10: - Expected declaration - /.../fixtures/Iface_constraint_mismatch/Foo.res:1:1-35: - Actual declaration + Their constraints differ. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Iface_extension_constructors.expected b/tests/build_tests/super_errors_multi/expected/Iface_extension_constructors.expected index 1b116eed3fd..e8390e9d2d1 100644 --- a/tests/build_tests/super_errors_multi/expected/Iface_extension_constructors.expected +++ b/tests/build_tests/super_errors_multi/expected/Iface_extension_constructors.expected @@ -5,11 +5,9 @@ The implementation /.../fixtures/Iface_extension_constructors/Foo.res does not match the interface /.../fixtures/Iface_extension_constructors/foo.cmi: - Extension declarations do not match: + + Actual declaration (/.../fixtures/Iface_extension_constructors/Foo.res:4:3-16): type t += Boom(string) - is not included in - type t += Boom(int) - /.../fixtures/Iface_extension_constructors/Foo.res: - Expected declaration - /.../fixtures/Iface_extension_constructors/Foo.res:4:3-16: - Actual declaration \ No newline at end of file + + Expected declaration (/.../fixtures/Iface_extension_constructors/Foo.resi:4:3-13): + type t += Boom(int) \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Iface_field_arity_mismatch.expected b/tests/build_tests/super_errors_multi/expected/Iface_field_arity_mismatch.expected index 92021a38533..0534014b39d 100644 --- a/tests/build_tests/super_errors_multi/expected/Iface_field_arity_mismatch.expected +++ b/tests/build_tests/super_errors_multi/expected/Iface_field_arity_mismatch.expected @@ -8,12 +8,11 @@ The implementation /.../fixtures/Iface_field_arity_mismatch/Foo.res does not match the interface /.../fixtures/Iface_field_arity_mismatch/foo.cmi: - Type declarations do not match: + + Actual declaration (/.../fixtures/Iface_field_arity_mismatch/Foo.res:1:1-19): type t = A(int) | B - is not included in + + Expected declaration (/.../fixtures/Iface_field_arity_mismatch/Foo.resi:1:1-24): type t = A(int, int) | B - /.../fixtures/Iface_field_arity_mismatch/Foo.resi:1:1-24: - Expected declaration - /.../fixtures/Iface_field_arity_mismatch/Foo.res:1:1-19: - Actual declaration + The arities for constructor A differ. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Iface_field_mutable_mismatch.expected b/tests/build_tests/super_errors_multi/expected/Iface_field_mutable_mismatch.expected index 1b0534cb661..77331c167ae 100644 --- a/tests/build_tests/super_errors_multi/expected/Iface_field_mutable_mismatch.expected +++ b/tests/build_tests/super_errors_multi/expected/Iface_field_mutable_mismatch.expected @@ -8,12 +8,11 @@ The implementation /.../fixtures/Iface_field_mutable_mismatch/Foo.res does not match the interface /.../fixtures/Iface_field_mutable_mismatch/foo.cmi: - Type declarations do not match: + + Actual declaration (/.../fixtures/Iface_field_mutable_mismatch/Foo.res:1:1-21): type t = {count: int} - is not included in + + Expected declaration (/.../fixtures/Iface_field_mutable_mismatch/Foo.resi:1:1-29): type t = {mutable count: int} - /.../fixtures/Iface_field_mutable_mismatch/Foo.resi:1:1-29: - Expected declaration - /.../fixtures/Iface_field_mutable_mismatch/Foo.res:1:1-21: - Actual declaration + The mutability of field count is different. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Iface_field_names_mismatch.expected b/tests/build_tests/super_errors_multi/expected/Iface_field_names_mismatch.expected index 50e347af7e1..f552db48639 100644 --- a/tests/build_tests/super_errors_multi/expected/Iface_field_names_mismatch.expected +++ b/tests/build_tests/super_errors_multi/expected/Iface_field_names_mismatch.expected @@ -8,12 +8,11 @@ The implementation /.../fixtures/Iface_field_names_mismatch/Foo.res does not match the interface /.../fixtures/Iface_field_names_mismatch/foo.cmi: - Type declarations do not match: + + Actual declaration (/.../fixtures/Iface_field_names_mismatch/Foo.res:1:1-25): type t = {a: int, b: int} - is not included in + + Expected declaration (/.../fixtures/Iface_field_names_mismatch/Foo.resi:1:1-25): type t = {x: int, y: int} - /.../fixtures/Iface_field_names_mismatch/Foo.resi:1:1-25: - Expected declaration - /.../fixtures/Iface_field_names_mismatch/Foo.res:1:1-25: - Actual declaration + Fields number 1 have different names, a and x. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Iface_field_optional_mismatch.expected b/tests/build_tests/super_errors_multi/expected/Iface_field_optional_mismatch.expected index 56261f1f0fa..b504fcaede3 100644 --- a/tests/build_tests/super_errors_multi/expected/Iface_field_optional_mismatch.expected +++ b/tests/build_tests/super_errors_multi/expected/Iface_field_optional_mismatch.expected @@ -8,12 +8,11 @@ The implementation /.../fixtures/Iface_field_optional_mismatch/Foo.res does not match the interface /.../fixtures/Iface_field_optional_mismatch/foo.cmi: - Type declarations do not match: + + Actual declaration (/.../fixtures/Iface_field_optional_mismatch/Foo.res:1:1-28): type t = {a: int, b: string} - is not included in + + Expected declaration (/.../fixtures/Iface_field_optional_mismatch/Foo.resi:1:1-29): type t = {a: int, b?: string} - /.../fixtures/Iface_field_optional_mismatch/Foo.resi:1:1-29: - Expected declaration - /.../fixtures/Iface_field_optional_mismatch/Foo.res:1:1-28: - Actual declaration + The optional attribute of field b is different. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Iface_immediate_mismatch.expected b/tests/build_tests/super_errors_multi/expected/Iface_immediate_mismatch.expected index 7b6273d7c02..8de281130e7 100644 --- a/tests/build_tests/super_errors_multi/expected/Iface_immediate_mismatch.expected +++ b/tests/build_tests/super_errors_multi/expected/Iface_immediate_mismatch.expected @@ -8,12 +8,11 @@ The implementation /.../fixtures/Iface_immediate_mismatch/Foo.res does not match the interface /.../fixtures/Iface_immediate_mismatch/foo.cmi: - Type declarations do not match: + + Actual declaration (/.../fixtures/Iface_immediate_mismatch/Foo.res:1:1-15): type t = string - is not included in + + Expected declaration (/.../fixtures/Iface_immediate_mismatch/Foo.resi:2:1-6): @immediate type t - /.../fixtures/Iface_immediate_mismatch/Foo.resi:2:1-6: - Expected declaration - /.../fixtures/Iface_immediate_mismatch/Foo.res:1:1-15: - Actual declaration - the first is not an immediate type. \ No newline at end of file + + the actual declaration is not an immediate type. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Iface_kind_mismatch.expected b/tests/build_tests/super_errors_multi/expected/Iface_kind_mismatch.expected index c00ea7282a2..dfb3550040b 100644 --- a/tests/build_tests/super_errors_multi/expected/Iface_kind_mismatch.expected +++ b/tests/build_tests/super_errors_multi/expected/Iface_kind_mismatch.expected @@ -8,12 +8,11 @@ The implementation /.../fixtures/Iface_kind_mismatch/Foo.res does not match the interface /.../fixtures/Iface_kind_mismatch/foo.cmi: - Type declarations do not match: + + Actual declaration (/.../fixtures/Iface_kind_mismatch/Foo.res:1:1-17): type t = {x: int} - is not included in + + Expected declaration (/.../fixtures/Iface_kind_mismatch/Foo.resi:1:1-14): type t = A | B - /.../fixtures/Iface_kind_mismatch/Foo.resi:1:1-14: - Expected declaration - /.../fixtures/Iface_kind_mismatch/Foo.res:1:1-17: - Actual declaration + Their kinds differ. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Iface_manifest_mismatch.expected b/tests/build_tests/super_errors_multi/expected/Iface_manifest_mismatch.expected index 7271fca599e..2ffb30d4041 100644 --- a/tests/build_tests/super_errors_multi/expected/Iface_manifest_mismatch.expected +++ b/tests/build_tests/super_errors_multi/expected/Iface_manifest_mismatch.expected @@ -8,11 +8,9 @@ The implementation /.../fixtures/Iface_manifest_mismatch/Foo.res does not match the interface /.../fixtures/Iface_manifest_mismatch/foo.cmi: - Type declarations do not match: + + Actual declaration (/.../fixtures/Iface_manifest_mismatch/Foo.res:1:1-15): type t = string - is not included in - type t = int - /.../fixtures/Iface_manifest_mismatch/Foo.resi:1:1-12: - Expected declaration - /.../fixtures/Iface_manifest_mismatch/Foo.res:1:1-15: - Actual declaration \ No newline at end of file + + Expected declaration (/.../fixtures/Iface_manifest_mismatch/Foo.resi:1:1-12): + type t = int \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Iface_missing_value.expected b/tests/build_tests/super_errors_multi/expected/Iface_missing_value.expected index afd9c825542..decee53abd4 100644 --- a/tests/build_tests/super_errors_multi/expected/Iface_missing_value.expected +++ b/tests/build_tests/super_errors_multi/expected/Iface_missing_value.expected @@ -9,6 +9,8 @@ The implementation /.../fixtures/Iface_missing_value/Foo.res does not match the interface /.../fixtures/Iface_missing_value/foo.cmi: - The value `b` is required but not provided - /.../fixtures/Iface_missing_value/Foo.resi:2:1-13: - Expected declaration \ No newline at end of file + + The value `b` is required but not provided. + + Expected declaration (/.../fixtures/Iface_missing_value/Foo.resi:2:1-13): + let b: string \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Iface_modtype_infos.expected b/tests/build_tests/super_errors_multi/expected/Iface_modtype_infos.expected index 9d950c7a69d..caae0f592be 100644 --- a/tests/build_tests/super_errors_multi/expected/Iface_modtype_infos.expected +++ b/tests/build_tests/super_errors_multi/expected/Iface_modtype_infos.expected @@ -5,26 +5,11 @@ The implementation /.../fixtures/Iface_modtype_infos/Foo.res does not match the interface /.../fixtures/Iface_modtype_infos/foo.cmi: - Module type declarations do not match: - module type T = { - let v: string - } - does not match - module type T = { - let v: int - } - At position module type T = - Modules do not match: - { - let v: string - } - is not included in - { - let v: int - } - At position module type T = - Values do not match: let v: string is not included in let v: int - /.../fixtures/Iface_modtype_infos/Foo.resi:2:3-12: - Expected declaration - /.../fixtures/Iface_modtype_infos/Foo.res:2:3-15: - Actual declaration \ No newline at end of file + + In module type T: + + Actual declaration (/.../fixtures/Iface_modtype_infos/Foo.res:2:3-15): + let v: string + + Expected declaration (/.../fixtures/Iface_modtype_infos/Foo.resi:2:3-12): + let v: int \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Iface_module_types.expected b/tests/build_tests/super_errors_multi/expected/Iface_module_types.expected index 09f893a1627..a1feb8c6b7f 100644 --- a/tests/build_tests/super_errors_multi/expected/Iface_module_types.expected +++ b/tests/build_tests/super_errors_multi/expected/Iface_module_types.expected @@ -5,18 +5,11 @@ The implementation /.../fixtures/Iface_module_types/Foo.res does not match the interface /.../fixtures/Iface_module_types/foo.cmi: + In module Inner: - Modules do not match: - { - let value: string - } - is not included in - { - let value: int - } - In module Inner: - Values do not match: let value: string is not included in let value: int - /.../fixtures/Iface_module_types/Foo.resi:2:3-16: - Expected declaration - /.../fixtures/Iface_module_types/Foo.res:2:7-11: - Actual declaration \ No newline at end of file + + Actual declaration (/.../fixtures/Iface_module_types/Foo.res:2:7-11): + let value: string + + Expected declaration (/.../fixtures/Iface_module_types/Foo.resi:2:3-16): + let value: int \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Iface_privacy_mismatch.expected b/tests/build_tests/super_errors_multi/expected/Iface_privacy_mismatch.expected index c8b4726a2b2..1dca80df79f 100644 --- a/tests/build_tests/super_errors_multi/expected/Iface_privacy_mismatch.expected +++ b/tests/build_tests/super_errors_multi/expected/Iface_privacy_mismatch.expected @@ -8,12 +8,11 @@ The implementation /.../fixtures/Iface_privacy_mismatch/Foo.res does not match the interface /.../fixtures/Iface_privacy_mismatch/foo.cmi: - Type declarations do not match: + + Actual declaration (/.../fixtures/Iface_privacy_mismatch/Foo.res:1:1-20): type t = private int - is not included in + + Expected declaration (/.../fixtures/Iface_privacy_mismatch/Foo.resi:1:1-12): type t = int - /.../fixtures/Iface_privacy_mismatch/Foo.resi:1:1-12: - Expected declaration - /.../fixtures/Iface_privacy_mismatch/Foo.res:1:1-20: - Actual declaration + A private type would be revealed. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Iface_record_representation_mismatch.expected b/tests/build_tests/super_errors_multi/expected/Iface_record_representation_mismatch.expected index 7eb863109e6..33c71647001 100644 --- a/tests/build_tests/super_errors_multi/expected/Iface_record_representation_mismatch.expected +++ b/tests/build_tests/super_errors_multi/expected/Iface_record_representation_mismatch.expected @@ -8,13 +8,12 @@ The implementation /.../fixtures/Iface_record_representation_mismatch/Foo.res does not match the interface /.../fixtures/Iface_record_representation_mismatch/foo.cmi: - Type declarations do not match: + + Actual declaration (/.../fixtures/Iface_record_representation_mismatch/Foo.res:1:1-17): type t = {x: int} - is not included in + + Expected declaration (/.../fixtures/Iface_record_representation_mismatch/Foo.resi:2:1-17): @unboxed type t = {x: int} - /.../fixtures/Iface_record_representation_mismatch/Foo.resi:2:1-17: - Expected declaration - /.../fixtures/Iface_record_representation_mismatch/Foo.res:1:1-17: - Actual declaration + Their internal representations differ: - the second declaration uses unboxed representation. \ No newline at end of file + The expected declaration uses unboxed representation. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Iface_tag_name_mismatch.expected b/tests/build_tests/super_errors_multi/expected/Iface_tag_name_mismatch.expected index 96795bfb816..16821fcba12 100644 --- a/tests/build_tests/super_errors_multi/expected/Iface_tag_name_mismatch.expected +++ b/tests/build_tests/super_errors_multi/expected/Iface_tag_name_mismatch.expected @@ -11,12 +11,11 @@ The implementation /.../fixtures/Iface_tag_name_mismatch/Foo.res does not match the interface /.../fixtures/Iface_tag_name_mismatch/foo.cmi: - Type declarations do not match: + + Actual declaration (/.../fixtures/Iface_tag_name_mismatch/Foo.res:2:1-4:5): type t = @as("a") A | B - is not included in + + Expected declaration (/.../fixtures/Iface_tag_name_mismatch/Foo.resi:2:1-4:5): type t = @as("a") A | B - /.../fixtures/Iface_tag_name_mismatch/Foo.resi:2:1-4:5: - Expected declaration - /.../fixtures/Iface_tag_name_mismatch/Foo.res:2:1-4:5: - Actual declaration + Their @tag annotations differ. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Iface_type_decl_record.expected b/tests/build_tests/super_errors_multi/expected/Iface_type_decl_record.expected index 16ea04ada1a..372f6d8deaf 100644 --- a/tests/build_tests/super_errors_multi/expected/Iface_type_decl_record.expected +++ b/tests/build_tests/super_errors_multi/expected/Iface_type_decl_record.expected @@ -8,12 +8,11 @@ The implementation /.../fixtures/Iface_type_decl_record/Foo.res does not match the interface /.../fixtures/Iface_type_decl_record/foo.cmi: - Type declarations do not match: + + Actual declaration (/.../fixtures/Iface_type_decl_record/Foo.res:1:1-25): type t = {x: int, z: int} - is not included in + + Expected declaration (/.../fixtures/Iface_type_decl_record/Foo.resi:1:1-25): type t = {x: int, y: int} - /.../fixtures/Iface_type_decl_record/Foo.resi:1:1-25: - Expected declaration - /.../fixtures/Iface_type_decl_record/Foo.res:1:1-25: - Actual declaration + Fields number 2 have different names, z and y. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Iface_type_decl_variant.expected b/tests/build_tests/super_errors_multi/expected/Iface_type_decl_variant.expected index 0805c41df8c..d02d412a2e4 100644 --- a/tests/build_tests/super_errors_multi/expected/Iface_type_decl_variant.expected +++ b/tests/build_tests/super_errors_multi/expected/Iface_type_decl_variant.expected @@ -10,12 +10,11 @@ The implementation /.../fixtures/Iface_type_decl_variant/Foo.res does not match the interface /.../fixtures/Iface_type_decl_variant/foo.cmi: - Type declarations do not match: + + Actual declaration (/.../fixtures/Iface_type_decl_variant/Foo.res:1:1-3:13): type t = A | B(string) - is not included in + + Expected declaration (/.../fixtures/Iface_type_decl_variant/Foo.resi:1:1-3:10): type t = A | B(int) - /.../fixtures/Iface_type_decl_variant/Foo.resi:1:1-3:10: - Expected declaration - /.../fixtures/Iface_type_decl_variant/Foo.res:1:1-3:13: - Actual declaration + The types for constructor B are not equal. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Iface_unboxed_variant_mismatch.expected b/tests/build_tests/super_errors_multi/expected/Iface_unboxed_variant_mismatch.expected index 3d6d2f2df17..86d27629823 100644 --- a/tests/build_tests/super_errors_multi/expected/Iface_unboxed_variant_mismatch.expected +++ b/tests/build_tests/super_errors_multi/expected/Iface_unboxed_variant_mismatch.expected @@ -8,13 +8,12 @@ The implementation /.../fixtures/Iface_unboxed_variant_mismatch/Foo.res does not match the interface /.../fixtures/Iface_unboxed_variant_mismatch/foo.cmi: - Type declarations do not match: + + Actual declaration (/.../fixtures/Iface_unboxed_variant_mismatch/Foo.res:1:1-18): type t = Wrap(int) - is not included in + + Expected declaration (/.../fixtures/Iface_unboxed_variant_mismatch/Foo.resi:2:1-18): @unboxed type t = Wrap(int) - /.../fixtures/Iface_unboxed_variant_mismatch/Foo.resi:2:1-18: - Expected declaration - /.../fixtures/Iface_unboxed_variant_mismatch/Foo.res:1:1-18: - Actual declaration + Their internal representations differ: - the second declaration uses unboxed representation. \ No newline at end of file + The expected declaration uses unboxed representation. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Iface_value_arity_mismatch.expected b/tests/build_tests/super_errors_multi/expected/Iface_value_arity_mismatch.expected index 4001195e3ba..f8e0555b7f0 100644 --- a/tests/build_tests/super_errors_multi/expected/Iface_value_arity_mismatch.expected +++ b/tests/build_tests/super_errors_multi/expected/Iface_value_arity_mismatch.expected @@ -8,12 +8,11 @@ The implementation /.../fixtures/Iface_value_arity_mismatch/Foo.res does not match the interface /.../fixtures/Iface_value_arity_mismatch/foo.cmi: - Values do not match: + + Actual declaration (/.../fixtures/Iface_value_arity_mismatch/Foo.res:1:5): let f: int => int => int - is not included in + + Expected declaration (/.../fixtures/Iface_value_arity_mismatch/Foo.resi:1:1-24): let f: (int, int) => int - The implementation contains a function taking 1 argument where the interface expects one taking 2 arguments. - /.../fixtures/Iface_value_arity_mismatch/Foo.resi:1:1-24: - Expected declaration - /.../fixtures/Iface_value_arity_mismatch/Foo.res:1:5: - Actual declaration \ No newline at end of file + + The implementation contains a function taking 1 argument where the interface expects one taking 2 arguments. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Iface_value_descriptions.expected b/tests/build_tests/super_errors_multi/expected/Iface_value_descriptions.expected index 6f9df31b053..453213e6cd8 100644 --- a/tests/build_tests/super_errors_multi/expected/Iface_value_descriptions.expected +++ b/tests/build_tests/super_errors_multi/expected/Iface_value_descriptions.expected @@ -8,11 +8,9 @@ The implementation /.../fixtures/Iface_value_descriptions/Foo.res does not match the interface /.../fixtures/Iface_value_descriptions/foo.cmi: - Values do not match: + + Actual declaration (/.../fixtures/Iface_value_descriptions/Foo.res:1:5-11): let compute: string => int - is not included in - let compute: int => int - /.../fixtures/Iface_value_descriptions/Foo.resi:1:1-23: - Expected declaration - /.../fixtures/Iface_value_descriptions/Foo.res:1:5-11: - Actual declaration \ No newline at end of file + + Expected declaration (/.../fixtures/Iface_value_descriptions/Foo.resi:1:1-23): + let compute: int => int \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Iface_variance_mismatch.expected b/tests/build_tests/super_errors_multi/expected/Iface_variance_mismatch.expected index 39b96b60e2c..f22b882f3f8 100644 --- a/tests/build_tests/super_errors_multi/expected/Iface_variance_mismatch.expected +++ b/tests/build_tests/super_errors_multi/expected/Iface_variance_mismatch.expected @@ -8,12 +8,11 @@ The implementation /.../fixtures/Iface_variance_mismatch/Foo.res does not match the interface /.../fixtures/Iface_variance_mismatch/foo.cmi: - Type declarations do not match: + + Actual declaration (/.../fixtures/Iface_variance_mismatch/Foo.res:1:1-21): type t<'a> = 'a => 'a - is not included in + + Expected declaration (/.../fixtures/Iface_variance_mismatch/Foo.resi:1:1-11): type t<+'a> - /.../fixtures/Iface_variance_mismatch/Foo.resi:1:1-11: - Expected declaration - /.../fixtures/Iface_variance_mismatch/Foo.res:1:1-21: - Actual declaration + Their variances do not agree. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Iface_variant_extra_constructor.expected b/tests/build_tests/super_errors_multi/expected/Iface_variant_extra_constructor.expected index f8d5e277dee..b65115be144 100644 --- a/tests/build_tests/super_errors_multi/expected/Iface_variant_extra_constructor.expected +++ b/tests/build_tests/super_errors_multi/expected/Iface_variant_extra_constructor.expected @@ -8,12 +8,11 @@ The implementation /.../fixtures/Iface_variant_extra_constructor/Foo.res does not match the interface /.../fixtures/Iface_variant_extra_constructor/foo.cmi: - Type declarations do not match: + + Actual declaration (/.../fixtures/Iface_variant_extra_constructor/Foo.res:1:1-18): type t = A | B | C - is not included in + + Expected declaration (/.../fixtures/Iface_variant_extra_constructor/Foo.resi:1:1-14): type t = A | B - /.../fixtures/Iface_variant_extra_constructor/Foo.resi:1:1-14: - Expected declaration - /.../fixtures/Iface_variant_extra_constructor/Foo.res:1:1-18: - Actual declaration - The constructor C is only present in the first declaration. \ No newline at end of file + + The constructor C is only present in the actual declaration. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Iface_variant_representation_mismatch.expected b/tests/build_tests/super_errors_multi/expected/Iface_variant_representation_mismatch.expected index a9e569f984b..8dc2f60e2aa 100644 --- a/tests/build_tests/super_errors_multi/expected/Iface_variant_representation_mismatch.expected +++ b/tests/build_tests/super_errors_multi/expected/Iface_variant_representation_mismatch.expected @@ -10,12 +10,11 @@ The implementation /.../fixtures/Iface_variant_representation_mismatch/Foo.res does not match the interface /.../fixtures/Iface_variant_representation_mismatch/foo.cmi: - Type declarations do not match: + + Actual declaration (/.../fixtures/Iface_variant_representation_mismatch/Foo.res:1:1-3:5): type t = @as(0) A | B - is not included in + + Expected declaration (/.../fixtures/Iface_variant_representation_mismatch/Foo.resi:1:1-3:5): type t = @as("zero") A | B - /.../fixtures/Iface_variant_representation_mismatch/Foo.resi:1:1-3:5: - Expected declaration - /.../fixtures/Iface_variant_representation_mismatch/Foo.res:1:1-3:5: - Actual declaration + The internal representations for case A are not equal. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Smoke_interface_mismatch.expected b/tests/build_tests/super_errors_multi/expected/Smoke_interface_mismatch.expected index 96c0f47f00d..5b6bfa6ab72 100644 --- a/tests/build_tests/super_errors_multi/expected/Smoke_interface_mismatch.expected +++ b/tests/build_tests/super_errors_multi/expected/Smoke_interface_mismatch.expected @@ -8,8 +8,9 @@ The implementation /.../fixtures/Smoke_interface_mismatch/Foo.res does not match the interface /.../fixtures/Smoke_interface_mismatch/foo.cmi: - Values do not match: let v: string is not included in let v: int - /.../fixtures/Smoke_interface_mismatch/Foo.resi:1:1-10: - Expected declaration - /.../fixtures/Smoke_interface_mismatch/Foo.res:1:5: - Actual declaration \ No newline at end of file + + Actual declaration (/.../fixtures/Smoke_interface_mismatch/Foo.res:1:5): + let v: string + + Expected declaration (/.../fixtures/Smoke_interface_mismatch/Foo.resi:1:1-10): + let v: int \ No newline at end of file From 7641737260fd685feef9c1291bdad63ae88abd91 Mon Sep 17 00:00:00 2001 From: Christoph Knittel Date: Fri, 30 Oct 2026 12:46:12 +0000 Subject: [PATCH 2/4] Label the two sides when runtime representations differ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Why: "The actual declaration states values whose typeof is "object"" reads clumsily: a declaration doesn't state values. The two lines now use the labels of the declaration blocks above them, followed by what each side states. Diagnostic modified (runtime representation reason): Before (diagnostic): Their runtime representations differ: The actual declaration states values whose typeof is "object". The expected declaration states values whose typeof is "string". After (diagnostic): Their runtime representations differ: Actual declaration: typeof "object" Expected declaration: typeof "string" Diagnostic modified (@notUndefined reason): Before (diagnostic): Their runtime representations differ: The expected declaration is @notUndefined, but the actual declaration can hold undefined. After (diagnostic): Their runtime representations differ: Actual declaration: can hold undefined Expected declaration: @notUndefined Mapping modified (what a declaration states, Ast_untagged_variants.describe_declared_values): Before (representation): @instanceOf("Dog") ↦ instances of Dog @instanceOf("Dog") of a subclass ↦ instances of Dog, a subclass of Animal arrays ↦ arrays @typeOf("string") ↦ values whose typeof is "string" nothing ↦ no runtime class or typeof After (representation): @instanceOf("Dog") ↦ instances of Dog @instanceOf("Dog") of a subclass ↦ instances of Dog, a subclass of Animal arrays ↦ arrays @typeOf("string") ↦ typeof "string" nothing ↦ no stated class or typeof Review: Where do the labels come from? From the side names the caller passes, without their article: "the actual" and "declaration" make "Actual declaration"; the type definition errors of Typedecl get "Original definition" and "This definition". Review: Why no period? The lines are labels with a value, like the declaration labels, not sentences. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Kbf3gLpf7RN1MiRcubPgRn Signed-off-by: Christoph Knittel --- compiler/ml/ast_untagged_variants.ml | 10 ++--- compiler/ml/includecore.ml | 39 +++++++++++-------- ...ot_undefined_functor_argument.res.expected | 4 +- ...t_undefined_functor_parameter.res.expected | 4 +- ...otation_interface_over_record.res.expected | 4 +- ...t_undefined_option_implementation.expected | 4 +- ...e_annotation_claimed_by_interface.expected | 4 +- ...ntime_annotation_functor_argument.expected | 4 +- ...ss_runtime_annotation_hidden_base.expected | 4 +- ...time_annotation_hidden_superclass.expected | 4 +- 10 files changed, 44 insertions(+), 37 deletions(-) diff --git a/compiler/ml/ast_untagged_variants.ml b/compiler/ml/ast_untagged_variants.ml index 2b43fdd6fe4..d9d746eb5e3 100644 --- a/compiler/ml/ast_untagged_variants.ml +++ b/compiler/ml/ast_untagged_variants.ml @@ -322,16 +322,16 @@ let runtime_annotation_to_string = function | Type_of block_type -> Printf.sprintf "@%s(\"%s\")" type_of (typeof_name block_type) -(* What a declaration's annotations state, for error messages *) -let describe_declared_block_type = function +(* What a declaration's annotations state about its values, for error + messages *) +let describe_declared_values = function | Some (InstanceType (Class {name; ancestors = []})) -> "instances of " ^ name | Some (InstanceType (Class {name; ancestors})) -> "instances of " ^ name ^ ", a subclass of " ^ String.concat " and " ancestors | Some (InstanceType Array) -> "arrays" - | Some block_type -> - "values whose typeof is \"" ^ typeof_name block_type ^ "\"" - | None -> "no runtime class or typeof" + | Some block_type -> "typeof \"" ^ typeof_name block_type ^ "\"" + | None -> "no stated class or typeof" (* The [@notUndefined], [@instanceOf] or [@typeOf] annotation in [attrs], validated. Only [Typedecl] passes [~loc]; later readers see attributes it diff --git a/compiler/ml/includecore.ml b/compiler/ml/includecore.ml index 62526016a0f..35793986722 100644 --- a/compiler/ml/includecore.ml +++ b/compiler/ml/includecore.ml @@ -191,6 +191,16 @@ type type_mismatch = | Runtime_annotation of string * string | Not_undefined +(* A side of a comparison as a label: "the actual" and "declaration" make + "Actual declaration" *) +let label side decl = + let side = + match String.split_on_char ' ' side with + | "the" :: rest -> String.concat " " rest + | _ -> side + in + String.capitalize_ascii (side ^ " " ^ decl) + let report_type_mismatch0 first second decl ppf err = let pr fmt = Format.fprintf ppf fmt in match err with @@ -235,24 +245,21 @@ let report_type_mismatch0 first second decl ppf err = | Not_undefined -> pr "@[Their runtime representations differ:@,\ - %s %s is @notUndefined,@,\ - but %s %s can hold undefined@]" - (String.capitalize_ascii second) - decl first decl + %s: can hold undefined@,\ + %s: @notUndefined@]" + (label first decl) (label second decl) | Runtime_annotation (declared1, declared2) -> - pr - "@[Their runtime representations differ:@,\ - %s %s states %s.@,\ - %s %s states %s@]" - (String.capitalize_ascii first) - decl declared1 - (String.capitalize_ascii second) - decl declared2 + pr "@[Their runtime representations differ:@,%s: %s@,%s: %s@]" + (label first decl) declared1 (label second decl) declared2 let report_type_mismatch first second decl ppf = List.iter (fun err -> - if err = Manifest then () - else + match err with + | Manifest -> () + (* Its lines are labels, not sentences *) + | Runtime_annotation _ | Not_undefined -> + Format.fprintf ppf "@ %a" (report_type_mismatch0 first second decl) err + | _ -> Format.fprintf ppf "@ %a." (report_type_mismatch0 first second decl) err) let rec compare_constructor_arguments env cstr params1 params2 arg1 arg2 = @@ -397,8 +404,8 @@ let compare_runtime_annotations env id decl1 decl2 = else [ Runtime_annotation - ( Ast_untagged_variants.describe_declared_block_type declared1, - Ast_untagged_variants.describe_declared_block_type declared2 ); + ( Ast_untagged_variants.describe_declared_values declared1, + Ast_untagged_variants.describe_declared_values declared2 ); ] let type_declarations ?(equality = false) ~loc env name decl1 id decl2 = diff --git a/tests/build_tests/super_errors/expected/not_undefined_functor_argument.res.expected b/tests/build_tests/super_errors/expected/not_undefined_functor_argument.res.expected index faaa875e651..c971c01bd19 100644 --- a/tests/build_tests/super_errors/expected/not_undefined_functor_argument.res.expected +++ b/tests/build_tests/super_errors/expected/not_undefined_functor_argument.res.expected @@ -18,5 +18,5 @@ type t Their runtime representations differ: - The expected declaration is @notUndefined, - but the actual declaration can hold undefined. \ No newline at end of file + Actual declaration: can hold undefined + Expected declaration: @notUndefined \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/not_undefined_functor_parameter.res.expected b/tests/build_tests/super_errors/expected/not_undefined_functor_parameter.res.expected index ab95c1bddf5..0caa1a7f979 100644 --- a/tests/build_tests/super_errors/expected/not_undefined_functor_parameter.res.expected +++ b/tests/build_tests/super_errors/expected/not_undefined_functor_parameter.res.expected @@ -19,5 +19,5 @@ type t Their runtime representations differ: - The expected declaration is @notUndefined, - but the actual declaration can hold undefined. \ No newline at end of file + Actual declaration: can hold undefined + Expected declaration: @notUndefined \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/runtime_annotation_interface_over_record.res.expected b/tests/build_tests/super_errors/expected/runtime_annotation_interface_over_record.res.expected index 51420072afc..adc91edef23 100644 --- a/tests/build_tests/super_errors/expected/runtime_annotation_interface_over_record.res.expected +++ b/tests/build_tests/super_errors/expected/runtime_annotation_interface_over_record.res.expected @@ -18,5 +18,5 @@ type t Their runtime representations differ: - The actual declaration states values whose typeof is "object". - The expected declaration states values whose typeof is "string". \ No newline at end of file + Actual declaration: typeof "object" + Expected declaration: typeof "string" \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_not_undefined_option_implementation.expected b/tests/build_tests/super_errors_multi/expected/Cross_not_undefined_option_implementation.expected index eedd19ea8ce..efdcaf1cbde 100644 --- a/tests/build_tests/super_errors_multi/expected/Cross_not_undefined_option_implementation.expected +++ b/tests/build_tests/super_errors_multi/expected/Cross_not_undefined_option_implementation.expected @@ -17,5 +17,5 @@ type t Their runtime representations differ: - The expected declaration is @notUndefined, - but the actual declaration can hold undefined. \ No newline at end of file + Actual declaration: can hold undefined + Expected declaration: @notUndefined \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_claimed_by_interface.expected b/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_claimed_by_interface.expected index dd45d82f18d..98af76b7380 100644 --- a/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_claimed_by_interface.expected +++ b/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_claimed_by_interface.expected @@ -16,5 +16,5 @@ type t Their runtime representations differ: - The actual declaration states no runtime class or typeof. - The expected declaration states values whose typeof is "string". \ No newline at end of file + Actual declaration: no stated class or typeof + Expected declaration: typeof "string" \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_functor_argument.expected b/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_functor_argument.expected index fc4d04a6955..b5a64b4b2db 100644 --- a/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_functor_argument.expected +++ b/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_functor_argument.expected @@ -17,5 +17,5 @@ type dog Their runtime representations differ: - The actual declaration states instances of Dog, a subclass of Animal. - The expected declaration states instances of Dog. \ No newline at end of file + Actual declaration: instances of Dog, a subclass of Animal + Expected declaration: instances of Dog \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_hidden_base.expected b/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_hidden_base.expected index 7d0ac015db8..88c413dbf4d 100644 --- a/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_hidden_base.expected +++ b/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_hidden_base.expected @@ -17,5 +17,5 @@ type dog = private animal Their runtime representations differ: - The actual declaration states instances of Dog, a subclass of Animal. - The expected declaration states instances of Dog. \ No newline at end of file + Actual declaration: instances of Dog, a subclass of Animal + Expected declaration: instances of Dog \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_hidden_superclass.expected b/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_hidden_superclass.expected index 8bd7a11dbd5..a45f58ed706 100644 --- a/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_hidden_superclass.expected +++ b/tests/build_tests/super_errors_multi/expected/Cross_runtime_annotation_hidden_superclass.expected @@ -17,5 +17,5 @@ type dog Their runtime representations differ: - The actual declaration states instances of Dog, a subclass of Animal. - The expected declaration states instances of Dog. \ No newline at end of file + Actual declaration: instances of Dog, a subclass of Animal + Expected declaration: instances of Dog \ No newline at end of file From 3a0228cb0a003bb72eb8ba472c6fc75275bb9f8d Mon Sep 17 00:00:00 2001 From: Christoph Knittel Date: Fri, 30 Oct 2026 13:18:35 +0000 Subject: [PATCH 3/4] Keep the module type comparison around a permutation of its fields Why: Codex review of #9140: when two module types have the same fields in another order, the innermost symptom is the permutation, which shows no declarations, and leaving out the module type comparison around it left only "Illegal permutation of structure fields". A comparison is now left out only when a later symptom shows the declarations that differ. The parser gave a module type declaration in a signature no location, unlike one in a structure, so the expected side printed without a position. It now spans from the name to the end, as in a structure. Diagnostic modified (fields of a module type in another order): Example: module M: { module type T = { let a: int let b: int } } = { module type T = { let b: int let a: int } } Before (diagnostic): Signature mismatch: In module type T: Illegal permutation of structure fields After (diagnostic): Signature mismatch: Actual declaration (include_modtype_permutation.res:7:15-10:3): module type T = { let b: int let a: int } Expected declaration (include_modtype_permutation.res:2:15-5:3): module type T = { let a: int let b: int } In module type T: Illegal permutation of structure fields Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Kbf3gLpf7RN1MiRcubPgRn Signed-off-by: Christoph Knittel --- compiler/ml/includemod.ml | 16 ++++++++++++++-- compiler/syntax/src/res_core.ml | 8 +++++++- .../include_modtype_permutation.res.expected | 12 ++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/compiler/ml/includemod.ml b/compiler/ml/includemod.ml index 79a5d8d326d..fec429fb926 100644 --- a/compiler/ml/includemod.ml +++ b/compiler/ml/includemod.ml @@ -681,10 +681,22 @@ let include_err ~show_context ppf (cxt, env, err) = differ. The modules on the way are left out, as the items at the end say what differs, each under the position it is at. *) let report_error ppf errs = + (* Whether a symptom shows the declarations that differ. A permutation of + fields doesn't, so the comparison of the module types around it stays. *) + let shows_declarations (_, _, symptom) = + match symptom with + | Missing_field _ | Value_descriptions _ | Type_declarations _ + | Extension_constructors _ | Module_types _ | Modtype_infos _ -> + true + | Modtype_permutation | Interface_mismatch _ | Unbound_modtype_path _ + | Unbound_module_path _ | Invalid_module_alias _ -> + false + in let rec shown = function | [] -> [] - | [err] -> [err] - | (_, _, (Module_types _ | Modtype_infos _)) :: rest -> shown rest + | (_, _, (Module_types _ | Modtype_infos _)) :: rest + when List.exists shows_declarations rest -> + shown rest | err :: rest -> err :: shown rest in let rec print ppf previous_cxt = function diff --git a/compiler/syntax/src/res_core.ml b/compiler/syntax/src/res_core.ml index 0f6aeb23de5..7dd62d872f9 100644 --- a/compiler/syntax/src/res_core.ml +++ b/compiler/syntax/src/res_core.ml @@ -7244,6 +7244,7 @@ and parse_module_declaration_or_alias ~attrs p = and parse_module_type_declaration ~attrs ~start_pos p = Parser.expect Typ p; + let name_start = Parser.start_pos p in let module_name = match Parser.peek p with | Uident ident -> @@ -7265,7 +7266,12 @@ and parse_module_type_declaration ~attrs ~start_pos p = Some (parse_module_type p) | _ -> None in - let module_decl = Ast_helper.Mtd.mk ~attrs ?typ module_name in + (* From the name, like a module type declaration in a structure *) + let module_decl = + Ast_helper.Mtd.mk ~attrs + ~loc:(mk_loc name_start (Parser.position p)) + ?typ module_name + in Ast_helper.Sig.modtype ~loc:(mk_loc start_pos (Parser.position p)) module_decl and parse_sign_let_desc ~attrs p = diff --git a/tests/build_tests/super_errors/expected/include_modtype_permutation.res.expected b/tests/build_tests/super_errors/expected/include_modtype_permutation.res.expected index 72d4be407da..022f9a64c8c 100644 --- a/tests/build_tests/super_errors/expected/include_modtype_permutation.res.expected +++ b/tests/build_tests/super_errors/expected/include_modtype_permutation.res.expected @@ -13,6 +13,18 @@ Signature mismatch: + Actual declaration (/.../fixtures/include_modtype_permutation.res:7:15-10:3): + module type T = { + let b: int + let a: int + } + + Expected declaration (/.../fixtures/include_modtype_permutation.res:2:15-5:3): + module type T = { + let a: int + let b: int + } + In module type T: Illegal permutation of structure fields \ No newline at end of file From 42eed6ab0055317e1e0aca526785d3c98120c695 Mon Sep 17 00:00:00 2001 From: Christoph Knittel Date: Fri, 30 Oct 2026 13:34:43 +0000 Subject: [PATCH 4/4] Report the actual side of a module type found by comparing the other way Why: Codex review of #9140: two module types must be equal, and check_modtype_equiv also includes the expected one in the actual one. An item only the actual module type has is found by that reverse check, but the error called it required and its declaration the expected one. This was mislabelled before too, and the comparison of the two module types printed above it was the only hint, which the new layout leaves out. The reverse check now adds a Reverse position to the path. Like a functor parameter it swaps the sides, and it is not printed. Diagnostic modified (an item only the actual module type has): Example: module M: { module type T = { let a: int } } = { module type T = { let a: int let b: int } } Before (diagnostic): In module type T: The value `b` is required but not provided. Expected declaration (inclusion_layout_module_type_extra.res:10:5-14): let b: int After (diagnostic): In module type T: The value `b` is only present in the actual declaration. Actual declaration (inclusion_layout_module_type_extra.res:10:5-14): let b: int Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Kbf3gLpf7RN1MiRcubPgRn Signed-off-by: Christoph Knittel --- compiler/ml/includemod.ml | 34 +++++++++++++------ compiler/ml/includemod.mli | 3 ++ ...sion_layout_module_type_extra.res.expected | 21 ++++++++++++ .../inclusion_layout_module_type_extra.res | 12 +++++++ 4 files changed, 59 insertions(+), 11 deletions(-) create mode 100644 tests/build_tests/super_errors/expected/inclusion_layout_module_type_extra.res.expected create mode 100644 tests/build_tests/super_errors/fixtures/inclusion_layout_module_type_extra.res diff --git a/compiler/ml/includemod.ml b/compiler/ml/includemod.ml index fec429fb926..aee078f519a 100644 --- a/compiler/ml/includemod.ml +++ b/compiler/ml/includemod.ml @@ -43,6 +43,9 @@ type pos = | Modtype of Ident.t | Arg of Ident.t | Body of Ident.t + | Reverse + (** The module types at this position compared the other way round, in + the second half of an equivalence check *) type error = pos list * Env.t * symptom exception Error of error list @@ -423,7 +426,7 @@ and modtype_infos ~loc env cxt subst id info1 info2 = and check_modtype_equiv ~loc env cxt mty1 mty2 = match ( modtypes ~loc env cxt Subst.identity mty1 mty2, - modtypes ~loc env cxt Subst.identity mty2 mty1 ) + modtypes ~loc env (Reverse :: cxt) Subst.identity mty2 mty1 ) with | Tcoerce_none, Tcoerce_none -> () | _c1, _c2 -> @@ -555,11 +558,18 @@ let show_arity_mismatch env ppf (d1 : value_description) let include_symptom ~swapped env ppf = function | Missing_field (id, loc, kind, item) -> - fprintf ppf "The %s `%a` is required but not provided.@,@,%a" kind ident id - (show_declaration - (if swapped then "Actual declaration" else "Expected declaration") - loc signature) - [item] + (* Reversed, the item is one the actual declaration has and the expected + one lacks *) + if swapped then + fprintf ppf "The %s `%a` is only present in the actual declaration.@,@,%a" + kind ident id + (show_declaration "Actual declaration" loc signature) + [item] + else + fprintf ppf "The %s `%a` is required but not provided.@,@,%a" kind ident + id + (show_declaration "Expected declaration" loc signature) + [item] | Value_descriptions (id, d1, d2) -> show_declarations ~swapped (value_description id) ppf (d1, d1.val_loc, d2, d2.val_loc); @@ -604,6 +614,7 @@ let rec context ppf = function fprintf ppf "@[<2>module type %a =@ %a@]" ident id context_mty rem | Body x :: rem -> fprintf ppf "(%s) =>@ %a" (argname x) context_mty rem | Arg x :: rem -> fprintf ppf "(%a:@ %a) => ..." ident x context_mty rem + | Reverse :: rem -> context ppf rem | [] -> fprintf ppf "" and context_mty ppf = function @@ -623,10 +634,10 @@ let path_of_modules = function let rec subm path = function | [] -> Some path | Module id :: rem -> subm (Pdot (path, Ident.name id, -1)) rem - | (Modtype _ | Arg _ | Body _) :: _ -> None + | (Modtype _ | Arg _ | Body _ | Reverse) :: _ -> None in subm (Pident id) rem - | (Modtype _ | Arg _ | Body _) :: _ | [] -> None + | (Modtype _ | Arg _ | Body _ | Reverse) :: _ | [] -> None (* Where in the module an error is, as a line before it. [cxt] is outermost first. A module type or a functor's result at the end of a module path is @@ -659,12 +670,13 @@ let context ppf cxt = | None, _ -> fprintf ppf "@[At position@ %a@]@,@," context cxt let include_err ~show_context ppf (cxt, env, err) = - (* Inclusion is reversed in each functor parameter on the way *) + (* Inclusion is reversed in each functor parameter on the way, and in the + second half of an equivalence check of module types *) let swapped = List.length (List.filter (function - | Arg _ -> true + | Arg _ | Reverse -> true | Module _ | Modtype _ | Body _ -> false) cxt) mod 2 @@ -673,7 +685,7 @@ let include_err ~show_context ppf (cxt, env, err) = Printtyp.wrap_printing_env env (fun () -> fprintf ppf "@[%a%a@]" (fun ppf cxt -> if show_context then context ppf cxt) - (List.rev cxt) + (List.rev (List.filter (fun pos -> pos <> Reverse) cxt)) (include_symptom ~swapped env) err) diff --git a/compiler/ml/includemod.mli b/compiler/ml/includemod.mli index 83cf0765aa1..e50087dd12c 100644 --- a/compiler/ml/includemod.mli +++ b/compiler/ml/includemod.mli @@ -61,6 +61,9 @@ type pos = | Modtype of Ident.t | Arg of Ident.t | Body of Ident.t + | Reverse + (** The module types at this position compared the other way round, in + the second half of an equivalence check *) type error = pos list * Env.t * symptom exception Error of error list diff --git a/tests/build_tests/super_errors/expected/inclusion_layout_module_type_extra.res.expected b/tests/build_tests/super_errors/expected/inclusion_layout_module_type_extra.res.expected new file mode 100644 index 00000000000..b28e8df4922 --- /dev/null +++ b/tests/build_tests/super_errors/expected/inclusion_layout_module_type_extra.res.expected @@ -0,0 +1,21 @@ + + We've found a bug for you! + /.../fixtures/inclusion_layout_module_type_extra.res:7:5-12:1 + + 5 │ let a: int + 6 │ } + 7 │ } = { + 8 │  module type T = { + . │ ... + 11 │  } + 12 │ } + 13 │ + + Signature mismatch: + + In module type T: + + The value `b` is only present in the actual declaration. + + Actual declaration (/.../fixtures/inclusion_layout_module_type_extra.res:10:5-14): + let b: int \ No newline at end of file diff --git a/tests/build_tests/super_errors/fixtures/inclusion_layout_module_type_extra.res b/tests/build_tests/super_errors/fixtures/inclusion_layout_module_type_extra.res new file mode 100644 index 00000000000..aa6e2154686 --- /dev/null +++ b/tests/build_tests/super_errors/fixtures/inclusion_layout_module_type_extra.res @@ -0,0 +1,12 @@ +// Module types must be equal: an item only the actual module type has is +// found by comparing the other way round, and reported on the actual side +module M: { + module type T = { + let a: int + } +} = { + module type T = { + let a: int + let b: int + } +}