The future 4.03 release of OCaml has added a new warning, 57, to prevent ambiguous guarded pattern. Namely, the issue is that on an or-pattern with a when clause, if the first part of the or-pat matches, but the when evaluates to false, the complete pattern will be discarded, although another variant of the or-pat could have succeed. For instance, on the following code, ko will be bound to 1, which can be surprising:
type t = A of string | B of string
let bad x y =
match x,y with
| A s, _ | _, A s when s = "foo" -> 0
| _, _ -> 1
let ok = bad (A "foo") (A "bar")
let ko = bad (A "bar") (A "foo")
In 4.03, OCaml will complain with Warning 57: Ambiguous guarded pattern, variable s may match different or-pattern arguments, suggesting you to check whether you really intended this behavior or not.
However, the warning is also active on the second line of the pattern matching in the following definition:
let f x y =
match x,y with
| A _, A _ -> 0
| A s, _ | _, A s when s = "foo" -> 1
| _ -> 2
Here, I'd argue that the ambiguity cannot arise, since A _, A _ is matched by the first line, hence at most one of the components of the or-pattern can match if the program gets to this point. Is this reasoning correct?
If the answer is yes, I would like to know in addition whether it is possible to silence this warning on this specific branch. Indeed, I can do match [@warning "-57"] x,y with, but this will silence the warning if someone introduces another ambiguous pattern there sometime later. I've tried to put the attribute at the pattern level (| A s, _ | _, A s [@warning "-57"] when s = "foo"), but this has no effect.
NB: I know that in this specific case I could just replace the catch-all with | A s, B _ | B _, A s when s = "foo" to make the ambiguity disappear, but consider that this is only a reduced example.