10

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."
authchir
  • 1,605
  • 14
  • 26
  • Deleted my answer since the typo seems to have been made in transfer. Otherwise it looks correct to me, but might be that deprecated let bindings have to be used in a different compilation unit for the warning to trigger? – glennsl Feb 02 '18 at 09:46
  • I moved them to different files (`util.ml` and `usage.ml`) but it behaves the same. – authchir Feb 02 '18 at 10:01
  • Add a `util.mli` with the decprecation annotations included? That doesn't quite answer the question as given, but it seems like the right thing to do here. – gsg Feb 04 '18 at 08:24

2 Answers2

8

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 *)
Étienne Millon
  • 3,018
  • 11
  • 27
0

Just had the same issue. OCaml syntax for attributes is somewhat hairy. This works:

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

(notice the single @)

rixed
  • 96
  • 2