如何在OCaml中注释let bind as deprecated?

aut*_*hir 8 ocaml annotations ml deprecated

我想要将外部库中的函数注释为已弃用,以确保它不会在我的项目中使用.我们假设该库提供以下模块:

module Lib : sig
  val safe_function : int -> unit
  val unsafe_function : int -> int -> unit
end = struct
  let safe_function _ = ()
  let unsafe_function _ _ = ()
end
Run Code Online (Sandbox Code Playgroud)

Util.ml我的项目中有一个文件,我在每个文件中打开.在其中,我想做类似的事情:

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]
Run Code Online (Sandbox Code Playgroud)

编译以下usage.ml文件

open Util

let _ = unsafe_function 0 0
let _ = foo 0

let _ = A
let f (x : t) = x
Run Code Online (Sandbox Code Playgroud)

产生以下警告:

$ 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
Run Code Online (Sandbox Code Playgroud)

因此,deprecatedlet-bindings上的属性不会触发,但是类型定义和构造函数上的属性会触发.该属性的语法似乎让两者.

我找到了这个答案,但似乎已经过时,因为:

  1. 它明确地说它" 只适用于值(不是类型) ",这不是真的(不再是?),如上例所示.
  2. 文档明确说明注释" 可以应用于签名或结构中的大多数项目. "

Éti*_*lon 6

我不确定具体的语法是什么(你的建议听起来正确并且对应于解析器代码,所以它可能是编译器中的一个错误),但你可以(ab)使用模块系统来做到这一点:

include (Lib : sig
    val unsafe_function : int -> int -> unit
    [@@ocaml.deprecated "Use safe_function instead."]
  end)

let _ = unsafe_function 0 0 (* warning here *)
Run Code Online (Sandbox Code Playgroud)