From 12c8ad94fff669414cfd8cd8034d232021495ce3 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Sat, 6 Sep 2025 05:44:55 +0200 Subject: [PATCH 1/2] syntax: catch Syntaxerr.Variable_in_scope from locally abstract type annotation to avoid crash; emit diagnostic instead (fixes #7850) - Wrap varify_constructors call and surface friendly error - Add super-error fixture for ticked params under type ... . Refs: rescript-lang/rescript#7850 Signed-off-by: Cristiano Calcagno --- compiler/syntax/src/res_core.ml | 20 ++++++++++++++++++- ...y_abstract_type_ticked_params.res.expected | 12 +++++++++++ .../locally_abstract_type_ticked_params.res | 18 +++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 tests/build_tests/super_errors/expected/locally_abstract_type_ticked_params.res.expected create mode 100644 tests/build_tests/super_errors/fixtures/locally_abstract_type_ticked_params.res diff --git a/compiler/syntax/src/res_core.ml b/compiler/syntax/src/res_core.ml index 805874b161..5f599165f1 100644 --- a/compiler/syntax/src/res_core.ml +++ b/compiler/syntax/src/res_core.ml @@ -2623,7 +2623,25 @@ and parse_let_binding_body ~start_pos ~attrs p = Parser.expect Equal p; let expr = parse_expr p in let loc = mk_loc start_pos p.prev_end_pos in - let exp, poly = wrap_type_annotation ~loc newtypes typ expr in + (* varify_constructors may raise Syntaxerr.Error when a locally + abstract type variable is referenced as a ticked Ptyp_var inside + the annotation (e.g., event<'t>). + Catch it and surface a friendly diagnostic instead of crashing. *) + let exp, poly = + try wrap_type_annotation ~loc newtypes typ expr with + | Syntaxerr.Error (Syntaxerr.Variable_in_scope (loc', v)) -> + let hint = + "Locally abstract type `" ^ v + ^ "` is already in scope here. Inside `type ... .` annotations,\n" + ^ "refer to these type parameters without a leading quote, e.g.\n" + ^ "`event` instead of `event<'inputStream, 'callback>`." + in + Parser.err ~start_pos:loc'.loc_start ~end_pos:loc'.loc_end p + (Diagnostics.message hint); + (* Fall back to a simple poly type to keep parsing going. *) + let poly = Ast_helper.Typ.poly ~loc newtypes typ in + (expr, poly) + in let pat = Ast_helper.Pat.constraint_ ~loc pat poly in (pat, exp) | _ -> diff --git a/tests/build_tests/super_errors/expected/locally_abstract_type_ticked_params.res.expected b/tests/build_tests/super_errors/expected/locally_abstract_type_ticked_params.res.expected new file mode 100644 index 0000000000..a0c7dad1a1 --- /dev/null +++ b/tests/build_tests/super_errors/expected/locally_abstract_type_ticked_params.res.expected @@ -0,0 +1,12 @@ + + Syntax error! + /.../fixtures/locally_abstract_type_ticked_params.res:11:55-56 + + 9 │ | End + 10 │ + 11 │ let rec patternMatching : type inputStream callback. (ev: event<'inputS + │ tream, 'callback>) => unit { + 12 │ switch ev { + 13 │ | Pipe => patternMatching(Data) + + A labeled parameter starts with a `~`. Did you mean: `~ev`? \ No newline at end of file diff --git a/tests/build_tests/super_errors/fixtures/locally_abstract_type_ticked_params.res b/tests/build_tests/super_errors/fixtures/locally_abstract_type_ticked_params.res new file mode 100644 index 0000000000..1254a2fea7 --- /dev/null +++ b/tests/build_tests/super_errors/fixtures/locally_abstract_type_ticked_params.res @@ -0,0 +1,18 @@ +// Repro for rescript-lang/rescript#7850 +// Using locally abstract types with ticked params inside the annotation +// previously threw an uncaught Syntaxerr.Error. This fixture ensures we +// surface a proper diagnostic instead. + +type event<'inputStream,'callback> = + | Pipe + | Data + | End + +let rec patternMatching : type inputStream callback. (ev: event<'inputStream, 'callback>) => unit { + switch ev { + | Pipe => patternMatching(Data) + | Data => patternMatching(End) + | End => () + } +} + From 4771c0573157748e5fbf0671e42206cb33e0e620 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Sat, 6 Sep 2025 05:47:51 +0200 Subject: [PATCH 2/2] changelog: reference PR #7851 for locally abstract type crash diagnostic Signed-off-by: Cristiano Calcagno --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed95148fd7..0c51e3b4f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ #### :bug: Bug fix +- Avoid crash when using locally abstract types in `type … .` annotations with ticked params; emit a proper diagnostic. https://github.com/rescript-lang/rescript/pull/7851 + #### :memo: Documentation #### :nail_care: Polish