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 diff --git a/compiler/syntax/src/res_core.ml b/compiler/syntax/src/res_core.ml index 4c3a683042..805874b161 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 error message. *) + 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/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 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/syntax_tests/data/parsing/errors/expressions/typeDefInFunction.res b/tests/syntax_tests/data/parsing/errors/expressions/typeDefInFunction.res new file mode 100644 index 0000000000..8f9c83804f --- /dev/null +++ b/tests/syntax_tests/data/parsing/errors/expressions/typeDefInFunction.res @@ -0,0 +1,5 @@ +let f = () => { + type t = int + 1 +} +