aboutsummaryrefslogtreecommitdiffhomepage
path: root/toplevel/coqloop.ml
diff options
context:
space:
mode:
authorGravatar Emilio Jesus Gallego Arias <e+git@x80.org>2018-02-28 20:24:18 +0100
committerGravatar Emilio Jesus Gallego Arias <e+git@x80.org>2018-02-28 21:51:30 +0100
commitae27de7dbce680e91353982bf23d568adca0d017 (patch)
treeccb88dd09e5d940719e62531721ed87e5f15766a /toplevel/coqloop.ml
parentf726e860917b56abc94f21d9d5add7594d23bb6d (diff)
[toplevel] Update state when `Drop` exception is thrown [#6872]
`Drop` is implemented using exceptions-as-control flow, so the toplevel state gets corrupted as `do_vernac` will never return when `Drop` occurs in the input. The right fix would be to remove `Drop` from the vernacular and make it a toplevel-only command, but meanwhile we can just patch the state in the exception handler. We also need to keep the global state in `Coqloop` as the main `coqtop` entry point won't be called by `go ()`. Fixes #6872.
Diffstat (limited to 'toplevel/coqloop.ml')
-rw-r--r--toplevel/coqloop.ml11
1 files changed, 10 insertions, 1 deletions
diff --git a/toplevel/coqloop.ml b/toplevel/coqloop.ml
index ae0b94476..7ad8e2c05 100644
--- a/toplevel/coqloop.ml
+++ b/toplevel/coqloop.ml
@@ -339,6 +339,8 @@ let loop_flush_all () =
Format.pp_print_flush !Topfmt.std_ft ();
Format.pp_print_flush !Topfmt.err_ft ()
+let drop_last_doc = ref None
+
let rec loop ~time ~state =
let open Vernac.State in
Sys.catch_break true;
@@ -353,7 +355,14 @@ let rec loop ~time ~state =
not possible due exceptions. *)
in vernac_loop ~state
with
- | CErrors.Drop -> state
+ | CErrors.Drop ->
+ (* Due to using exceptions as a form of control, state here goes
+ out of sync as [do_vernac] will never return. We must thus do
+ this hack until we make `Drop` a toplevel-only command. See
+ bug #6872. *)
+ let state = { state with sid = Stm.get_current_state ~doc:state.doc } in
+ drop_last_doc := Some state;
+ state
| CErrors.Quit -> exit 0
| any ->
top_stderr (str "Anomaly: main loop exited with exception: " ++