Opinionated OCaml linter with Merlin integration for code quality, naming conventions, and style checks
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

merlint,ocaml-merlin: fix E351 to detect stdlib ref and array in signatures

E351 reads Merlin.Dump.value_sigs and matches the outer type
constructor against Stdlib.ref / Stdlib.array. Two bugs kept it
silent:

1. parse_sig_value took the word immediately after Tsig_value as
the stamped name, but the typedtree emits a value_description
header first:

Tsig_value
value_description counter/274 (bad.mli[1,0+0]..)

That header word has no "/", so parse_named_item returned None
and value_sigs stayed empty.

2. The typedtree renders the built-in array as "array/10!" -- no
Stdlib prefix, but with a trailing "!" that flags the
constructor as predef/stdlib-resolved. ref comes through as
"Stdlib!.ref". A user-defined array has no trailing "!".
parse_name threw that marker away, so the rule either missed
stdlib array or false-positived on user-defined array.

parse_name now records the trailing "!" and normalises bare predef
names to prefix = ["Stdlib"]. good.mli carries a shadow case to
pin the behaviour.

+10 -6
+3 -5
lib/rules/e351.ml
··· 20 20 (** Payload for mutable state issues *) 21 21 22 22 let is_stdlib_mutable (path : Merlin.Dump.name) = 23 - match path.prefix with 24 - | [ "Stdlib" ] -> 25 - if path.base = "ref" then Some "ref" 26 - else if path.base = "array" then Some "array" 27 - else None 23 + match (path.prefix, path.base) with 24 + | [ "Stdlib" ], "ref" -> Some "ref" 25 + | [ "Stdlib" ], "array" -> Some "array" 28 26 | _ -> None 29 27 30 28 let check (ctx : Context.file) =
+7 -1
test/cram/e351.t/good.mli
··· 12 12 (** Cache operations - state is encapsulated *) 13 13 val cache_get : int -> int option 14 14 val cache_set : int -> int -> unit 15 - val cache_clear : unit -> unit 15 + val cache_clear : unit -> unit 16 + 17 + (** User-defined [array] type shadowing Stdlib's - not a mutable primitive, 18 + must not be flagged. *) 19 + type 'a array = Nil | Cons of 'a 20 + 21 + val users : int array