From 57bf1518438578305367b45628b4d49bdadb8f44 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Fri, 5 Sep 2025 11:25:48 +0200 Subject: [PATCH 1/5] better error when defining a type inside of a function --- compiler/syntax/src/res_core.ml | 14 ++++++++++++++ .../expected/type_in_function.res.expected | 11 +++++++++++ .../super_errors/fixtures/type_in_function.res | 4 ++++ 3 files changed, 29 insertions(+) create mode 100644 tests/build_tests/super_errors/expected/type_in_function.res.expected create mode 100644 tests/build_tests/super_errors/fixtures/type_in_function.res diff --git a/compiler/syntax/src/res_core.ml b/compiler/syntax/src/res_core.ml index 4c3a683042..1157cb5623 100644 --- a/compiler/syntax/src/res_core.ml +++ b/compiler/syntax/src/res_core.ml @@ -184,6 +184,10 @@ module ErrorMessages = struct ^ "_`)\n If you need the field to be \"" ^ keyword_txt ^ "\" at runtime, annotate the field: `@as(\"" ^ keyword_txt ^ "\") " ^ keyword_txt ^ "_ : ...`" + + let type_definition_in_function = + "Type definitions are not allowed inside functions.\n" + ^ " Move this `type` declaration to the top level or into a module." end module InExternal = struct @@ -3479,6 +3483,16 @@ and parse_expr_block_item p = in let loc = mk_loc start_pos p.prev_end_pos in Ast_helper.Exp.let_ ~loc rec_flag let_bindings next + | Typ -> + (* Parse to be able to give a good *) + let type_start = start_pos in + Parser.begin_region p; + let _ = parse_type_definition_or_extension ~attrs p in + Parser.end_region p; + Parser.err ~start_pos:type_start ~end_pos:p.prev_end_pos p + (Diagnostics.message ErrorMessages.type_definition_in_function); + parse_newline_or_semicolon_expr_block p; + parse_expr_block p | _ -> let e1 = let expr = parse_expr p in diff --git a/tests/build_tests/super_errors/expected/type_in_function.res.expected b/tests/build_tests/super_errors/expected/type_in_function.res.expected new file mode 100644 index 0000000000..2c8202adec --- /dev/null +++ b/tests/build_tests/super_errors/expected/type_in_function.res.expected @@ -0,0 +1,11 @@ + + Syntax error! + /.../fixtures/type_in_function.res:2:3-14 + + 1 │ let f = () => { + 2 │ type t = int + 3 │ 1 + 4 │ } + + Type definitions are not allowed inside functions. + Move this `type` declaration to the top level or into a module. \ No newline at end of file diff --git a/tests/build_tests/super_errors/fixtures/type_in_function.res b/tests/build_tests/super_errors/fixtures/type_in_function.res new file mode 100644 index 0000000000..168245cf69 --- /dev/null +++ b/tests/build_tests/super_errors/fixtures/type_in_function.res @@ -0,0 +1,4 @@ +let f = () => { + type t = int + 1 +} From a997bc475fc1fbb189a338f7c742a97a78eb0c59 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Fri, 5 Sep 2025 11:27:20 +0200 Subject: [PATCH 2/5] changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71f716ec1f..1c2dda552e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,8 @@ #### :nail_care: Polish +- Improve error message for trying to define a type inside a function. https://github.com/rescript-lang/rescript/pull/7843 + #### :house: Internal # 12.0.0-beta.9 From c8e85f9be2d5e5cb1e93c07797135f7956e6b32a Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Fri, 5 Sep 2025 11:30:31 +0200 Subject: [PATCH 3/5] complete comment --- compiler/syntax/src/res_core.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/syntax/src/res_core.ml b/compiler/syntax/src/res_core.ml index 1157cb5623..805874b161 100644 --- a/compiler/syntax/src/res_core.ml +++ b/compiler/syntax/src/res_core.ml @@ -3484,7 +3484,7 @@ and parse_expr_block_item p = let loc = mk_loc start_pos p.prev_end_pos in Ast_helper.Exp.let_ ~loc rec_flag let_bindings next | Typ -> - (* Parse to be able to give a good *) + (* Parse to be able to give a good error message. *) let type_start = start_pos in Parser.begin_region p; let _ = parse_type_definition_or_extension ~attrs p in From 2a58629a3527e546464cdb3052f697da6531a2d3 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Fri, 5 Sep 2025 12:25:00 +0200 Subject: [PATCH 4/5] make syntax test instead --- .../expected/type_in_function.res.expected | 11 ----------- .../expressions/expected/typeDefInFunction.res.txt | 13 +++++++++++++ .../errors/expressions/typeDefInFunction.res} | 1 + 3 files changed, 14 insertions(+), 11 deletions(-) delete mode 100644 tests/build_tests/super_errors/expected/type_in_function.res.expected create mode 100644 tests/syntax_tests/data/parsing/errors/expressions/expected/typeDefInFunction.res.txt rename tests/{build_tests/super_errors/fixtures/type_in_function.res => syntax_tests/data/parsing/errors/expressions/typeDefInFunction.res} (97%) diff --git a/tests/build_tests/super_errors/expected/type_in_function.res.expected b/tests/build_tests/super_errors/expected/type_in_function.res.expected deleted file mode 100644 index 2c8202adec..0000000000 --- a/tests/build_tests/super_errors/expected/type_in_function.res.expected +++ /dev/null @@ -1,11 +0,0 @@ - - Syntax error! - /.../fixtures/type_in_function.res:2:3-14 - - 1 │ let f = () => { - 2 │ type t = int - 3 │ 1 - 4 │ } - - Type definitions are not allowed inside functions. - Move this `type` declaration to the top level or into a module. \ No newline at end of file diff --git a/tests/syntax_tests/data/parsing/errors/expressions/expected/typeDefInFunction.res.txt b/tests/syntax_tests/data/parsing/errors/expressions/expected/typeDefInFunction.res.txt new file mode 100644 index 0000000000..622b8030a9 --- /dev/null +++ b/tests/syntax_tests/data/parsing/errors/expressions/expected/typeDefInFunction.res.txt @@ -0,0 +1,13 @@ + + Syntax error! + syntax_tests/data/parsing/errors/expressions/typeDefInFunction.res:2:3-14 + + 1 │ let f = () => { + 2 │ type t = int + 3 │ 1 + 4 │ } + + Type definitions are not allowed inside functions. + Move this `type` declaration to the top level or into a module. + +let f [arity:1]() = ((1)[@res.braces ]) \ No newline at end of file diff --git a/tests/build_tests/super_errors/fixtures/type_in_function.res b/tests/syntax_tests/data/parsing/errors/expressions/typeDefInFunction.res similarity index 97% rename from tests/build_tests/super_errors/fixtures/type_in_function.res rename to tests/syntax_tests/data/parsing/errors/expressions/typeDefInFunction.res index 168245cf69..8f9c83804f 100644 --- a/tests/build_tests/super_errors/fixtures/type_in_function.res +++ b/tests/syntax_tests/data/parsing/errors/expressions/typeDefInFunction.res @@ -2,3 +2,4 @@ let f = () => { type t = int 1 } + From 5668baf247d9292b46d54b031d8235ffc5489e40 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Fri, 5 Sep 2025 12:34:16 +0200 Subject: [PATCH 5/5] update analysis tests --- .../tests/src/expected/CompletionExpressions.res.txt | 4 ++-- .../tests/src/expected/CompletionPipeSubmodules.res.txt | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/analysis_tests/tests/src/expected/CompletionExpressions.res.txt b/tests/analysis_tests/tests/src/expected/CompletionExpressions.res.txt index ddd83b7e52..680b29abeb 100644 --- a/tests/analysis_tests/tests/src/expected/CompletionExpressions.res.txt +++ b/tests/analysis_tests/tests/src/expected/CompletionExpressions.res.txt @@ -1235,8 +1235,8 @@ Path fnTakingPolyVariant }] Complete src/CompletionExpressions.res 281:24 -posCursor:[281:24] posNoWhite:[281:23] Found expr:[281:3->290:18] -Pexp_apply ...[281:3->281:22] (...[281:23->281:25], ...[290:0->290:16]) +posCursor:[281:24] posNoWhite:[281:23] Found expr:[281:3->302:1] +Pexp_apply ...[281:3->281:22] (...[281:23->281:25], ...[290:0->290:16], ...[292:2->301:20]) Completable: Cexpression CArgument Value[fnTakingPolyVariant]($0)=# Package opens Stdlib.place holder Pervasives.JsxModules.place holder Resolved opens 1 Stdlib diff --git a/tests/analysis_tests/tests/src/expected/CompletionPipeSubmodules.res.txt b/tests/analysis_tests/tests/src/expected/CompletionPipeSubmodules.res.txt index 6669a1e770..8c6ad20505 100644 --- a/tests/analysis_tests/tests/src/expected/CompletionPipeSubmodules.res.txt +++ b/tests/analysis_tests/tests/src/expected/CompletionPipeSubmodules.res.txt @@ -1,4 +1,6 @@ Complete src/CompletionPipeSubmodules.res 13:20 +posCursor:[13:20] posNoWhite:[13:19] Found expr:[13:11->23:23] +Pexp_apply ...[21:9->21:10] (...[13:11->21:8], ...[23:2->23:23]) posCursor:[13:20] posNoWhite:[13:19] Found expr:[13:11->21:8] Completable: Cpath Value[A, B1, xx]-> Package opens Stdlib.place holder Pervasives.JsxModules.place holder @@ -18,6 +20,8 @@ Path }] Complete src/CompletionPipeSubmodules.res 17:18 +posCursor:[17:18] posNoWhite:[17:17] Found expr:[17:11->23:23] +Pexp_apply ...[21:9->21:10] (...[17:11->21:8], ...[23:2->23:23]) posCursor:[17:18] posNoWhite:[17:17] Found expr:[17:11->21:8] Completable: Cpath Value[A, x].v-> Package opens Stdlib.place holder Pervasives.JsxModules.place holder