Skip to content

Commit 538e153

Browse files
Merge PR #20674: Stronger synterp/interp phase split checking
Reviewed-by: ppedrot Co-authored-by: ppedrot <ppedrot@users.noreply.github.com>
2 parents a3a2976 + 3fd6e59 commit 538e153

File tree

12 files changed

+60
-24
lines changed

12 files changed

+60
-24
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
overlay elpi https://github.com/SkySkimmer/coq-elpi stronger-synterp-flag 20674

lib/flags.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ let in_ml_toplevel = ref false
5353

5454
let raw_print = ref false
5555

56-
let in_synterp_phase = ref false
56+
let in_synterp_phase = ref None
5757

5858
(* Translate *)
5959
let beautify = ref false

lib/flags.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ val in_debugger : bool ref
4545
val in_ml_toplevel : bool ref
4646

4747
(* Used to check stages are used correctly. *)
48-
val in_synterp_phase : bool ref
48+
val in_synterp_phase : bool option ref
4949

5050
(* Set Printing All flag. For some reason it is a global flag *)
5151
val raw_print : bool ref

library/global.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ let is_curmod_library () =
3535
Safe_typing.is_curmod_library !global_env
3636

3737
let assert_not_synterp () =
38-
if !Flags.in_synterp_phase then
38+
if !Flags.in_synterp_phase = Some true then
3939
CErrors.anomaly (
4040
Pp.strbrk"The global environment cannot be accessed during the syntactic interpretation phase.")
4141

library/lib.ml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,20 @@ let add_discharged_leaf obj =
515515

516516
let add_leaf obj =
517517
Libobject.cache_object (prefix(),obj);
518-
match Libobject.object_stage obj with
518+
let ostage = Libobject.object_stage obj in
519+
let ok_stage = match !Flags.in_synterp_phase with
520+
| None -> true
521+
| Some false -> ostage == Interp
522+
| Some true -> ostage == Synterp
523+
in
524+
let () = if not ok_stage then
525+
let ppstage = match ostage with Interp -> "interp" | Synterp -> "synterp" in
526+
CErrors.anomaly
527+
Pp.(str "Adding object " ++
528+
str (Libobject.object_name obj) ++
529+
str " in incorrect stage (object_stage = " ++ str ppstage ++ str ").")
530+
in
531+
match ostage with
519532
| Summary.Stage.Synterp ->
520533
SynterpActions.add_leaf_entry (AtomicObject obj)
521534
| Summary.Stage.Interp ->

library/libobject.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,10 @@ let object_stage (Dyn.Dyn (tag, v)) =
246246
let O decl = DynMap.find tag !cache_tab in
247247
decl.object_stage
248248

249+
let object_name (Dyn.Dyn (tag, v)) =
250+
let O decl = DynMap.find tag !cache_tab in
251+
decl.object_name
252+
249253
let dump = Dyn.dump
250254

251255
let local_object_nodischarge ?stage s ~cache =

library/libobject.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ val load_object : int -> object_prefix * obj -> unit
238238
val open_object : open_filter -> int -> object_prefix * obj -> unit
239239
val subst_object : substitution * obj -> obj
240240
val classify_object : obj -> substitutivity
241+
val object_name : obj -> string
241242
val object_stage : obj -> Summary.Stage.t
242243

243244
type discharged_obj

parsing/procq.ml

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ let empty_full_state =
4949
user_state = GramState.empty;
5050
}
5151

52+
let assert_synterp () =
53+
if !Flags.in_synterp_phase = Some false then
54+
CErrors.anomaly Pp.(str "The grammar cannot be modified during the interp phase.")
55+
5256
(** Not marshallable! *)
5357
let state = ref empty_full_state
5458

@@ -73,7 +77,9 @@ let modify_state_unsync f state =
7377
let current_state = if is_base then base_state else f state.current_state in
7478
{ state with base_state; current_state }
7579

76-
let modify_state_unsync f () = state := modify_state_unsync f !state
80+
let modify_state_unsync f () =
81+
assert_synterp ();
82+
state := modify_state_unsync f !state
7783

