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: E351 stdlib ref check uses Ident.persistent on the path

The earlier [Path.name p = "ref" || "Stdlib.ref"] check would have
tripped on a locally-defined [type 'a ref = 'a list] (the path still
prints as "ref"). Match instead on the full path shape: a
[Pdot (Pident stdlib, "ref")] where [stdlib] is a persistent ident
named "Stdlib". Local user-defined [ref] resolves to [Pident id]
with [Ident.persistent id = false] and is correctly skipped.

Also document [Context.cmt] as the single typed-tree access point
for rules -- any new rule needing [Types.type_expr]/[Path.t]/[Typedtree]
should query through here rather than introducing a parallel path.

+15 -7
+6 -2
lib/context.mli
··· 71 71 72 72 val cmt : file -> Ocaml_typing.Cmt_format.cmt_infos option 73 73 (** [cmt file] returns the parsed [.cmt]/[.cmti] for [file] when 74 - available, [None] otherwise. The result is cached on the context so 75 - repeated rule queries share a single read. *) 74 + available, [None] otherwise. The result is cached on the context so 75 + repeated rule queries share a single read. 76 + 77 + This is the {e one} typed-tree access point for rules. New rules 78 + that need [Types.type_expr] / [Path.t] / [Typedtree] information 79 + must query through here -- don't introduce a parallel path. *) 76 80 77 81 (** {2 Project context accessors} *) 78 82
+9 -5
lib/rules/e351.ml
··· 16 16 module Path = Ocaml_typing.Path 17 17 module Predef = Ocaml_typing.Predef 18 18 19 - let is_stdlib_ref p = 20 - (* [ref] is not a predef -- it's a regular record type in [Stdlib], so 21 - we compare against the qualified name directly. *) 22 - let n = Path.name p in 23 - n = "ref" || n = "Stdlib.ref" 19 + let is_stdlib_ref = function 20 + (* [ref] is not a [Predef] constant -- it's a regular record type in 21 + the [Stdlib] module, so we match on the path shape directly. 22 + Must be [Stdlib.ref]: a local [type 'a ref = ...] would resolve 23 + to [Pident id] with a non-persistent [id] and not match. *) 24 + | Ocaml_typing.Path.Pdot (Pident stdlib, "ref") -> 25 + Ocaml_typing.Ident.persistent stdlib 26 + && Ocaml_typing.Ident.name stdlib = "Stdlib" 27 + | _ -> false 24 28 25 29 let mutable_kind_of_type_expr te = 26 30 (* [Types.get_desc] unwraps [Tlink]s and other indirections without