From 881e9823ebc82082c859db143ea565cb5f8959e5 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Tue, 8 Apr 2025 14:06:16 +0200 Subject: [PATCH 1/3] suggest existing module name in scope when it makes sense for missing values --- compiler/ml/typetexp.ml | 26 +++++++++++++++++-- ...module_for_missing_identifier.res.expected | 10 +++++++ .../suggest_module_for_missing_identifier.res | 1 + tests/build_tests/super_errors/input.js | 4 +-- 4 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 tests/build_tests/super_errors/expected/suggest_module_for_missing_identifier.res.expected create mode 100644 tests/build_tests/super_errors/fixtures/suggest_module_for_missing_identifier.res diff --git a/compiler/ml/typetexp.ml b/compiler/ml/typetexp.ml index d212eb2dc6..fef7215284 100644 --- a/compiler/ml/typetexp.ml +++ b/compiler/ml/typetexp.ml @@ -841,7 +841,7 @@ let report_error env ppf = function Printtyp.reset_and_mark_loops_list [ty; ty']; fprintf ppf "@[Method '%s' has type %a,@ which should be %a@]" l Printtyp.type_expr ty Printtyp.type_expr ty') - | Unbound_value lid -> + | Unbound_value lid -> ( (* modified *) (match lid with | Ldot (outer, inner) -> @@ -850,7 +850,29 @@ let report_error env ppf = function | other_ident -> Format.fprintf ppf "The value %a can't be found" Printtyp.longident other_ident); - super_spellcheck ppf Env.fold_values env lid |> ignore + let did_spellcheck = super_spellcheck ppf Env.fold_values env lid in + (* For cases such as when the user refers to something that's a value with + a lowercase identifier in JS but a module in ReScript. + + 'Console' is a typical example, where JS is `console.log` and ReScript is `Console.log`. *) + (* TODO(codemods) Add codemod for refering to the module instead. *) + let as_module = + match lid with + | Lident name -> ( + try + Some + (env + |> Env.lookup_module ~load:false + (Lident (String.capitalize_ascii name))) + with _ -> None) + | _ -> None + in + match as_module with + | None -> () + | Some module_path -> + Format.fprintf ppf "@,@[@,@[%s to use the module @{%a@}?@]@]" + (if did_spellcheck then "Or did you mean" else "Maybe you meant") + Printtyp.path module_path) | Unbound_module lid -> (* modified *) (match lid with diff --git a/tests/build_tests/super_errors/expected/suggest_module_for_missing_identifier.res.expected b/tests/build_tests/super_errors/expected/suggest_module_for_missing_identifier.res.expected new file mode 100644 index 0000000000..be1a9f2a14 --- /dev/null +++ b/tests/build_tests/super_errors/expected/suggest_module_for_missing_identifier.res.expected @@ -0,0 +1,10 @@ + + We've found a bug for you! + /.../fixtures/suggest_module_for_missing_identifier.res:1:1-7 + + 1 │ console.log("Hello") + 2 │ + + The value console can't be found + + Maybe you meant to use the module Console? \ No newline at end of file diff --git a/tests/build_tests/super_errors/fixtures/suggest_module_for_missing_identifier.res b/tests/build_tests/super_errors/fixtures/suggest_module_for_missing_identifier.res new file mode 100644 index 0000000000..8a07264f8e --- /dev/null +++ b/tests/build_tests/super_errors/fixtures/suggest_module_for_missing_identifier.res @@ -0,0 +1 @@ +console.log("Hello") diff --git a/tests/build_tests/super_errors/input.js b/tests/build_tests/super_errors/input.js index f31370b097..ffd99160fe 100644 --- a/tests/build_tests/super_errors/input.js +++ b/tests/build_tests/super_errors/input.js @@ -10,8 +10,8 @@ const { bsc } = setup(import.meta.dirname); const expectedDir = path.join(import.meta.dirname, "expected"); -const fixtures = readdirSync("fixtures").filter( - fileName => path.extname(fileName) === ".res", +const fixtures = readdirSync(path.join(import.meta.dirname, "fixtures")).filter( + (fileName) => path.extname(fileName) === ".res" ); const prefix = ["-w", "+A", "-bs-jsx", "4"]; From c6855ee30e672d9cbe8b1c970e283195350b917d Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Tue, 8 Apr 2025 14:10:31 +0200 Subject: [PATCH 2/3] add another test --- ..._missing_identifier_with_spellcheck.res.expected | 13 +++++++++++++ ...odule_for_missing_identifier_with_spellcheck.res | 2 ++ 2 files changed, 15 insertions(+) create mode 100644 tests/build_tests/super_errors/expected/suggest_module_for_missing_identifier_with_spellcheck.res.expected create mode 100644 tests/build_tests/super_errors/fixtures/suggest_module_for_missing_identifier_with_spellcheck.res diff --git a/tests/build_tests/super_errors/expected/suggest_module_for_missing_identifier_with_spellcheck.res.expected b/tests/build_tests/super_errors/expected/suggest_module_for_missing_identifier_with_spellcheck.res.expected new file mode 100644 index 0000000000..70a7cde3b2 --- /dev/null +++ b/tests/build_tests/super_errors/expected/suggest_module_for_missing_identifier_with_spellcheck.res.expected @@ -0,0 +1,13 @@ + + We've found a bug for you! + /.../fixtures/suggest_module_for_missing_identifier_with_spellcheck.res:2:1-7 + + 1 │ let consol = 1 + 2 │ console.log("Hello") + 3 │ + + The value console can't be found + + Hint: Did you mean consol? + + Or did you mean to use the module Console? \ No newline at end of file diff --git a/tests/build_tests/super_errors/fixtures/suggest_module_for_missing_identifier_with_spellcheck.res b/tests/build_tests/super_errors/fixtures/suggest_module_for_missing_identifier_with_spellcheck.res new file mode 100644 index 0000000000..27f91343fc --- /dev/null +++ b/tests/build_tests/super_errors/fixtures/suggest_module_for_missing_identifier_with_spellcheck.res @@ -0,0 +1,2 @@ +let consol = 1 +console.log("Hello") From 3514745ae40d6c7d11d5f6ab9a3d341cf1ad2ffb Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Tue, 8 Apr 2025 14:11:43 +0200 Subject: [PATCH 3/3] changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa2de7b05f..d0fc04077f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,10 @@ - Better representation of JSX in AST. https://github.com/rescript-lang/rescript/pull/7286 +#### :nail_care: Polish + +- Improve error message for missing value when the identifier is also the name of a module in scope. https://github.com/rescript-lang/rescript/pull/7384 + # 12.0.0-alpha.11 #### :bug: Bug fix