Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pattern type constraint in let expression parsed inconsistently #7758

vicuna opened this Issue Mar 25, 2018 · 2 comments


None yet
1 participant
Copy link

vicuna commented Mar 25, 2018

Original bug ID: 7758
Reporter: antron
Status: new
Resolution: open
Priority: normal
Severity: minor
Version: 4.06.1
Category: lexing and parsing
Monitored by: @nojb @Drup @ygrek

Bug description

The expression

(1) let foo : int = 42 in ...

seems to get parsed as

 `let foo : int = 42 : int in ...`

while the expression

(2) let (foo : int) = 42 in ...

which differs only in having parentheses, seems to get parsed as

  `let foo : int = 42 in ...`

I would have expected the second parse for both cases. The first parse can be problematic when using PPX, because the variable and expression may need to have different types. In particular, in

  `let%lwt foo : int = bar in ...`

foo should have type int, and bar should have type int Lwt.t. See ocsigen/lwt#564.

Steps to reproduce

let () =
  let foo : int = 42 in
  let (foo : int) = 42 in
  ignore foo
  1. ocamlopt -dparsetree -c

  2. Result is:

  structure_item ([1,0+0]..[4,59+12])
    Pstr_value Nonrec
        pattern ([1,0+4]..[1,0+6])
          Ppat_construct "()" ([1,0+4]..[1,0+6])
        expression ([2,9+2]..[4,59+12])
          Pexp_let Nonrec
              pattern ([2,9+6]..[2,9+20]) ghost
                pattern ([2,9+6]..[2,9+9])
                  Ppat_var "foo" ([2,9+6]..[2,9+9])
                core_type ([2,9+6]..[2,9+20]) ghost
                  core_type ([2,9+12]..[2,9+15])
                    Ptyp_constr "int" ([2,9+12]..[2,9+15])
              expression ([2,9+6]..[2,9+20]) ghost
                Pexp_constraint   <----------------------------- !!!!
                expression ([2,9+18]..[2,9+20])
                  Pexp_constant PConst_int (42,None)
                core_type ([2,9+12]..[2,9+15])
                  Ptyp_constr "int" ([2,9+12]..[2,9+15])
          expression ([3,33+2]..[4,59+12])
            Pexp_let Nonrec
                pattern ([3,33+6]..[3,33+17])
                  pattern ([3,33+7]..[3,33+10])
                    Ppat_var "foo" ([3,33+7]..[3,33+10])
                  core_type ([3,33+13]..[3,33+16])
                    Ptyp_constr "int" ([3,33+13]..[3,33+16])
                expression ([3,33+20]..[3,33+22])
                  Pexp_constant PConst_int (42,None)
            expression ([4,59+2]..[4,59+12])
              expression ([4,59+2]..[4,59+8])
                Pexp_ident "ignore" ([4,59+2]..[4,59+8])
                  expression ([4,59+9]..[4,59+12])
                    Pexp_ident "foo" ([4,59+9]..[4,59+12])

Additional information

Further complicating this in practice is that in 4.05.0, (1) is parsed as

  `let foo = 42 : int in`

i.e. the constraint is removed from the pattern and appears on the expression only.


This comment has been minimized.

Copy link
Collaborator Author

vicuna commented Apr 11, 2018

Comment author: @Drup

It would be nice to sort this out before the next release, as it messes up with ppx in a way that is difficult to take into account, even with ocaml-migrate-parsetree.

If someone has a concrete proposition on how to make this cleaner, I'm ready to implement it.


This comment has been minimized.

Copy link
Collaborator Author

vicuna commented Oct 15, 2018

Comment author: @alainfrisch

See, "":

We plan to change the AST to have an explicit representation for:...

FWIW, I'm not 100% convinced by the proposal, since it would mean treating very differently

let (x1 : t), x2 = e1, e2 in ...


let (x1 : t) = x1 in ...

which might be surprising for ppx authors and for users (in the first case, the annotation would not be propagated to the expression e1).

An alternative would be to keep the annotations only in the pattern at the AST level, but somehow extract them (with a strategy to define) and apply them to the bound expression.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.