diff --git a/CHANGELOG.md b/CHANGELOG.md index 85350be7e0..34d28f033b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,7 @@ - Expand `super_errors` fixture coverage for warnings and errors. https://github.com/rescript-lang/rescript/pull/8429 - Run `super_errors` fixtures in parallel (~2.4× faster locally). https://github.com/rescript-lang/rescript/pull/8430 - Expand `super_errors` fixture coverage for the remaining reachable single-file error variants. https://github.com/rescript-lang/rescript/pull/8432 +- Add a multi-file fixture harness (`super_errors_multi`) for cross-module errors and warnings. https://github.com/rescript-lang/rescript/pull/8433 # 13.0.0-alpha.4 diff --git a/scripts/format.sh b/scripts/format.sh index daf6fd988b..4d504f98c0 100755 --- a/scripts/format.sh +++ b/scripts/format.sh @@ -8,7 +8,7 @@ echo Formatting OCaml code... opam exec -- dune build @fmt --auto-promote echo Formatting ReScript code... -files=$(find packages tests -type f \( -name "*.res" -o -name "*.resi" \) ! -name "syntaxErrors*" ! -name "generated_mocha_test.res" ! -path "tests/build_tests/super_errors/fixtures/break_keyword_binding.res" ! -path "tests/syntax_tests*" ! -path "tests/analysis_tests/tests*" ! -path "*/node_modules/*") +files=$(find packages tests -type f \( -name "*.res" -o -name "*.resi" \) ! -name "syntaxErrors*" ! -name "generated_mocha_test.res" ! -path "tests/build_tests/super_errors/fixtures/break_keyword_binding.res" ! -path "tests/build_tests/super_errors_multi/fixtures/Iface_not_compiled/*" ! -path "tests/syntax_tests*" ! -path "tests/analysis_tests/tests*" ! -path "*/node_modules/*") ./cli/rescript.js format $files echo Formatting JS code... diff --git a/scripts/format_check.sh b/scripts/format_check.sh index 84edccf479..b4a57d02c1 100755 --- a/scripts/format_check.sh +++ b/scripts/format_check.sh @@ -17,7 +17,7 @@ case "$(uname -s)" in fi echo "Checking ReScript code formatting..." - files=$(find packages tests -type f \( -name "*.res" -o -name "*.resi" \) ! -name "syntaxErrors*" ! -name "generated_mocha_test.res" ! -path "tests/build_tests/super_errors/fixtures/break_keyword_binding.res" ! -path "tests/syntax_tests*" ! -path "tests/analysis_tests/tests*" ! -path "*/node_modules/*") + files=$(find packages tests -type f \( -name "*.res" -o -name "*.resi" \) ! -name "syntaxErrors*" ! -name "generated_mocha_test.res" ! -path "tests/build_tests/super_errors/fixtures/break_keyword_binding.res" ! -path "tests/build_tests/super_errors_multi/fixtures/Iface_not_compiled/*" ! -path "tests/syntax_tests*" ! -path "tests/analysis_tests/tests*" ! -path "*/node_modules/*") if ./cli/rescript.js format --check $files; then printf "${successGreen}✅ ReScript code formatting ok.${reset}\n" else diff --git a/tests/build_tests/super_errors_multi/.gitignore b/tests/build_tests/super_errors_multi/.gitignore new file mode 100644 index 0000000000..d9d632f901 --- /dev/null +++ b/tests/build_tests/super_errors_multi/.gitignore @@ -0,0 +1,6 @@ +fixtures/**/*.cmi +fixtures/**/*.cmj +fixtures/**/*.cmt +fixtures/**/*.cmti +fixtures/**/*.mjs +fixtures/**/*.js diff --git a/tests/build_tests/super_errors_multi/expected/Cross_abstract_type_construction.expected b/tests/build_tests/super_errors_multi/expected/Cross_abstract_type_construction.expected new file mode 100644 index 0000000000..c3c8d10770 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Cross_abstract_type_construction.expected @@ -0,0 +1,10 @@ +===== User.res ===== + + We've found a bug for you! + /.../fixtures/Cross_abstract_type_construction/User.res:1:18 + + 1 │ let bad: Abs.t = 1 + 2 │ + + This has type: int + But it's expected to have type: Abs.t \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_async_promise_mismatch.expected b/tests/build_tests/super_errors_multi/expected/Cross_async_promise_mismatch.expected new file mode 100644 index 0000000000..3f1fdb107d --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Cross_async_promise_mismatch.expected @@ -0,0 +1,12 @@ +===== User.res ===== + + We've found a bug for you! + /.../fixtures/Cross_async_promise_mismatch/User.res:1:29-44 + + 1 │ let consume = (): string => Lib.fetch("api") + 2 │ + + This has type: promise + But it's expected to have type: string + + - Did you mean to await this promise before using it? \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_chain_of_aliases.expected b/tests/build_tests/super_errors_multi/expected/Cross_chain_of_aliases.expected new file mode 100644 index 0000000000..2b762fd2a9 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Cross_chain_of_aliases.expected @@ -0,0 +1,12 @@ +===== C.res ===== + + We've found a bug for you! + /.../fixtures/Cross_chain_of_aliases/C.res:1:23-29 + + 1 │ let v: B.Reexport.t = "wrong" + 2 │ + + This has type: string + But it's expected to have type: B.Reexport.t (defined as int) + + You can convert string to int with Int.fromString. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_dependent_clash.expected b/tests/build_tests/super_errors_multi/expected/Cross_dependent_clash.expected new file mode 100644 index 0000000000..479acd9337 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Cross_dependent_clash.expected @@ -0,0 +1,9 @@ +===== User.res ===== + + We've found a bug for you! + /.../fixtures/Cross_dependent_clash/User.res:1:21-34 + + 1 │ let _ = Sender.send({to_: "alice"}) + 2 │ + + Some required record fields are missing: body. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_deprecated_type.expected b/tests/build_tests/super_errors_multi/expected/Cross_deprecated_type.expected new file mode 100644 index 0000000000..8c4bb3af7b --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Cross_deprecated_type.expected @@ -0,0 +1,10 @@ +===== User.res ===== + + Warning number 3 + /.../fixtures/Cross_deprecated_type/User.res:1:8-15 + + 1 │ let v: Legacy.t = 1 + 2 │ + + deprecated: Legacy.t + Use newType instead \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_deprecated_value.expected b/tests/build_tests/super_errors_multi/expected/Cross_deprecated_value.expected new file mode 100644 index 0000000000..79d17efb7c --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Cross_deprecated_value.expected @@ -0,0 +1,10 @@ +===== User.res ===== + + Warning number 3 + /.../fixtures/Cross_deprecated_value/User.res:1:9-22 + + 1 │ let x = Legacy.compute(1) + 2 │ + + deprecated: Legacy.compute + Use computeNew instead \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_dict_pattern.expected b/tests/build_tests/super_errors_multi/expected/Cross_dict_pattern.expected new file mode 100644 index 0000000000..0350dffa20 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Cross_dict_pattern.expected @@ -0,0 +1,13 @@ +===== User.res ===== + + Warning number 8 + /.../fixtures/Cross_dict_pattern/User.res:2:3-4:3 + + 1 │ let read = (cfg: Defs.config) => + 2 │ switch cfg { + 3 │  | dict{"port": p} => p + 4 │  } + 5 │ + + You forgot to handle a possible case here, for example: + | {port: ?None} \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_exception_arity_mismatch.expected b/tests/build_tests/super_errors_multi/expected/Cross_exception_arity_mismatch.expected new file mode 100644 index 0000000000..5f6cc2ef6c --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Cross_exception_arity_mismatch.expected @@ -0,0 +1,9 @@ +===== User.res ===== + + We've found a bug for you! + /.../fixtures/Cross_exception_arity_mismatch/User.res:1:28-52 + + 1 │ let raise_it = () => throw(Errors.ParseError("oops")) + 2 │ + + This variant constructor Errors.ParseError expects 2 arguments, but it's only being passed 1. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_external_argument_clash.expected b/tests/build_tests/super_errors_multi/expected/Cross_external_argument_clash.expected new file mode 100644 index 0000000000..7c8ec25834 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Cross_external_argument_clash.expected @@ -0,0 +1,12 @@ +===== User.res ===== + + We've found a bug for you! + /.../fixtures/Cross_external_argument_clash/User.res:1:22-23 + + 1 │ let x = Ffi.parseInt(42) + 2 │ + + This has type: int + But this function argument is expecting: string + + You can convert int to string with Int.toString. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_gadt_pattern.expected b/tests/build_tests/super_errors_multi/expected/Cross_gadt_pattern.expected new file mode 100644 index 0000000000..7222bfb318 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Cross_gadt_pattern.expected @@ -0,0 +1,12 @@ +===== User.res ===== + + We've found a bug for you! + /.../fixtures/Cross_gadt_pattern/User.res:3:5-7 + + 1 │ let bad: Gadt.t => string = x => + 2 │ switch x { + 3 │ | Int(n) => n + 4 │ | Pair(_, _) => "pair" + 5 │ } + + The GADT constructor Int of type Gadt.t must be qualified in this pattern. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_hidden_through_interface.expected b/tests/build_tests/super_errors_multi/expected/Cross_hidden_through_interface.expected new file mode 100644 index 0000000000..bf099d3730 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Cross_hidden_through_interface.expected @@ -0,0 +1,17 @@ +===== User.res ===== + + We've found a bug for you! + /.../fixtures/Cross_hidden_through_interface/User.res:2:16 + + 1 │ let v = Defs.make() + 2 │ let leaked = v.x + 3 │ + + You're trying to access the record field x, but the thing you're trying to access it on is not a record. + +The type of the thing you're trying to access it on is: + +Defs.t + + + Only records have fields that can be accessed with dot notation. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_inline_record_constructor.expected b/tests/build_tests/super_errors_multi/expected/Cross_inline_record_constructor.expected new file mode 100644 index 0000000000..6a1cdb1ef8 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Cross_inline_record_constructor.expected @@ -0,0 +1,9 @@ +===== User.res ===== + + We've found a bug for you! + /.../fixtures/Cross_inline_record_constructor/User.res:1:9-23 + + 1 │ let v = Defs.Pair(1, 2) + 2 │ + + This constructor expects an inlined record argument. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_module_alias_dot_access.expected b/tests/build_tests/super_errors_multi/expected/Cross_module_alias_dot_access.expected new file mode 100644 index 0000000000..d4e1595922 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Cross_module_alias_dot_access.expected @@ -0,0 +1,11 @@ +===== User.res ===== + + We've found a bug for you! + /.../fixtures/Cross_module_alias_dot_access/User.res:3:21-26 + + 1 │ module S = Lib.Settings + 2 │ + 3 │ let port = S.port + S.host + 4 │ + + The value host can't be found in S \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_module_open_shadow_label_constructor.expected b/tests/build_tests/super_errors_multi/expected/Cross_module_open_shadow_label_constructor.expected new file mode 100644 index 0000000000..8831e4634f --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Cross_module_open_shadow_label_constructor.expected @@ -0,0 +1,24 @@ +===== User.res ===== + + Warning number 45 + /.../fixtures/Cross_module_open_shadow_label_constructor/User.res:5:1-6 + + 3 │ | Bar + 4 │ + 5 │ open A + 6 │ + 7 │ let v = Foo + + this open statement shadows the constructor Foo (which is later used) + + + Warning number 41 + /.../fixtures/Cross_module_open_shadow_label_constructor/User.res:7:9-11 + + 5 │ open A + 6 │ + 7 │ let v = Foo + 8 │ + + Foo belongs to several types: A.t t +The first one was selected. Disambiguate if this is wrong. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_module_record_disambiguation.expected b/tests/build_tests/super_errors_multi/expected/Cross_module_record_disambiguation.expected new file mode 100644 index 0000000000..33e0bdfb77 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Cross_module_record_disambiguation.expected @@ -0,0 +1,11 @@ +===== User.res ===== + + We've found a bug for you! + /.../fixtures/Cross_module_record_disambiguation/User.res:1:19-23 + + 1 │ let r: Point.t = {width: 1, height: 2} + 2 │ + + The field width does not belong to type Point.t + + This record expression is expected to have type Point.t \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_module_type_only_no_impl.expected b/tests/build_tests/super_errors_multi/expected/Cross_module_type_only_no_impl.expected new file mode 100644 index 0000000000..3ef0fee69d --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Cross_module_type_only_no_impl.expected @@ -0,0 +1,12 @@ +===== User.res ===== + + We've found a bug for you! + /.../fixtures/Cross_module_type_only_no_impl/User.res:1:17-23 + + 1 │ let x: string = Iface.v + 2 │ + + This has type: int + But it's expected to have type: string + + You can convert int to string with Int.toString. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_open_shadows_identifier.expected b/tests/build_tests/super_errors_multi/expected/Cross_open_shadows_identifier.expected new file mode 100644 index 0000000000..f077840896 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Cross_open_shadows_identifier.expected @@ -0,0 +1,11 @@ +===== User.res ===== + + Warning number 44 + /.../fixtures/Cross_open_shadows_identifier/User.res:2:1-6 + + 1 │ let answer = "outer" + 2 │ open A + 3 │ let _ = answer + 4 │ + + this open statement shadows the value identifier answer (which is later used) \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_optional_label_omitted.expected b/tests/build_tests/super_errors_multi/expected/Cross_optional_label_omitted.expected new file mode 100644 index 0000000000..8fd5d7769c --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Cross_optional_label_omitted.expected @@ -0,0 +1,14 @@ +===== User.res ===== + + We've found a bug for you! + /.../fixtures/Cross_optional_label_omitted/User.res:1:9-17 + + 1 │ let s = Lib.greet() + 2 │ + + This function call is incorrect. + The function has type: + (~name: string, ~greeting: string=?, unit) => string + + - Missing arguments that must be provided: ~name + - Hint: Did you want to partially apply the function? You can do that by putting `...` just before the closing parens of the function call. Example: yourFn(~arg1=someVar, ...) \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_polyvariant_constraint.expected b/tests/build_tests/super_errors_multi/expected/Cross_polyvariant_constraint.expected new file mode 100644 index 0000000000..c3ddd67026 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Cross_polyvariant_constraint.expected @@ -0,0 +1,16 @@ +===== User.res ===== + + We've found a bug for you! + /.../fixtures/Cross_polyvariant_constraint/User.res:1:19-25 + + 1 │ let v = Spec.pick(#Purple) + 2 │ + + This has type: [> #Purple] + But this function argument is expecting: Spec.allowed + + The second polymorphic variant is closed and doesn't include the constructor: #Purple. + + Possible solutions: + - Either make the second variant open so it can accept additional constructors. To do this, make sure the type starts with [> instead of [ + - Or add the missing constructor to it. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_private_constructor_pattern.expected b/tests/build_tests/super_errors_multi/expected/Cross_private_constructor_pattern.expected new file mode 100644 index 0000000000..ef3cce1c23 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Cross_private_constructor_pattern.expected @@ -0,0 +1,30 @@ +===== Result.res ===== + + Warning number 37 + /.../fixtures/Cross_private_constructor_pattern/Result.res:1:1-3:11 + + 1 │ type t = + 2 │  | Loaded(string) + 3 │  | Loading + 4 │ + 5 │ let loaded = s => Loaded(s) + + constructor Loading is never used to build values. +Its type is exported as a private type. + + +===== User.res ===== + + We've found a bug for you! + /.../fixtures/Cross_private_constructor_pattern/User.res:1:9-21 + + 1 │ let x = Result.Loaded("hello") + 2 │ + + The variant constructor Result.Loaded can't be found. + + - If it's defined in another module or file, bring it into scope by: + - Prefixing it with said module name: TheModule.Result.Loaded + - Or specifying its type: let theValue: TheModule.theType = Result.Loaded + - Constructors and modules are both capitalized. Did you want the latter? + Then instead of let foo = Bar, try module Foo = Bar. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_qualified_constructor_mismatch.expected b/tests/build_tests/super_errors_multi/expected/Cross_qualified_constructor_mismatch.expected new file mode 100644 index 0000000000..f89b459b4e --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Cross_qualified_constructor_mismatch.expected @@ -0,0 +1,10 @@ +===== User.res ===== + + We've found a bug for you! + /.../fixtures/Cross_qualified_constructor_mismatch/User.res:1:18-26 + + 1 │ let v: Shape.t = Color.Red + 2 │ + + The constructor Color.Red belongs to the variant type Color.t + but a constructor was expected belonging to the variant type Shape.t \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_record_extra_field.expected b/tests/build_tests/super_errors_multi/expected/Cross_record_extra_field.expected new file mode 100644 index 0000000000..6c1d502620 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Cross_record_extra_field.expected @@ -0,0 +1,11 @@ +===== User.res ===== + + We've found a bug for you! + /.../fixtures/Cross_record_extra_field/User.res:1:30-34 + + 1 │ let r: Defs.t = {a: 1, b: 2, extra: 3} + 2 │ + + The field extra does not belong to type Defs.t + + This record expression is expected to have type Defs.t \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_uncurried_arity.expected b/tests/build_tests/super_errors_multi/expected/Cross_uncurried_arity.expected new file mode 100644 index 0000000000..a229159ea5 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Cross_uncurried_arity.expected @@ -0,0 +1,9 @@ +===== User.res ===== + + We've found a bug for you! + /.../fixtures/Cross_uncurried_arity/User.res:1:23-29 + + 1 │ let bad: int => int = Lib.add + 2 │ + + This function is expected to have 1 argument, but has 3 \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_unused_open.expected b/tests/build_tests/super_errors_multi/expected/Cross_unused_open.expected new file mode 100644 index 0000000000..6ceb8001ec --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Cross_unused_open.expected @@ -0,0 +1,10 @@ +===== User.res ===== + + Warning number 33 + /.../fixtures/Cross_unused_open/User.res:1:1-12 + + 1 │ open Helpers + 2 │ + 3 │ let v = 42 + + unused open Helpers. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Cross_variant_spread.expected b/tests/build_tests/super_errors_multi/expected/Cross_variant_spread.expected new file mode 100644 index 0000000000..8647cc9529 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Cross_variant_spread.expected @@ -0,0 +1,13 @@ +===== Ext.res ===== + + We've found a bug for you! + /.../fixtures/Cross_variant_spread/Ext.res:3:8-13 + + 1 │ type t = + 2 │ | A + 3 │ | ...Base.t + 4 │ | C + 5 │ + + Variant Base.t has a constructor named A, but a constructor named A already exists in the variant it's spread into. + You cannot spread variants with overlapping constructors. \ 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 new file mode 100644 index 0000000000..ac624fa56f --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Iface_extension_constructors.expected @@ -0,0 +1,15 @@ +===== Foo.res ===== + + We've found a bug for you! + /.../fixtures/Iface_extension_constructors/Foo.res + + The implementation /.../fixtures/Iface_extension_constructors/Foo.res + does not match the interface /.../fixtures/Iface_extension_constructors/foo.cmi: + Extension declarations do not match: + 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 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 new file mode 100644 index 0000000000..1b0534cb66 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Iface_field_mutable_mismatch.expected @@ -0,0 +1,19 @@ +===== Foo.res ===== + + We've found a bug for you! + /.../fixtures/Iface_field_mutable_mismatch/Foo.res:1:1-21 + + 1 │ type t = {count: int} + 2 │ + + 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: + type t = {count: int} + is not included in + 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_optional_mismatch.expected b/tests/build_tests/super_errors_multi/expected/Iface_field_optional_mismatch.expected new file mode 100644 index 0000000000..56261f1f0f --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Iface_field_optional_mismatch.expected @@ -0,0 +1,19 @@ +===== Foo.res ===== + + We've found a bug for you! + /.../fixtures/Iface_field_optional_mismatch/Foo.res:1:1-28 + + 1 │ type t = {a: int, b: string} + 2 │ + + 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: + type t = {a: int, b: string} + is not included in + 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_missing_value.expected b/tests/build_tests/super_errors_multi/expected/Iface_missing_value.expected new file mode 100644 index 0000000000..b69da19d07 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Iface_missing_value.expected @@ -0,0 +1,14 @@ +===== Foo.res ===== + + We've found a bug for you! + /.../fixtures/Iface_missing_value/Foo.resi:2:1-13 + + 1 │ let a: int + 2 │ let b: string + 3 │ + + 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 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 new file mode 100644 index 0000000000..2cf2a858fb --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Iface_modtype_infos.expected @@ -0,0 +1,30 @@ +===== Foo.res ===== + + We've found a bug for you! + /.../fixtures/Iface_modtype_infos/Foo.res + + 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 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 new file mode 100644 index 0000000000..6276a98fcd --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Iface_module_types.expected @@ -0,0 +1,22 @@ +===== Foo.res ===== + + We've found a bug for you! + /.../fixtures/Iface_module_types/Foo.res + + 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 diff --git a/tests/build_tests/super_errors_multi/expected/Iface_not_compiled.expected b/tests/build_tests/super_errors_multi/expected/Iface_not_compiled.expected new file mode 100644 index 0000000000..9075954a61 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Iface_not_compiled.expected @@ -0,0 +1,18 @@ +===== Foo.resi ===== + + Syntax error! + /.../fixtures/Iface_not_compiled/Foo.resi:1:12 + + 1 │ let v: int = + 2 │ + + I'm not sure what to parse here when looking at "=". + + +===== Foo.res ===== + + We've found a bug for you! + /.../fixtures/Iface_not_compiled/Foo.res + + Could not find the .cmi file for interface + /.../fixtures/Iface_not_compiled/Foo.resi. \ 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 new file mode 100644 index 0000000000..621a81f6ec --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Iface_privacy_mismatch.expected @@ -0,0 +1,19 @@ +===== Foo.res ===== + + We've found a bug for you! + /.../fixtures/Iface_privacy_mismatch/Foo.res:1:1-20 + + 1 │ type t = private int + 2 │ + + The implementation /.../fixtures/Iface_privacy_mismatch/Foo.res + does not match the interface /.../fixtures/Iface_privacy_mismatch/foo.cmi: + Type declarations do not match: + type t = int + is not included in + 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_tag_name_mismatch.expected b/tests/build_tests/super_errors_multi/expected/Iface_tag_name_mismatch.expected new file mode 100644 index 0000000000..96795bfb81 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Iface_tag_name_mismatch.expected @@ -0,0 +1,22 @@ +===== Foo.res ===== + + We've found a bug for you! + /.../fixtures/Iface_tag_name_mismatch/Foo.res:2:1-4:5 + + 1 │ @tag("type") + 2 │ type t = + 3 │  | @as("a") A + 4 │  | B + 5 │ + + 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: + type t = @as("a") A | B + is not included in + 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 new file mode 100644 index 0000000000..16ea04ada1 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Iface_type_decl_record.expected @@ -0,0 +1,19 @@ +===== Foo.res ===== + + We've found a bug for you! + /.../fixtures/Iface_type_decl_record/Foo.res:1:1-25 + + 1 │ type t = {x: int, z: int} + 2 │ + + 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: + type t = {x: int, z: int} + is not included in + 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 new file mode 100644 index 0000000000..e3d5b75c8d --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Iface_type_decl_variant.expected @@ -0,0 +1,21 @@ +===== Foo.res ===== + + We've found a bug for you! + /.../fixtures/Iface_type_decl_variant/Foo.res:1:1-3:13 + + 1 │ type t = + 2 │  | A + 3 │  | B(string) + 4 │ + + 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: + type t = A | B(string) + is not included in + 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 field 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 new file mode 100644 index 0000000000..3d6d2f2df1 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Iface_unboxed_variant_mismatch.expected @@ -0,0 +1,20 @@ +===== Foo.res ===== + + We've found a bug for you! + /.../fixtures/Iface_unboxed_variant_mismatch/Foo.res:1:1-18 + + 1 │ type t = Wrap(int) + 2 │ + + 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: + type t = Wrap(int) + is not included in + @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 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 new file mode 100644 index 0000000000..6f9df31b05 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Iface_value_descriptions.expected @@ -0,0 +1,18 @@ +===== Foo.res ===== + + We've found a bug for you! + /.../fixtures/Iface_value_descriptions/Foo.res:1:5-11 + + 1 │ let compute = (s: string) => String.length(s) + 2 │ + + The implementation /.../fixtures/Iface_value_descriptions/Foo.res + does not match the interface /.../fixtures/Iface_value_descriptions/foo.cmi: + Values do not match: + 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 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 new file mode 100644 index 0000000000..a9e569f984 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Iface_variant_representation_mismatch.expected @@ -0,0 +1,21 @@ +===== Foo.res ===== + + We've found a bug for you! + /.../fixtures/Iface_variant_representation_mismatch/Foo.res:1:1-3:5 + + 1 │ type t = + 2 │  | @as(0) A + 3 │  | B + 4 │ + + 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: + type t = @as(0) A | B + is not included in + 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/Modules_not_allowed_toplevel.expected b/tests/build_tests/super_errors_multi/expected/Modules_not_allowed_toplevel.expected new file mode 100644 index 0000000000..7bbe7fbdc7 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Modules_not_allowed_toplevel.expected @@ -0,0 +1,11 @@ +===== User.res ===== + + We've found a bug for you! + /.../fixtures/Modules_not_allowed_toplevel/User.res:8:5-13 + + 6 │ ) + 7 │ + 8 │ let module(M) = make() + 9 │ + + Modules are not allowed in this pattern. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Smoke_cross_module_type_clash.expected b/tests/build_tests/super_errors_multi/expected/Smoke_cross_module_type_clash.expected new file mode 100644 index 0000000000..73cdc4f6da --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Smoke_cross_module_type_clash.expected @@ -0,0 +1,12 @@ +===== User.res ===== + + We've found a bug for you! + /.../fixtures/Smoke_cross_module_type_clash/User.res:1:23-29 + + 1 │ let v = Lib.increment("hello") + 2 │ + + This has type: string + But this function argument is expecting: int + + You can convert string to int with Int.fromString. \ 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 new file mode 100644 index 0000000000..96c0f47f00 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Smoke_interface_mismatch.expected @@ -0,0 +1,15 @@ +===== Foo.res ===== + + We've found a bug for you! + /.../fixtures/Smoke_interface_mismatch/Foo.res:1:5 + + 1 │ let v = "not an int" + 2 │ + + 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 diff --git a/tests/build_tests/super_errors_multi/expected/Smoke_missing_field.expected b/tests/build_tests/super_errors_multi/expected/Smoke_missing_field.expected new file mode 100644 index 0000000000..0012f34f13 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Smoke_missing_field.expected @@ -0,0 +1,9 @@ +===== Use.res ===== + + We've found a bug for you! + /.../fixtures/Smoke_missing_field/Use.res:1:23-28 + + 1 │ let bad: Defs.point = {x: 1} + 2 │ + + Some required record fields are missing: y. \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Smoke_unbound_module_reference.expected b/tests/build_tests/super_errors_multi/expected/Smoke_unbound_module_reference.expected new file mode 100644 index 0000000000..b22c467082 --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Smoke_unbound_module_reference.expected @@ -0,0 +1,12 @@ +===== Consumer.res ===== + + We've found a bug for you! + /.../fixtures/Smoke_unbound_module_reference/Consumer.res:1:9-31 + + 1 │ let x = NonexistentModule.value + 2 │ + + The module or file NonexistentModule can't be found. + - If it's a third-party dependency: + - Did you add it to the "dependencies" or "dev-dependencies" in rescript.json? + - Did you include the file's directory to the "sources" in rescript.json? \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/expected/Unexpected_existential_in_let.expected b/tests/build_tests/super_errors_multi/expected/Unexpected_existential_in_let.expected new file mode 100644 index 0000000000..719a57ea4a --- /dev/null +++ b/tests/build_tests/super_errors_multi/expected/Unexpected_existential_in_let.expected @@ -0,0 +1,11 @@ +===== User.res ===== + + We've found a bug for you! + /.../fixtures/Unexpected_existential_in_let/User.res:3:5-17 + + 1 │ let value: Gadt.wrap = Gadt.Pack(1) + 2 │ + 3 │ let Gadt.Pack(_x) = value + 4 │ + + Unexpected existential \ No newline at end of file diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_abstract_type_construction/Abs.res b/tests/build_tests/super_errors_multi/fixtures/Cross_abstract_type_construction/Abs.res new file mode 100644 index 0000000000..144d9bb482 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_abstract_type_construction/Abs.res @@ -0,0 +1,3 @@ +type t = int + +let make = v => v diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_abstract_type_construction/Abs.resi b/tests/build_tests/super_errors_multi/fixtures/Cross_abstract_type_construction/Abs.resi new file mode 100644 index 0000000000..5c236fb1c8 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_abstract_type_construction/Abs.resi @@ -0,0 +1,3 @@ +type t + +let make: int => t diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_abstract_type_construction/User.res b/tests/build_tests/super_errors_multi/fixtures/Cross_abstract_type_construction/User.res new file mode 100644 index 0000000000..4d423a447b --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_abstract_type_construction/User.res @@ -0,0 +1 @@ +let bad: Abs.t = 1 diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_async_promise_mismatch/Lib.res b/tests/build_tests/super_errors_multi/fixtures/Cross_async_promise_mismatch/Lib.res new file mode 100644 index 0000000000..525fdfb21c --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_async_promise_mismatch/Lib.res @@ -0,0 +1 @@ +let fetch = async (url: string): string => url diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_async_promise_mismatch/User.res b/tests/build_tests/super_errors_multi/fixtures/Cross_async_promise_mismatch/User.res new file mode 100644 index 0000000000..992915231d --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_async_promise_mismatch/User.res @@ -0,0 +1 @@ +let consume = (): string => Lib.fetch("api") diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_chain_of_aliases/A.res b/tests/build_tests/super_errors_multi/fixtures/Cross_chain_of_aliases/A.res new file mode 100644 index 0000000000..23d13e567b --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_chain_of_aliases/A.res @@ -0,0 +1,4 @@ +module Inner = { + type t = int + let v = 0 +} diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_chain_of_aliases/B.res b/tests/build_tests/super_errors_multi/fixtures/Cross_chain_of_aliases/B.res new file mode 100644 index 0000000000..d2ede9cbaa --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_chain_of_aliases/B.res @@ -0,0 +1 @@ +module Reexport = A.Inner diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_chain_of_aliases/C.res b/tests/build_tests/super_errors_multi/fixtures/Cross_chain_of_aliases/C.res new file mode 100644 index 0000000000..a2ceb98aea --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_chain_of_aliases/C.res @@ -0,0 +1 @@ +let v: B.Reexport.t = "wrong" diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_dependent_clash/Sender.res b/tests/build_tests/super_errors_multi/fixtures/Cross_dependent_clash/Sender.res new file mode 100644 index 0000000000..26c6349dfe --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_dependent_clash/Sender.res @@ -0,0 +1,3 @@ +type message = {to_: string, body: string} + +let send: message => unit = _msg => () diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_dependent_clash/User.res b/tests/build_tests/super_errors_multi/fixtures/Cross_dependent_clash/User.res new file mode 100644 index 0000000000..0dd83b5b4b --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_dependent_clash/User.res @@ -0,0 +1 @@ +let _ = Sender.send({to_: "alice"}) diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_deprecated_type/Legacy.res b/tests/build_tests/super_errors_multi/fixtures/Cross_deprecated_type/Legacy.res new file mode 100644 index 0000000000..53e551b132 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_deprecated_type/Legacy.res @@ -0,0 +1,2 @@ +@deprecated("Use newType instead") +type t = int diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_deprecated_type/User.res b/tests/build_tests/super_errors_multi/fixtures/Cross_deprecated_type/User.res new file mode 100644 index 0000000000..2b8956acb5 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_deprecated_type/User.res @@ -0,0 +1 @@ +let v: Legacy.t = 1 diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_deprecated_value/Legacy.res b/tests/build_tests/super_errors_multi/fixtures/Cross_deprecated_value/Legacy.res new file mode 100644 index 0000000000..b827ea2d04 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_deprecated_value/Legacy.res @@ -0,0 +1,2 @@ +@deprecated("Use computeNew instead") @val +external compute: int => int = "compute" diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_deprecated_value/User.res b/tests/build_tests/super_errors_multi/fixtures/Cross_deprecated_value/User.res new file mode 100644 index 0000000000..7df87bdf2c --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_deprecated_value/User.res @@ -0,0 +1 @@ +let x = Legacy.compute(1) diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_dict_pattern/Defs.res b/tests/build_tests/super_errors_multi/fixtures/Cross_dict_pattern/Defs.res new file mode 100644 index 0000000000..ad12bd1813 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_dict_pattern/Defs.res @@ -0,0 +1 @@ +type config = dict diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_dict_pattern/User.res b/tests/build_tests/super_errors_multi/fixtures/Cross_dict_pattern/User.res new file mode 100644 index 0000000000..1782881539 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_dict_pattern/User.res @@ -0,0 +1,4 @@ +let read = (cfg: Defs.config) => + switch cfg { + | dict{"port": p} => p + } diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_exception_arity_mismatch/Errors.res b/tests/build_tests/super_errors_multi/fixtures/Cross_exception_arity_mismatch/Errors.res new file mode 100644 index 0000000000..cb0fb172ac --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_exception_arity_mismatch/Errors.res @@ -0,0 +1 @@ +exception ParseError(string, int) diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_exception_arity_mismatch/User.res b/tests/build_tests/super_errors_multi/fixtures/Cross_exception_arity_mismatch/User.res new file mode 100644 index 0000000000..6b4c1a8478 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_exception_arity_mismatch/User.res @@ -0,0 +1 @@ +let raise_it = () => throw(Errors.ParseError("oops")) diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_external_argument_clash/Ffi.res b/tests/build_tests/super_errors_multi/fixtures/Cross_external_argument_clash/Ffi.res new file mode 100644 index 0000000000..ce430fb62e --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_external_argument_clash/Ffi.res @@ -0,0 +1 @@ +@val external parseInt: string => int = "parseInt" diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_external_argument_clash/User.res b/tests/build_tests/super_errors_multi/fixtures/Cross_external_argument_clash/User.res new file mode 100644 index 0000000000..5957ea12fc --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_external_argument_clash/User.res @@ -0,0 +1 @@ +let x = Ffi.parseInt(42) diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_gadt_pattern/Gadt.res b/tests/build_tests/super_errors_multi/fixtures/Cross_gadt_pattern/Gadt.res new file mode 100644 index 0000000000..7e78cb17ed --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_gadt_pattern/Gadt.res @@ -0,0 +1,3 @@ +type rec t<_> = + | Int(int): t + | Pair(t<'a>, t<'b>): t<('a, 'b)> diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_gadt_pattern/User.res b/tests/build_tests/super_errors_multi/fixtures/Cross_gadt_pattern/User.res new file mode 100644 index 0000000000..7081757e9b --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_gadt_pattern/User.res @@ -0,0 +1,5 @@ +let bad: Gadt.t => string = x => + switch x { + | Int(n) => n + | Pair(_, _) => "pair" + } diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_hidden_through_interface/Defs.res b/tests/build_tests/super_errors_multi/fixtures/Cross_hidden_through_interface/Defs.res new file mode 100644 index 0000000000..abb7607f0e --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_hidden_through_interface/Defs.res @@ -0,0 +1,3 @@ +type t = {x: int, y: int} + +let make = () => {x: 0, y: 0} diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_hidden_through_interface/Defs.resi b/tests/build_tests/super_errors_multi/fixtures/Cross_hidden_through_interface/Defs.resi new file mode 100644 index 0000000000..f856ba275a --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_hidden_through_interface/Defs.resi @@ -0,0 +1,3 @@ +type t + +let make: unit => t diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_hidden_through_interface/User.res b/tests/build_tests/super_errors_multi/fixtures/Cross_hidden_through_interface/User.res new file mode 100644 index 0000000000..3beb6cc8c5 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_hidden_through_interface/User.res @@ -0,0 +1,2 @@ +let v = Defs.make() +let leaked = v.x diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_inline_record_constructor/Defs.res b/tests/build_tests/super_errors_multi/fixtures/Cross_inline_record_constructor/Defs.res new file mode 100644 index 0000000000..164c83aab3 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_inline_record_constructor/Defs.res @@ -0,0 +1 @@ +type t = Pair({x: int, y: int}) diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_inline_record_constructor/User.res b/tests/build_tests/super_errors_multi/fixtures/Cross_inline_record_constructor/User.res new file mode 100644 index 0000000000..f08bcf4eb2 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_inline_record_constructor/User.res @@ -0,0 +1 @@ +let v = Defs.Pair(1, 2) diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_module_alias_dot_access/Lib.res b/tests/build_tests/super_errors_multi/fixtures/Cross_module_alias_dot_access/Lib.res new file mode 100644 index 0000000000..b98d30ce23 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_module_alias_dot_access/Lib.res @@ -0,0 +1,3 @@ +module Settings = { + let port = 8080 +} diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_module_alias_dot_access/User.res b/tests/build_tests/super_errors_multi/fixtures/Cross_module_alias_dot_access/User.res new file mode 100644 index 0000000000..4a51ad4526 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_module_alias_dot_access/User.res @@ -0,0 +1,3 @@ +module S = Lib.Settings + +let port = S.port + S.host diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_module_open_shadow_label_constructor/A.res b/tests/build_tests/super_errors_multi/fixtures/Cross_module_open_shadow_label_constructor/A.res new file mode 100644 index 0000000000..0f13949afd --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_module_open_shadow_label_constructor/A.res @@ -0,0 +1,3 @@ +type t = + | Foo + | Bar diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_module_open_shadow_label_constructor/User.res b/tests/build_tests/super_errors_multi/fixtures/Cross_module_open_shadow_label_constructor/User.res new file mode 100644 index 0000000000..47b8a41a2b --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_module_open_shadow_label_constructor/User.res @@ -0,0 +1,7 @@ +type t = + | Foo + | Bar + +open A + +let v = Foo diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_module_record_disambiguation/Box.res b/tests/build_tests/super_errors_multi/fixtures/Cross_module_record_disambiguation/Box.res new file mode 100644 index 0000000000..6915e332a3 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_module_record_disambiguation/Box.res @@ -0,0 +1 @@ +type t = {width: int, height: int} diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_module_record_disambiguation/Point.res b/tests/build_tests/super_errors_multi/fixtures/Cross_module_record_disambiguation/Point.res new file mode 100644 index 0000000000..b5eab82245 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_module_record_disambiguation/Point.res @@ -0,0 +1 @@ +type t = {x: int, y: int} diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_module_record_disambiguation/User.res b/tests/build_tests/super_errors_multi/fixtures/Cross_module_record_disambiguation/User.res new file mode 100644 index 0000000000..dbde9b1c86 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_module_record_disambiguation/User.res @@ -0,0 +1 @@ +let r: Point.t = {width: 1, height: 2} diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_module_type_only_no_impl/Iface.resi b/tests/build_tests/super_errors_multi/fixtures/Cross_module_type_only_no_impl/Iface.resi new file mode 100644 index 0000000000..19b83dc216 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_module_type_only_no_impl/Iface.resi @@ -0,0 +1 @@ +let v: int diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_module_type_only_no_impl/User.res b/tests/build_tests/super_errors_multi/fixtures/Cross_module_type_only_no_impl/User.res new file mode 100644 index 0000000000..adc242ff65 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_module_type_only_no_impl/User.res @@ -0,0 +1 @@ +let x: string = Iface.v diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_open_shadows_identifier/A.res b/tests/build_tests/super_errors_multi/fixtures/Cross_open_shadows_identifier/A.res new file mode 100644 index 0000000000..cd298427b2 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_open_shadows_identifier/A.res @@ -0,0 +1 @@ +let answer = 42 diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_open_shadows_identifier/User.res b/tests/build_tests/super_errors_multi/fixtures/Cross_open_shadows_identifier/User.res new file mode 100644 index 0000000000..2c518455ed --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_open_shadows_identifier/User.res @@ -0,0 +1,3 @@ +let answer = "outer" +open A +let _ = answer diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_optional_label_omitted/Lib.res b/tests/build_tests/super_errors_multi/fixtures/Cross_optional_label_omitted/Lib.res new file mode 100644 index 0000000000..9234f71d1e --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_optional_label_omitted/Lib.res @@ -0,0 +1 @@ +let greet = (~name: string, ~greeting: string="Hello", ()) => greeting ++ ", " ++ name diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_optional_label_omitted/User.res b/tests/build_tests/super_errors_multi/fixtures/Cross_optional_label_omitted/User.res new file mode 100644 index 0000000000..562299106d --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_optional_label_omitted/User.res @@ -0,0 +1 @@ +let s = Lib.greet() diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_polyvariant_constraint/Spec.res b/tests/build_tests/super_errors_multi/fixtures/Cross_polyvariant_constraint/Spec.res new file mode 100644 index 0000000000..a660efb87b --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_polyvariant_constraint/Spec.res @@ -0,0 +1,8 @@ +type allowed = [#Red | #Green | #Blue] + +let pick: allowed => string = c => + switch c { + | #Red => "r" + | #Green => "g" + | #Blue => "b" + } diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_polyvariant_constraint/User.res b/tests/build_tests/super_errors_multi/fixtures/Cross_polyvariant_constraint/User.res new file mode 100644 index 0000000000..5e3385d240 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_polyvariant_constraint/User.res @@ -0,0 +1 @@ +let v = Spec.pick(#Purple) diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_private_constructor_pattern/Result.res b/tests/build_tests/super_errors_multi/fixtures/Cross_private_constructor_pattern/Result.res new file mode 100644 index 0000000000..4f7e62c517 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_private_constructor_pattern/Result.res @@ -0,0 +1,5 @@ +type t = + | Loaded(string) + | Loading + +let loaded = s => Loaded(s) diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_private_constructor_pattern/Result.resi b/tests/build_tests/super_errors_multi/fixtures/Cross_private_constructor_pattern/Result.resi new file mode 100644 index 0000000000..368723838f --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_private_constructor_pattern/Result.resi @@ -0,0 +1,6 @@ +type t = + private + | Loaded(string) + | Loading + +let loaded: string => t diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_private_constructor_pattern/User.res b/tests/build_tests/super_errors_multi/fixtures/Cross_private_constructor_pattern/User.res new file mode 100644 index 0000000000..7233bf7c71 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_private_constructor_pattern/User.res @@ -0,0 +1 @@ +let x = Result.Loaded("hello") diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_qualified_constructor_mismatch/Color.res b/tests/build_tests/super_errors_multi/fixtures/Cross_qualified_constructor_mismatch/Color.res new file mode 100644 index 0000000000..efc0eae0b5 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_qualified_constructor_mismatch/Color.res @@ -0,0 +1,3 @@ +type t = + | Red + | Green diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_qualified_constructor_mismatch/Shape.res b/tests/build_tests/super_errors_multi/fixtures/Cross_qualified_constructor_mismatch/Shape.res new file mode 100644 index 0000000000..36d3a19172 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_qualified_constructor_mismatch/Shape.res @@ -0,0 +1,3 @@ +type t = + | Circle + | Square diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_qualified_constructor_mismatch/User.res b/tests/build_tests/super_errors_multi/fixtures/Cross_qualified_constructor_mismatch/User.res new file mode 100644 index 0000000000..a809c8d4ca --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_qualified_constructor_mismatch/User.res @@ -0,0 +1 @@ +let v: Shape.t = Color.Red diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_record_extra_field/Defs.res b/tests/build_tests/super_errors_multi/fixtures/Cross_record_extra_field/Defs.res new file mode 100644 index 0000000000..e2e17af745 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_record_extra_field/Defs.res @@ -0,0 +1 @@ +type t = {a: int, b: int} diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_record_extra_field/User.res b/tests/build_tests/super_errors_multi/fixtures/Cross_record_extra_field/User.res new file mode 100644 index 0000000000..6073586019 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_record_extra_field/User.res @@ -0,0 +1 @@ +let r: Defs.t = {a: 1, b: 2, extra: 3} diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_uncurried_arity/Lib.res b/tests/build_tests/super_errors_multi/fixtures/Cross_uncurried_arity/Lib.res new file mode 100644 index 0000000000..20528a0755 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_uncurried_arity/Lib.res @@ -0,0 +1 @@ +let add = (a: int, b: int, c: int) => a + b + c diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_uncurried_arity/User.res b/tests/build_tests/super_errors_multi/fixtures/Cross_uncurried_arity/User.res new file mode 100644 index 0000000000..22c26b76f3 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_uncurried_arity/User.res @@ -0,0 +1 @@ +let bad: int => int = Lib.add diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_unused_open/Helpers.res b/tests/build_tests/super_errors_multi/fixtures/Cross_unused_open/Helpers.res new file mode 100644 index 0000000000..eda5ab9140 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_unused_open/Helpers.res @@ -0,0 +1 @@ +let unrelated = 1 diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_unused_open/User.res b/tests/build_tests/super_errors_multi/fixtures/Cross_unused_open/User.res new file mode 100644 index 0000000000..55d4ee7d67 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_unused_open/User.res @@ -0,0 +1,3 @@ +open Helpers + +let v = 42 diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_variant_spread/Base.res b/tests/build_tests/super_errors_multi/fixtures/Cross_variant_spread/Base.res new file mode 100644 index 0000000000..ebf3f1e2d8 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_variant_spread/Base.res @@ -0,0 +1,3 @@ +type t = + | A + | B diff --git a/tests/build_tests/super_errors_multi/fixtures/Cross_variant_spread/Ext.res b/tests/build_tests/super_errors_multi/fixtures/Cross_variant_spread/Ext.res new file mode 100644 index 0000000000..cf5cb8c058 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Cross_variant_spread/Ext.res @@ -0,0 +1,4 @@ +type t = + | A + | ...Base.t + | C diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_extension_constructors/Foo.res b/tests/build_tests/super_errors_multi/fixtures/Iface_extension_constructors/Foo.res new file mode 100644 index 0000000000..3caf4e6f3d --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_extension_constructors/Foo.res @@ -0,0 +1,4 @@ +type t = .. + +type t += + | Boom(string) diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_extension_constructors/Foo.resi b/tests/build_tests/super_errors_multi/fixtures/Iface_extension_constructors/Foo.resi new file mode 100644 index 0000000000..47a74f838d --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_extension_constructors/Foo.resi @@ -0,0 +1,4 @@ +type t = .. + +type t += + | Boom(int) diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_field_mutable_mismatch/Foo.res b/tests/build_tests/super_errors_multi/fixtures/Iface_field_mutable_mismatch/Foo.res new file mode 100644 index 0000000000..eddf68bf0e --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_field_mutable_mismatch/Foo.res @@ -0,0 +1 @@ +type t = {count: int} diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_field_mutable_mismatch/Foo.resi b/tests/build_tests/super_errors_multi/fixtures/Iface_field_mutable_mismatch/Foo.resi new file mode 100644 index 0000000000..329fbfd10e --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_field_mutable_mismatch/Foo.resi @@ -0,0 +1 @@ +type t = {mutable count: int} diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_field_optional_mismatch/Foo.res b/tests/build_tests/super_errors_multi/fixtures/Iface_field_optional_mismatch/Foo.res new file mode 100644 index 0000000000..ff122aa325 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_field_optional_mismatch/Foo.res @@ -0,0 +1 @@ +type t = {a: int, b: string} diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_field_optional_mismatch/Foo.resi b/tests/build_tests/super_errors_multi/fixtures/Iface_field_optional_mismatch/Foo.resi new file mode 100644 index 0000000000..fae28d7384 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_field_optional_mismatch/Foo.resi @@ -0,0 +1 @@ +type t = {a: int, b?: string} diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_missing_value/Foo.res b/tests/build_tests/super_errors_multi/fixtures/Iface_missing_value/Foo.res new file mode 100644 index 0000000000..67bbe3ba8e --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_missing_value/Foo.res @@ -0,0 +1 @@ +let a = 1 diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_missing_value/Foo.resi b/tests/build_tests/super_errors_multi/fixtures/Iface_missing_value/Foo.resi new file mode 100644 index 0000000000..0fb0b0c7e8 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_missing_value/Foo.resi @@ -0,0 +1,2 @@ +let a: int +let b: string diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_modtype_infos/Foo.res b/tests/build_tests/super_errors_multi/fixtures/Iface_modtype_infos/Foo.res new file mode 100644 index 0000000000..708a6eb23e --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_modtype_infos/Foo.res @@ -0,0 +1,3 @@ +module type T = { + let v: string +} diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_modtype_infos/Foo.resi b/tests/build_tests/super_errors_multi/fixtures/Iface_modtype_infos/Foo.resi new file mode 100644 index 0000000000..4d77f56961 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_modtype_infos/Foo.resi @@ -0,0 +1,3 @@ +module type T = { + let v: int +} diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_module_types/Foo.res b/tests/build_tests/super_errors_multi/fixtures/Iface_module_types/Foo.res new file mode 100644 index 0000000000..086f64fce1 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_module_types/Foo.res @@ -0,0 +1,3 @@ +module Inner = { + let value = "not an int" +} diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_module_types/Foo.resi b/tests/build_tests/super_errors_multi/fixtures/Iface_module_types/Foo.resi new file mode 100644 index 0000000000..c1c80261e5 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_module_types/Foo.resi @@ -0,0 +1,3 @@ +module Inner: { + let value: int +} diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_not_compiled/Foo.res b/tests/build_tests/super_errors_multi/fixtures/Iface_not_compiled/Foo.res new file mode 100644 index 0000000000..ab49c6303b --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_not_compiled/Foo.res @@ -0,0 +1 @@ +let v = 1 diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_not_compiled/Foo.resi b/tests/build_tests/super_errors_multi/fixtures/Iface_not_compiled/Foo.resi new file mode 100644 index 0000000000..bc6599a137 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_not_compiled/Foo.resi @@ -0,0 +1 @@ +let v: int = diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_privacy_mismatch/Foo.res b/tests/build_tests/super_errors_multi/fixtures/Iface_privacy_mismatch/Foo.res new file mode 100644 index 0000000000..0d8eb0e632 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_privacy_mismatch/Foo.res @@ -0,0 +1 @@ +type t = private int diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_privacy_mismatch/Foo.resi b/tests/build_tests/super_errors_multi/fixtures/Iface_privacy_mismatch/Foo.resi new file mode 100644 index 0000000000..975adb5316 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_privacy_mismatch/Foo.resi @@ -0,0 +1 @@ +type t = int diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_tag_name_mismatch/Foo.res b/tests/build_tests/super_errors_multi/fixtures/Iface_tag_name_mismatch/Foo.res new file mode 100644 index 0000000000..6bbd0febea --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_tag_name_mismatch/Foo.res @@ -0,0 +1,4 @@ +@tag("type") +type t = + | @as("a") A + | B diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_tag_name_mismatch/Foo.resi b/tests/build_tests/super_errors_multi/fixtures/Iface_tag_name_mismatch/Foo.resi new file mode 100644 index 0000000000..b0b2699b87 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_tag_name_mismatch/Foo.resi @@ -0,0 +1,4 @@ +@tag("kind") +type t = + | @as("a") A + | B diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_type_decl_record/Foo.res b/tests/build_tests/super_errors_multi/fixtures/Iface_type_decl_record/Foo.res new file mode 100644 index 0000000000..3bb325d27a --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_type_decl_record/Foo.res @@ -0,0 +1 @@ +type t = {x: int, z: int} diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_type_decl_record/Foo.resi b/tests/build_tests/super_errors_multi/fixtures/Iface_type_decl_record/Foo.resi new file mode 100644 index 0000000000..b5eab82245 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_type_decl_record/Foo.resi @@ -0,0 +1 @@ +type t = {x: int, y: int} diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_type_decl_variant/Foo.res b/tests/build_tests/super_errors_multi/fixtures/Iface_type_decl_variant/Foo.res new file mode 100644 index 0000000000..a968c4a733 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_type_decl_variant/Foo.res @@ -0,0 +1,3 @@ +type t = + | A + | B(string) diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_type_decl_variant/Foo.resi b/tests/build_tests/super_errors_multi/fixtures/Iface_type_decl_variant/Foo.resi new file mode 100644 index 0000000000..94e648c422 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_type_decl_variant/Foo.resi @@ -0,0 +1,3 @@ +type t = + | A + | B(int) diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_unboxed_variant_mismatch/Foo.res b/tests/build_tests/super_errors_multi/fixtures/Iface_unboxed_variant_mismatch/Foo.res new file mode 100644 index 0000000000..519e92579c --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_unboxed_variant_mismatch/Foo.res @@ -0,0 +1 @@ +type t = Wrap(int) diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_unboxed_variant_mismatch/Foo.resi b/tests/build_tests/super_errors_multi/fixtures/Iface_unboxed_variant_mismatch/Foo.resi new file mode 100644 index 0000000000..5b198abe28 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_unboxed_variant_mismatch/Foo.resi @@ -0,0 +1,2 @@ +@unboxed +type t = Wrap(int) diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_value_descriptions/Foo.res b/tests/build_tests/super_errors_multi/fixtures/Iface_value_descriptions/Foo.res new file mode 100644 index 0000000000..b6c3061ea6 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_value_descriptions/Foo.res @@ -0,0 +1 @@ +let compute = (s: string) => String.length(s) diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_value_descriptions/Foo.resi b/tests/build_tests/super_errors_multi/fixtures/Iface_value_descriptions/Foo.resi new file mode 100644 index 0000000000..aec7b21274 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_value_descriptions/Foo.resi @@ -0,0 +1 @@ +let compute: int => int diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_variant_representation_mismatch/Foo.res b/tests/build_tests/super_errors_multi/fixtures/Iface_variant_representation_mismatch/Foo.res new file mode 100644 index 0000000000..82945d226e --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_variant_representation_mismatch/Foo.res @@ -0,0 +1,3 @@ +type t = + | @as(0) A + | B diff --git a/tests/build_tests/super_errors_multi/fixtures/Iface_variant_representation_mismatch/Foo.resi b/tests/build_tests/super_errors_multi/fixtures/Iface_variant_representation_mismatch/Foo.resi new file mode 100644 index 0000000000..4ef6252b61 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Iface_variant_representation_mismatch/Foo.resi @@ -0,0 +1,3 @@ +type t = + | @as("zero") A + | B diff --git a/tests/build_tests/super_errors_multi/fixtures/Modules_not_allowed_toplevel/Sig.res b/tests/build_tests/super_errors_multi/fixtures/Modules_not_allowed_toplevel/Sig.res new file mode 100644 index 0000000000..fff5b5fd01 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Modules_not_allowed_toplevel/Sig.res @@ -0,0 +1,3 @@ +module type S = { + let v: int +} diff --git a/tests/build_tests/super_errors_multi/fixtures/Modules_not_allowed_toplevel/User.res b/tests/build_tests/super_errors_multi/fixtures/Modules_not_allowed_toplevel/User.res new file mode 100644 index 0000000000..fe841b594f --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Modules_not_allowed_toplevel/User.res @@ -0,0 +1,8 @@ +let make = (): module(Sig.S) => + module( + { + let v = 1 + } + ) + +let module(M) = make() diff --git a/tests/build_tests/super_errors_multi/fixtures/Smoke_cross_module_type_clash/Lib.res b/tests/build_tests/super_errors_multi/fixtures/Smoke_cross_module_type_clash/Lib.res new file mode 100644 index 0000000000..9e769359ed --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Smoke_cross_module_type_clash/Lib.res @@ -0,0 +1 @@ +let increment = (x: int) => x + 1 diff --git a/tests/build_tests/super_errors_multi/fixtures/Smoke_cross_module_type_clash/User.res b/tests/build_tests/super_errors_multi/fixtures/Smoke_cross_module_type_clash/User.res new file mode 100644 index 0000000000..953f935a09 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Smoke_cross_module_type_clash/User.res @@ -0,0 +1 @@ +let v = Lib.increment("hello") diff --git a/tests/build_tests/super_errors_multi/fixtures/Smoke_interface_mismatch/Foo.res b/tests/build_tests/super_errors_multi/fixtures/Smoke_interface_mismatch/Foo.res new file mode 100644 index 0000000000..618952e849 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Smoke_interface_mismatch/Foo.res @@ -0,0 +1 @@ +let v = "not an int" diff --git a/tests/build_tests/super_errors_multi/fixtures/Smoke_interface_mismatch/Foo.resi b/tests/build_tests/super_errors_multi/fixtures/Smoke_interface_mismatch/Foo.resi new file mode 100644 index 0000000000..19b83dc216 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Smoke_interface_mismatch/Foo.resi @@ -0,0 +1 @@ +let v: int diff --git a/tests/build_tests/super_errors_multi/fixtures/Smoke_missing_field/Defs.res b/tests/build_tests/super_errors_multi/fixtures/Smoke_missing_field/Defs.res new file mode 100644 index 0000000000..56a48ca98f --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Smoke_missing_field/Defs.res @@ -0,0 +1,3 @@ +type point = {x: int, y: int} + +let make = (x, y) => {x, y} diff --git a/tests/build_tests/super_errors_multi/fixtures/Smoke_missing_field/Use.res b/tests/build_tests/super_errors_multi/fixtures/Smoke_missing_field/Use.res new file mode 100644 index 0000000000..ea5921fb37 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Smoke_missing_field/Use.res @@ -0,0 +1 @@ +let bad: Defs.point = {x: 1} diff --git a/tests/build_tests/super_errors_multi/fixtures/Smoke_unbound_module_reference/Consumer.res b/tests/build_tests/super_errors_multi/fixtures/Smoke_unbound_module_reference/Consumer.res new file mode 100644 index 0000000000..1a74a469eb --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Smoke_unbound_module_reference/Consumer.res @@ -0,0 +1 @@ +let x = NonexistentModule.value diff --git a/tests/build_tests/super_errors_multi/fixtures/Unexpected_existential_in_let/Gadt.res b/tests/build_tests/super_errors_multi/fixtures/Unexpected_existential_in_let/Gadt.res new file mode 100644 index 0000000000..38495779cd --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Unexpected_existential_in_let/Gadt.res @@ -0,0 +1 @@ +type rec wrap<_> = Pack('a): wrap diff --git a/tests/build_tests/super_errors_multi/fixtures/Unexpected_existential_in_let/User.res b/tests/build_tests/super_errors_multi/fixtures/Unexpected_existential_in_let/User.res new file mode 100644 index 0000000000..bf843b2a86 --- /dev/null +++ b/tests/build_tests/super_errors_multi/fixtures/Unexpected_existential_in_let/User.res @@ -0,0 +1,3 @@ +let value: Gadt.wrap = Gadt.Pack(1) + +let Gadt.Pack(_x) = value diff --git a/tests/build_tests/super_errors_multi/input.js b/tests/build_tests/super_errors_multi/input.js new file mode 100644 index 0000000000..b4a82ca4d2 --- /dev/null +++ b/tests/build_tests/super_errors_multi/input.js @@ -0,0 +1,201 @@ +// @ts-check + +import { readdirSync, statSync } from "node:fs"; +import * as fs from "node:fs/promises"; +import * as os from "node:os"; +import * as path from "node:path"; +import { setup } from "#dev/process"; +import { normalizeNewlines } from "#dev/utils"; + +const { bsc } = setup(import.meta.dirname); + +const fixturesDir = path.join(import.meta.dirname, "fixtures"); +const expectedDir = path.join(import.meta.dirname, "expected"); + +const fixtures = readdirSync(fixturesDir) + .filter(name => statSync(path.join(fixturesDir, name)).isDirectory()) + .sort(); + +// `-bs-cmi-only` stops the pipeline after typechecking. Without it, bsc tries +// to emit .mjs and resolve sibling .js files for cross-module imports, which +// fails in this harness because we don't run the build system. +const bscFlags = [ + "-w", + "+A", + "-bs-jsx", + "4", + "-color", + "always", + "-bs-cmi-only", +]; + +const updateTests = process.argv[2] === "update"; + +/** + * @param {string} fixtureName + * @param {string} output + * @return {string} + */ +function postProcessErrorOutput(fixtureName, output) { + let result = output; + result = result.trimEnd(); + result = result.replace( + new RegExp( + `(?:[A-Z]:)?[\\\\/][^ ]+?tests[\\\\/]build_tests[\\\\/]super_errors_multi[\\\\/]fixtures[\\\\/]${fixtureName}[\\\\/]([^:\\s]+)`, + "g", + ), + (_match, file) => + `/.../fixtures/${fixtureName}/${file.replace(/\\/g, "/")}`, + ); + // `find_in_path_uncap` resolves `.cmi` lookups case-insensitively, so the + // path printed in error messages picks up whichever case the host + // filesystem returns (lowercase on macOS APFS/HFS+, capitalised on Linux + // ext4). Normalise every `.cmi` basename to lowercase so snapshots are + // platform-independent. + result = result.replace( + /([^/\s]+)\.cmi\b/g, + (_, stem) => `${stem.toLowerCase()}.cmi`, + ); + return normalizeNewlines(result); +} + +/** + * Per-fixture artifact extensions to clean between runs so each invocation + * compiles against a known-empty .cmi/.cmj/.cmt set. + */ +const artifactExts = [".cmi", ".cmj", ".cmt", ".cmti", ".mjs", ".js"]; + +/** + * @param {string} dir + */ +async function cleanArtifacts(dir) { + const entries = await fs.readdir(dir); + await Promise.all( + entries.map(async name => { + if (artifactExts.includes(path.extname(name))) { + await fs.unlink(path.join(dir, name)); + } + }), + ); +} + +/** + * @param {string} fixtureName + * @returns {Promise<{ fixtureName: string, failure: string | null }>} + */ +async function runFixture(fixtureName) { + const fixtureDir = path.join(fixturesDir, fixtureName); + + // Compile sources in alphabetical order, with one tweak: for any module + // that has both `.resi` and `.res`, the interface goes first so the + // implementation type-checks against the produced `.cmi`. Fixtures that + // need a specific dependency order across modules can prefix filenames + // with numeric labels (e.g. `01_Foo.res`, `02_Bar.res`). + const sources = (await fs.readdir(fixtureDir)) + .filter(name => name.endsWith(".res") || name.endsWith(".resi")) + .sort((a, b) => { + const aStem = a.replace(/\.resi?$/, ""); + const bStem = b.replace(/\.resi?$/, ""); + if (aStem === bStem) { + return a.endsWith(".resi") ? -1 : 1; + } + return aStem < bStem ? -1 : aStem > bStem ? 1 : 0; + }); + + await cleanArtifacts(fixtureDir); + + // Modules that have both an interface and an implementation need + // `-bs-read-cmi` on the implementation so the `.cmi` produced from the + // interface is enforced rather than overwritten. + const hasInterface = new Set(); + for (const source of sources) { + if (source.endsWith(".resi")) hasInterface.add(source.slice(0, -5)); + } + + const chunks = []; + for (const source of sources) { + const stem = source.replace(/\.resi?$/, ""); + const extraFlags = + source.endsWith(".res") && hasInterface.has(stem) ? ["-bs-read-cmi"] : []; + const { stderr } = await bsc( + [ + ...bscFlags, + ...extraFlags, + "-I", + fixtureDir, + path.join(fixtureDir, source), + ], + { cwd: fixtureDir }, + ); + const stderrStr = stderr.toString(); + if (stderrStr.length > 0) { + // Tag each chunk so a reader can tell which file produced which + // diagnostic — important when the same error gets re-emitted in the + // downstream consumer. + chunks.push(`===== ${source} =====\n${stderrStr}`); + } + } + + const actualErrorOutput = postProcessErrorOutput( + fixtureName, + chunks.join("\n"), + ); + const expectedFilePath = path.join(expectedDir, `${fixtureName}.expected`); + + if (updateTests) { + await fs.writeFile(expectedFilePath, actualErrorOutput); + return { fixtureName, failure: null }; + } + + let expectedErrorOutput; + try { + expectedErrorOutput = postProcessErrorOutput( + fixtureName, + await fs.readFile(expectedFilePath, "utf-8"), + ); + } catch { + return { + fixtureName, + failure: `Missing expected snapshot for ${fixtureName} (run with 'update' to create)`, + }; + } + + if (expectedErrorOutput === actualErrorOutput) { + return { fixtureName, failure: null }; + } + return { + fixtureName, + failure: [ + `The old and new error output for fixture ${fixtureName} aren't the same`, + "\n=== Old:", + expectedErrorOutput, + "\n=== New:", + actualErrorOutput, + ].join("\n"), + }; +} + +const concurrency = Math.max(1, os.availableParallelism()); +let cursor = 0; +const results = new Array(fixtures.length); + +await Promise.all( + Array.from({ length: Math.min(concurrency, fixtures.length) }, async () => { + while (true) { + const i = cursor++; + if (i >= fixtures.length) return; + results[i] = await runFixture(fixtures[i]); + } + }), +); + +let atLeastOneTaskFailed = false; +for (const { failure } of results) { + if (failure !== null) { + console.error(failure); + atLeastOneTaskFailed = true; + } +} +if (atLeastOneTaskFailed) { + process.exit(1); +}