Skip to content

Commit ac214f9

Browse files
committed
[errors] Introduce error registration API
Partially addresses #7560 Coq exception handling is complex, and requires quite a bit of meta-data on exceptions, including custom printing and documentation for each error. We introduce an error registration API that should help with the above problematic, by requiring new errors to be properly registered. There are some questions: - OCaml has support for private extensible types, however that cannot be used with exceptions unless we introduce a `CErrors.t` type. May be worth doing. - We could make the error kinds extensible too, but I'm not sure it is worth the gain, and it could be used badly. - Is the E0 variant worth it? A new error is declared as: ```ocaml module UE_Sig = struct type t = string option * Pp.t let print (hdr, pp) = Pp.strpp let doc = Pp.str "Generic User Error, to be deprecated" let kind = ErrorKind.Regular end module UserError = CoqError.Make(UE_Sig) ``` in the `.mli` file: ```ocaml module UserError = CErrors.S with type t := string option * Pp.t ``` the `with type` constraint is needed if the user wishes to expose the exception constructor.
1 parent 427fb92 commit ac214f9

File tree

2 files changed

+77
-2
lines changed

2 files changed

+77
-2
lines changed

lib/cErrors.ml

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,49 @@ let anomaly ?loc ?info ?label pp =
3030
let info = Option.cata (Loc.add_loc info) info loc in
3131
Exninfo.iraise (Anomaly (label, pp), info)
3232

33-
exception UserError of string option * Pp.t (* User errors *)
33+
module ErrorKind = struct
34+
type t = Anomaly | Regular
35+
end
36+
37+
(* TODO: support for errors with context *)
38+
module type S = sig
39+
type t
40+
val print : t -> Pp.t
41+
val doc : Pp.t
42+
val kind : ErrorKind.t
43+
end
44+
45+
module type E = sig
46+
type t
47+
type exn += E of t
48+
end
49+
50+
module type S0 = sig
51+
val print : Pp.t
52+
val doc : Pp.t
53+
val kind : ErrorKind.t
54+
end
55+
56+
module type E0 = sig
57+
type exn += E
58+
end
59+
60+
module CoqError : sig
61+
module Make (X : S) : E with type t = X.t
62+
module Make0 (X : S0) : E0
63+
end = struct
64+
module Make (X : S) = struct
65+
type t = X.t
66+
type exn += E of t
67+
(* register printer *)
68+
end
69+
module Make0 (X : S0) = struct
70+
type exn += E
71+
(* register printer *)
72+
end
73+
end
74+
75+
exception UserError of string option * Pp.t
3476

3577
let user_err ?loc ?info ?hdr strm =
3678
let info = Option.default Exninfo.null info in
@@ -132,7 +174,7 @@ let print_no_report e = iprint_no_report (e, Exninfo.info e)
132174
(** Predefined handlers **)
133175

134176
let _ = register_handler begin function
135-
| UserError(s, pps) ->
177+
| UserError (s, pps) ->
136178
Some (where s ++ pps)
137179
| _ -> None
138180
end

lib/cErrors.mli

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,39 @@
1616
val push : exn -> Exninfo.iexn
1717
[@@ocaml.deprecated "please use [Exninfo.capture]"]
1818

19+
(** {6 Error registration API} *)
20+
21+
module ErrorKind : sig
22+
type t = Anomaly | Regular
23+
end
24+
25+
module type S = sig
26+
type t
27+
val print : t -> Pp.t
28+
val doc : Pp.t
29+
val kind : ErrorKind.t
30+
end
31+
32+
module type E = sig
33+
type t
34+
type exn += E of t
35+
end
36+
37+
module type S0 = sig
38+
val print : Pp.t
39+
val doc : Pp.t
40+
val kind : ErrorKind.t
41+
end
42+
43+
module type E0 = sig
44+
type exn += E
45+
end
46+
47+
module CoqError : sig
48+
module Make0 (X : S0) : E0
49+
module Make (X : S) : E with type t = X.t
50+
end
51+
1952
(** {6 Generic errors.}
2053
2154
[Anomaly] is used for system errors and [UserError] for the

0 commit comments

Comments
 (0)