Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
20 changes: 19 additions & 1 deletion compiler/syntax/src/res_core.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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<inputStream, callback>` 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)
| _ ->
Expand Down
Original file line number Diff line number Diff line change
@@ -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`?
Original file line number Diff line number Diff line change
@@ -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 => ()
}
}

Loading