7884
let modify_keyword_state f =
7985
modify_state_unsync (fun {estate;kwstate;recover;has_non_assoc} -> {estate; kwstate = f kwstate; recover; has_non_assoc})
@@ -90,6 +96,7 @@ let make_entry_unsync make remake state =
9096
{ state with base_state; current_state }, e
9197

9298
let make_entry_unsync make remake () =
99+
assert_synterp();
93100
let statev, e = make_entry_unsync make remake !state in
94101
state := statev;
95102
e
@@ -129,7 +136,9 @@ let grammar_extend_sync user_state entry rules state =
129136
current_sync_extensions = GramExt entry :: state.current_sync_extensions;
130137
}
131138

132-
let grammar_extend_sync st e r () = state := grammar_extend_sync st e r !state
139+
let grammar_extend_sync st e r () =
140+
assert_synterp();
141+
state := grammar_extend_sync st e r !state
133142

134143
type ('a,'b) entry_extension = {
135144
eext_fun : 'a -> 'b Entry.t -> GramState.t -> GramState.t;
@@ -157,6 +166,7 @@ let extend_entry_sync (type a b)
157166
state, e
158167

159168
let extend_entry_sync tag interp data () =
169+
assert_synterp();
160170
let statev, e = extend_entry_sync tag interp data !state in
161171
state := statev;
162172
e
@@ -469,19 +479,21 @@ let replay_sync_extension = function
469479
| GramExt (Dyn (tag,g)) -> extend_grammar_command tag g
470480
| EntryExt (tag,data) -> ignore (extend_entry_command tag data : _ Entry.t)
471481

472-
let unfreeze = function
473-
| {frozen_sync;} as frozen ->
474-
let to_remove, to_add, _common = factorize_grams (!state).current_sync_extensions frozen_sync in
475-
if CList.is_empty to_remove then begin
476-
List.iter replay_sync_extension (List.rev to_add);
477-
unfreeze_only_keywords frozen
478-
end
479-
else begin
480-
state := reset_to_base !state;
481-
List.iter replay_sync_extension (List.rev frozen_sync);
482-
(* put back the keyword state, needed to support ssr hacks *)
483-
unfreeze_only_keywords frozen
484-
end
482+
let unfreeze ({frozen_sync;} as frozen) =
483+
(* allow unfreezing synterp state even during interp phase *)
484+
Flags.with_modified_ref Flags.in_synterp_phase (fun _ -> None) (fun () ->
485+
let to_remove, to_add, _common = factorize_grams (!state).current_sync_extensions frozen_sync in
486+
if CList.is_empty to_remove then begin
487+
List.iter replay_sync_extension (List.rev to_add);
488+
unfreeze_only_keywords frozen
489+
end
490+
else begin
491+
state := reset_to_base !state;
492+
List.iter replay_sync_extension (List.rev frozen_sync);
493+
(* put back the keyword state, needed to support ssr hacks *)
494+
unfreeze_only_keywords frozen
495+
end)
496+
()
485497

486498
let freeze_state state = {
487499
frozen_sync = state.current_sync_extensions;

stm/stm.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ end = struct (* {{{ *)
402402
403403
In case you are hitting the race enable stm_debug.
404404
*)
405-
if !stm_debug then Flags.in_synterp_phase := false;
405+
Flags.in_synterp_phase := Some false;
406406

407407
let fname =
408408
"stm_" ^ Str.global_replace (Str.regexp " ") "_" (Spawned.process_id ()) in

vernac/synterp.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,4 +502,4 @@ and synterp_control ~intern CAst.{ loc; v = cmd } =
502502
CAst.make ?loc { expr; control; attrs = cmd.attrs }
503503

504504
let synterp_control ~intern cmd =
505-
Flags.with_option Flags.in_synterp_phase (synterp_control ~intern) cmd
505+
Flags.with_modified_ref Flags.in_synterp_phase (fun _ -> Some true) (synterp_control ~intern) cmd

0 commit comments

Comments
 (0)