`let` field punning from records in ocaml

It is not because of the let punning but because of the type-driven record field names disambiguation. It is not principal and there is even a warning that tells you that your code depends on its presence. In the first case, the typechecker infers the type of the function from the application. In the second case, it doesn't have the type of information to infer that somefield comes from the module R1.

In OCaml, the field names are defined in the namespace of the module, so it is better to specify the module name explicitly, e.g.,

let _ = let { R.somefield} = R.inj  in 0

Alternatively, you can constrain the type to ensure that the type checker knows the type when it disambiguates the record name, e.g.,

let {somefield} : R.r = R.inj in 0

or,

let foo : R.r -> unit = function {somefield} -> ()

1)In the second case, let {somefield} = R.inj in 0 the typechecker starts the inference from the left-hand side, and is not yet knowing that the right-hand side has type R.r, if you will rewrite the code as, let r = R.inj in r.somefield; 0 it will figure out that somefield comes from R.