summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSon Ho2022-01-21 11:05:09 +0100
committerSon Ho2022-01-21 11:05:09 +0100
commit21fec40e3bee3d0544a76fc553067a0928c73b95 (patch)
treef224de13c0b0a643d1ae051c751718e83d9e5361 /src
parent0727595a26b7bbe03568c7e556a09ff449acaf87 (diff)
Implement more invariant checks for the symbolic values
Diffstat (limited to '')
-rw-r--r--src/Invariants.ml37
1 files changed, 34 insertions, 3 deletions
diff --git a/src/Invariants.ml b/src/Invariants.ml
index fc3ab07a..5e114c19 100644
--- a/src/Invariants.ml
+++ b/src/Invariants.ml
@@ -647,6 +647,12 @@ type sv_info = {
(this is why we preemptively expand copyable symbolic values)
- if a symbolic value contains regions: there is at most one occurrence
of this value in the concrete env
+ - if there is an aproj_borrows in the environment, there must also be a
+ corresponding aproj_loans
+ - aproj_loans are mutually disjoint
+ - TODO: aproj_borrows are mutually disjoint
+ - the union of the aproj_loans contains the aproj_borrows applied on the
+ same symbolic values
*)
let check_symbolic_values (_config : C.config) (ctx : C.eval_ctx) : unit =
(* Small utility *)
@@ -717,9 +723,7 @@ let check_symbolic_values (_config : C.config) (ctx : C.eval_ctx) : unit =
(* Check *)
let check_info _id info =
(* TODO: check that:
- * - the loans are mutually disjoint
* - the borrows are mutually disjoint
- * - the unions of the loans/borrows give everything
*)
(* A symbolic value can't be both in the regular environment and inside
* projectors of borrows in abstractions *)
@@ -729,7 +733,34 @@ let check_symbolic_values (_config : C.config) (ctx : C.eval_ctx) : unit =
if ty_has_borrows ctx.type_context.type_infos info.ty then
assert (info.env_count <= 1);
(* A duplicated symbolic value is necessarily primitively copyable *)
- assert (info.env_count <= 1 || ty_is_primitively_copyable info.ty)
+ assert (info.env_count <= 1 || ty_is_primitively_copyable info.ty);
+
+ assert (info.aproj_borrows = [] || info.aproj_loans <> []);
+ (* At the same time:
+ * - check that the loans don't intersect
+ * - compute the set of regions for which we project loans
+ *)
+ (* Check that the loan projectors contain the region projectors *)
+ let loan_regions =
+ List.fold_left
+ (fun regions linfo ->
+ let regions =
+ T.RegionId.Set.fold
+ (fun rid regions ->
+ assert (not (T.RegionId.Set.mem rid regions));
+ T.RegionId.Set.add rid regions)
+ regions linfo.regions
+ in
+ regions)
+ T.RegionId.Set.empty info.aproj_loans
+ in
+ (* Check that the union of the loan projectors contains the borrow projections. *)
+ List.iter
+ (fun binfo ->
+ assert (
+ projection_contains info.ty loan_regions binfo.proj_ty binfo.regions))
+ info.aproj_borrows;
+ ()
in
M.iter check_info !infos