annotationsocamldeprecatedml

How to annotate let binding as deprecated in OCaml?


I want to annotate a function from an external library as deprecated, to ensure it will not be use in my project. Let's assume the library offers the following module:

module Lib : sig
  val safe_function : int -> unit
  val unsafe_function : int -> int -> unit
end = struct
  let safe_function _ = ()
  let unsafe_function _ _ = ()
end

I have a Util.ml file in my project, which I open in every file. In it, I would like to do something like that:

open Lib

let unsafe_function = Lib.unsafe_function
  [@@deprecated "Use safe_function instead."]

let foo = (fun x -> x)
  [@@deprecated "BBB"]

type t =
  | A [@deprecated]
  | B [@deprecated]
  [@@deprecated]

Compiling the following usage.ml file

open Util

let _ = unsafe_function 0 0
let _ = foo 0

let _ = A
let f (x : t) = x

produces the following warnings:

$ ocamlc -c -w +3 usage.ml
File "usage.ml", line 6, characters 8-9:
Warning 3: deprecated: A
File "usage.ml", line 7, characters 11-12:
Warning 3: deprecated: Util.t

So the deprecated attributes on the let-bindings do not trigger, but the ones on the type definition and constructors do. The attribute syntax seems to allow both.

I found this answer but it seems to be outdated because:

  1. It explicitly says that it "is only available for values (not on types)", which is not true (anymore?) as shown by the above example.
  2. The documentation explicitly says the annotation "can be applied to most kind of items in signatures or structures."

Solution

  • I'm not sure what the exact syntax is (your suggestion sounds right and corresponds to the parser code, so it might be a bug in the compiler), but you can (ab)use the module system to do that :

    include (Lib : sig
        val unsafe_function : int -> int -> unit
        [@@ocaml.deprecated "Use safe_function instead."]
      end)
    
    let _ = unsafe_function 0 0 (* warning here *)