Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reset the uid counter when restoring the typer's state #1779

Merged
merged 4 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ UNRELEASED
`find_command` that does not raise (#1778)
- Prevent uid clashes by not returning PWO for defs located in the current
interface file (#1781)
- Reset uid counters when restoring the typer cache so that uids are stable
across re-typing (#1779)
+ editor modes
- emacs: add basic support for project-wide occurrences (#1766)
- vim: add basic support for project-wide occurrences (#1767, @Julow)
Expand Down
43 changes: 30 additions & 13 deletions src/kernel/mtyper.ml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type ('p,'t) item = {
typedtree_items: 't list * Types.signature_item list;
part_snapshot : Types.snapshot;
part_stamp : int;
part_uid : int;
part_env : Env.t;
part_errors : exn list;
part_checks : Typecore.delayed_check list;
Expand All @@ -49,6 +50,7 @@ type 'a cache_result = {
env : Env.t;
snapshot : Types.snapshot;
ident_stamp : int;
uid_stamp : int;
value : 'a;
index : (Shape.Uid.t * Longident.t Location.loc, unit) Stamped_hashtable.t;
}
Expand All @@ -60,15 +62,16 @@ let fresh_env config =
let env0 = Extension.register Mconfig.(config.merlin.extensions) env0 in
let snap0 = Btype.snapshot () in
let stamp0 = Ident.get_currentstamp () in
(env0, snap0, stamp0)
let uid0 = Shape.Uid.get_current_stamp () in
(env0, snap0, stamp0, uid0)

let get_cache config =
match !cache with
| Some ({ snapshot; _ } as c) when Types.is_valid snapshot -> c
| Some _ | None ->
let env, snapshot, ident_stamp = fresh_env config in
let env, snapshot, ident_stamp, uid_stamp = fresh_env config in
let index = Stamped_hashtable.create !index_changelog 256 in
{ env; snapshot; ident_stamp; value = None; index }
{ env; snapshot; ident_stamp; uid_stamp; value = None; index }

let return_and_cache status =
cache := Some ({ status with value = Some status.value });
Expand All @@ -80,6 +83,7 @@ type result = {
initial_snapshot : Types.snapshot;
initial_stamp : int;
stamp : int;
initial_uid_stamp : int;
typedtree : typedtree_items;
index : (Shape.Uid.t * Longident.t Location.loc, unit) Stamped_hashtable.t;
cache_stat : typer_cache_stats
Expand Down Expand Up @@ -116,6 +120,7 @@ let rec type_structure caught env = function
parsetree_item; typedtree_items; part_env;
part_snapshot = Btype.snapshot ();
part_stamp = Ident.get_currentstamp ();
part_uid = Shape.Uid.get_current_stamp ();
part_errors = !caught;
part_checks = !Typecore.delayed_checks;
part_warnings = Warnings.backup ();
Expand All @@ -131,6 +136,7 @@ let rec type_signature caught env = function
parsetree_item; typedtree_items = (sig_items, sig_type); part_env;
part_snapshot = Btype.snapshot ();
part_stamp = Ident.get_currentstamp ();
part_uid = Shape.Uid.get_current_stamp ();
part_errors = !caught;
part_checks = !Typecore.delayed_checks;
part_warnings = Warnings.backup ();
Expand All @@ -139,60 +145,70 @@ let rec type_signature caught env = function
| [] -> []

let type_implementation config caught parsetree =
let { env; snapshot; ident_stamp; value = prefix; index; _ } = get_cache config in
let { env; snapshot; ident_stamp; uid_stamp; value = prefix; index; _ } =
get_cache config
in
let prefix, parsetree, cache_stats =
match prefix with
| Some (`Implementation items) -> compatible_prefix items parsetree
| Some (`Interface _) | None -> ([], parsetree, Miss)
in
let env', snap', stamp', warn' = match prefix with
| [] -> (env, snapshot, ident_stamp, Warnings.backup ())
let env', snap', stamp', uid_stamp', warn' = match prefix with
| [] -> (env, snapshot, ident_stamp, uid_stamp, Warnings.backup ())
| x :: _ ->
caught := x.part_errors;
Typecore.delayed_checks := x.part_checks;
(x.part_env, x.part_snapshot, x.part_stamp, x.part_warnings)
(x.part_env, x.part_snapshot, x.part_stamp, x.part_uid, x.part_warnings)
in
Btype.backtrack snap';
Warnings.restore warn';
Env.cleanup_functor_caches ~stamp:stamp';
let stamp = List.length prefix - 1 in
Stamped_hashtable.backtrack !index_changelog ~stamp;
Env.cleanup_usage_tables ~stamp:uid_stamp';
Shape.Uid.restore_stamp uid_stamp';
let suffix = type_structure caught env' parsetree in
let () =
List.iteri ~f:(fun i { typedtree_items = (items, _); _ } ->
let stamp = stamp + i + 1 in
!index_items ~index ~stamp config (`Impl items)) suffix
in
let value = `Implementation (List.rev_append prefix suffix) in
return_and_cache { env; snapshot; ident_stamp; value; index }, cache_stats
return_and_cache { env; snapshot; ident_stamp; uid_stamp; value; index },
cache_stats

let type_interface config caught parsetree =
let { env; snapshot; ident_stamp; value = prefix; index; _ } = get_cache config in
let { env; snapshot; ident_stamp; uid_stamp; value = prefix; index; _ } =
get_cache config
in
let prefix, parsetree, cache_stats =
match prefix with
| Some (`Interface items) -> compatible_prefix items parsetree
| Some (`Implementation _) | None -> ([], parsetree, Miss)
in
let env', snap', stamp', warn' = match prefix with
| [] -> (env, snapshot, ident_stamp, Warnings.backup ())
let env', snap', stamp', uid_stamp', warn' = match prefix with
| [] -> (env, snapshot, ident_stamp, uid_stamp, Warnings.backup ())
| x :: _ ->
caught := x.part_errors;
Typecore.delayed_checks := x.part_checks;
(x.part_env, x.part_snapshot, x.part_stamp, x.part_warnings)
(x.part_env, x.part_snapshot, x.part_stamp, x.part_uid, x.part_warnings)
in
Btype.backtrack snap';
Warnings.restore warn';
Env.cleanup_functor_caches ~stamp:stamp';
let stamp = List.length prefix in
Stamped_hashtable.backtrack !index_changelog ~stamp;
Env.cleanup_usage_tables ~stamp:uid_stamp';
Shape.Uid.restore_stamp uid_stamp';
let suffix = type_signature caught env' parsetree in
let () =
List.iteri ~f:(fun i { typedtree_items = (items, _); _ } ->
let stamp = stamp + i + 1 in
!index_items ~index ~stamp config (`Intf items)) suffix
in
let value = `Interface (List.rev_append prefix suffix) in
return_and_cache { env; snapshot; ident_stamp; value; index}, cache_stats
return_and_cache { env; snapshot; ident_stamp; uid_stamp; value; index},
cache_stats

let run config parsetree =
if not (Env.check_state_consistency ()) then (
Expand All @@ -219,6 +235,7 @@ let run config parsetree =
initial_snapshot = cached_result.snapshot;
initial_stamp = cached_result.ident_stamp;
stamp;
initial_uid_stamp = cached_result.uid_stamp;
typedtree = cached_result.value;
index = cached_result.index;
cache_stat;
Expand Down
Loading
Loading