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
17 changes: 12 additions & 5 deletions .github/workflows/esy-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ jobs:
with:
node-version: 20

- name: Set up MinGW (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
choco upgrade mingw -y --no-progress
echo "C:\ProgramData\mingw64\mingw64\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append

- name: Install esy
run: npm install -g esy@0.9.0-beta.1

Expand All @@ -44,7 +51,7 @@ jobs:
uses: actions/cache/restore@v4
with:
path: ~/.esy/source
key: esy-source-${{ matrix.os }}-${{ matrix.ocaml-compiler }}-${{ hashFiles('esy.lock.json') }}
key: v0.0.2-esy-source-${{ matrix.os }}-${{ matrix.ocaml-compiler }}-${{ hashFiles('esy.lock.json') }}

- name: Print esy cache
id: print_esy_cache
Expand All @@ -57,8 +64,8 @@ jobs:
path: |
${{ steps.print_esy_cache.outputs.ESY_CACHE }}
_export
key: esy-build-${{ matrix.os }}-${{ matrix.ocaml-compiler }}-${{ hashFiles('esy.lock.json') }}
restore-keys: esy-build-${{ matrix.os }}-
key: v0.0.2-esy-build-${{ matrix.os }}-${{ matrix.ocaml-compiler }}-${{ hashFiles('esy.lock.json') }}
restore-keys: v0.0.2-esy-build-${{ matrix.os }}-

- name: Install dependencies
run: esy install
Expand Down Expand Up @@ -94,7 +101,7 @@ jobs:
if: steps.global-cache.outputs.cache-hit != 'true'
with:
path: ~/.esy/source
key: esy-source-${{ matrix.os }}-${{ matrix.ocaml-compiler }}-${{ hashFiles('esy.lock.json') }}
key: v0.0.2-esy-source-${{ matrix.os }}-${{ matrix.ocaml-compiler }}-${{ hashFiles('esy.lock.json') }}

- name: Save dependencies cache
if: steps.deps-cache.outputs.cache-hit != 'true'
Expand All @@ -103,7 +110,7 @@ jobs:
path: |
${{ steps.print_esy_cache.outputs.ESY_CACHE }}
_export
key: esy-build-${{ matrix.os }}-${{ matrix.ocaml-compiler }}-${{ hashFiles('esy.lock.json') }}
key: v0.0.2-esy-build-${{ matrix.os }}-${{ matrix.ocaml-compiler }}-${{ hashFiles('esy.lock.json') }}

# Cleanup build cache in case dependencies have changed
- name: Cleanup
Expand Down
9 changes: 5 additions & 4 deletions .github/workflows/opam-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ jobs:
# OCaml >= 4.13
# https://github.com/ocaml/setup-ocaml/issues/822#issuecomment-2215525942
- {ocaml-compiler: '4.14.x', os: windows-latest}
- {ocaml-compiler: 'ocaml-base-compiler.5.4.0', os: windows-latest}

runs-on: ${{ matrix.setup.os }}

Expand All @@ -51,15 +52,15 @@ jobs:
uses: actions/cache/restore@v4
with:
path: ~/.opam
key: opam-${{ matrix.setup.os }}-${{ matrix.setup.ocaml-compiler }}-${{ hashFiles('*.opam') }}
key: v0.0.1-opam-${{ matrix.setup.os }}-${{ matrix.setup.ocaml-compiler }}-${{ hashFiles('*.opam') }}

- name: Load opam cache when Windows
if: runner.os == 'Windows'
id: opam-cache-windows
uses: actions/cache/restore@v4
with:
path: _opam
key: opam-${{ matrix.setup.os }}-${{ matrix.setup.ocaml-compiler }}-${{ hashFiles('**.opam') }}
key: v0.0.1-opam-${{ matrix.setup.os }}-${{ matrix.setup.ocaml-compiler }}-${{ hashFiles('**.opam') }}

- name: Install dependencies
run: opam install . --deps-only
Expand Down Expand Up @@ -87,12 +88,12 @@ jobs:
if: steps.opam-cache.outputs.cache-hit != 'true' && runner.os != 'Windows'
with:
path: ~/.opam
key: opam-${{ matrix.setup.os }}-${{ matrix.setup.ocaml-compiler }}-${{ hashFiles('**.opam') }}
key: v0.0.1-opam-${{ matrix.setup.os }}-${{ matrix.setup.ocaml-compiler }}-${{ hashFiles('**.opam') }}

- name: Save cache when Windows
uses: actions/cache/save@v4
if: steps.opam-cache-windows.outputs.cache-hit != 'true' && runner.os == 'Windows'
with:
path: _opam
key: opam-${{ matrix.setup.os }}-${{ matrix.setup.ocaml-compiler }}-${{ hashFiles('**.opam') }}
key: v0.0.1-opam-${{ matrix.setup.os }}-${{ matrix.setup.ocaml-compiler }}-${{ hashFiles('**.opam') }}

16 changes: 13 additions & 3 deletions src/reason-parser/reason_pprint_ast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -5913,8 +5913,7 @@ let createFormatter () =
(pattern :: patternAux)
in
match argsList, return.pexp_desc with
| [], Pexp_constraint (e, ct) ->
assert (vbct = None);
| [], Pexp_constraint (e, ct) when vbct = None ->
let typeLayout =
source_map
~loc:ct.ptyp_loc
Expand Down Expand Up @@ -6244,7 +6243,18 @@ let createFormatter () =
~loc:pat.ppat_loc
(match vbct with
| Some _ ->
self#pattern_with_precedence ~attrs:pat.ppat_attributes pat
(match pat.ppat_desc with
| Ppat_alias _ ->
makeList
~wrap:("(", ")")
[ self#pattern_with_precedence
~attrs:pat.ppat_attributes
pat
]
| _ ->
self#pattern_with_precedence
~attrs:pat.ppat_attributes
pat)
| None -> self#pattern pat)
in
let appTerms = self#unparseExprApplicationItems expr in
Expand Down
1 change: 1 addition & 0 deletions test/dune
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@
(cram
(applies_to rtopIntegration)
(package rtop)
(enabled_if (= %{os_type} Unix))
(deps %{bin:ocamlc} %{bin:rtop}))
15 changes: 15 additions & 0 deletions test/expr-constraint-with-vbct.t/input.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* Array literal with type constraint */
let x: array(int) = ([|1, 2|]: array(int));

/* List literal with type constraint */
let x: list(int) = ([1, 2, 3]: list(int));

/* Tuple with type constraint */
let x: (int, string) = ((1, "a"): (int, string));

/* Function expression with type constraint */
let f: int => int = ((x => x + 1): int => int);

/* Record with type constraint */
type t = {a: int};
let x: t = ({a: 1}: t);
41 changes: 41 additions & 0 deletions test/expr-constraint-with-vbct.t/run.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
Format expression type constraints when binding also has a type constraint
$ refmt ./input.re | tee formatted.re
/* Array literal with type constraint */
let x: array(int) = ([|1, 2|]: array(int));

/* List literal with type constraint */
let x: list(int) = ([1, 2, 3]: list(int));

/* Tuple with type constraint */
let x: (int, string) = (
(1, "a"): (int, string)
);

/* Function expression with type constraint */
let f: int => int = (x => x + 1: int => int);

/* Record with type constraint */
type t = {a: int};
let x: t = ({ a: 1 }: t);

Idempotency check
$ refmt ./formatted.re | tee formatted_back.re
/* Array literal with type constraint */
let x: array(int) = ([|1, 2|]: array(int));

/* List literal with type constraint */
let x: list(int) = ([1, 2, 3]: list(int));

/* Tuple with type constraint */
let x: (int, string) = (
(1, "a"): (int, string)
);

/* Function expression with type constraint */
let f: int => int = (x => x + 1: int => int);

/* Record with type constraint */
type t = {a: int};
let x: t = ({ a: 1 }: t);

$ diff formatted.re formatted_back.re
4 changes: 2 additions & 2 deletions test/rtopIntegration.t
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ always error.
Given the above, we're gonna test that utop integration works by piping code
into it and asserting the existence of some output.

$ echo "let f = a => a;" | rtop | grep -o "let f: 'a => 'a = <fun>;"
$ echo "let f = a => a;" | rtop 2>&1 | grep -o "let f: 'a => 'a = <fun>;"
let f: 'a => 'a = <fun>;

$ echo "let f = (a) => 1 + \"hi\";" | rtop | grep -o "has type"
$ echo "let f = (a) => 1 + \"hi\";" | rtop 2>&1 | grep -o "has type"
has type
14 changes: 14 additions & 0 deletions test/value-constraint-alias-pattern.t/input.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
let x: t = x;
let (x as y): t = x;
let ((x, y) as pair): t = x;
let (Some(x) as opt): t = opt;
let ({url, mode} as target): t = x;
let ({url, mode, protocol} as target): TargetT.Safe.t =
multiTarget->MultiTargetT.toIgnorableTargetT;
let ({url, mode}): t = x;
let ({url: u, mode: m} as target): t = x;
let Foo.{url, mode}: t = x;
let (Foo.{url, mode} as target): t = x;
let ([x, y] as listPair): t = value;
let (_ as anyValue): t = value;
let ((x as y: u): t) = value;
33 changes: 33 additions & 0 deletions test/value-constraint-alias-pattern.t/run.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
$ refmt ./input.re | tee formatted.re
let x: t = x;
let (x as y): t = x;
let ((x, y) as pair): t = x;
let (Some(x) as opt): t = opt;
let ({ url, mode } as target): t = x;
let ({ url, mode, protocol } as target): TargetT.Safe.t =
multiTarget->MultiTargetT.toIgnorableTargetT;
let { url, mode }: t = x;
let ({ url: u, mode: m } as target): t = x;
let Foo.{ url, mode } : t = x;
let (Foo.{ url, mode } as target): t = x;
let ([x, y] as listPair): t = value;
let (_ as anyValue): t = value;
let ((x as y: u): t) = value;

$ refmt ./formatted.re | tee formatted_back.re
let x: t = x;
let (x as y): t = x;
let ((x, y) as pair): t = x;
let (Some(x) as opt): t = opt;
let ({ url, mode } as target): t = x;
let ({ url, mode, protocol } as target): TargetT.Safe.t =
multiTarget->MultiTargetT.toIgnorableTargetT;
let { url, mode }: t = x;
let ({ url: u, mode: m } as target): t = x;
let Foo.{ url, mode } : t = x;
let (Foo.{ url, mode } as target): t = x;
let ([x, y] as listPair): t = value;
let (_ as anyValue): t = value;
let ((x as y: u): t) = value;

$ diff formatted.re formatted_back.re
Loading