summaryrefslogtreecommitdiff
path: root/compiler/InterpreterBorrows.ml
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--compiler/InterpreterBorrows.ml757
-rw-r--r--compiler/InterpreterBorrows.mli31
2 files changed, 451 insertions, 337 deletions
diff --git a/compiler/InterpreterBorrows.ml b/compiler/InterpreterBorrows.ml
index 17810705..e593ae75 100644
--- a/compiler/InterpreterBorrows.ml
+++ b/compiler/InterpreterBorrows.ml
@@ -7,6 +7,7 @@ open TypesUtils
open InterpreterUtils
open InterpreterBorrowsCore
open InterpreterProjectors
+open Errors
(** The local logger *)
let log = Logging.borrows_log
@@ -29,8 +30,9 @@ let log = Logging.borrows_log
loans. This is used to merge borrows with abstractions, to compute loop
fixed points for instance.
*)
-let end_borrow_get_borrow (allowed_abs : AbstractionId.id option)
- (allow_inner_loans : bool) (l : BorrowId.id) (ctx : eval_ctx) :
+let end_borrow_get_borrow (meta : Meta.meta)
+ (allowed_abs : AbstractionId.id option) (allow_inner_loans : bool)
+ (l : BorrowId.id) (ctx : eval_ctx) :
( eval_ctx * (AbstractionId.id option * g_borrow_content) option,
priority_borrows_or_abs )
result =
@@ -41,7 +43,7 @@ let end_borrow_get_borrow (allowed_abs : AbstractionId.id option)
in
let set_replaced_bc (abs_id : AbstractionId.id option) (bc : g_borrow_content)
=
- assert (Option.is_none !replaced_bc);
+ sanity_check __FILE__ __LINE__ (Option.is_none !replaced_bc) meta;
replaced_bc := Some (abs_id, bc)
in
(* Raise an exception if:
@@ -180,7 +182,7 @@ let end_borrow_get_borrow (allowed_abs : AbstractionId.id option)
* Also note that, as we are moving the borrowed value inside the
* abstraction (and not really giving the value back to the context)
* we do not insert {!AEndedMutBorrow} but rather {!ABottom} *)
- raise (Failure "Unimplemented")
+ craise __FILE__ __LINE__ meta "Unimplemented"
(* ABottom *))
else
(* Update the outer borrows before diving into the child avalue *)
@@ -215,7 +217,7 @@ let end_borrow_get_borrow (allowed_abs : AbstractionId.id option)
set_replaced_bc (fst outer) (Abstract bc);
(* Update the value - note that we are necessarily in the second
* of the two cases described above *)
- let asb = remove_borrow_from_asb l asb in
+ let asb = remove_borrow_from_asb meta l asb in
ABorrow (AProjSharedBorrow asb))
else (* Nothing special to do *)
super#visit_ABorrow outer bc
@@ -223,8 +225,8 @@ let end_borrow_get_borrow (allowed_abs : AbstractionId.id option)
method! visit_abs outer abs =
(* Update the outer abs *)
let outer_abs, outer_borrows = outer in
- assert (Option.is_none outer_abs);
- assert (Option.is_none outer_borrows);
+ sanity_check __FILE__ __LINE__ (Option.is_none outer_abs) meta;
+ sanity_check __FILE__ __LINE__ (Option.is_none outer_borrows) meta;
let outer = (Some abs.abs_id, None) in
super#visit_abs outer abs
end
@@ -244,21 +246,27 @@ let end_borrow_get_borrow (allowed_abs : AbstractionId.id option)
give the value back.
TODO: this was not the case before, so some sanity checks are not useful anymore.
*)
-let give_back_value (config : config) (bid : BorrowId.id) (nv : typed_value)
- (ctx : eval_ctx) : eval_ctx =
+let give_back_value (config : config) (meta : Meta.meta) (bid : BorrowId.id)
+ (nv : typed_value) (ctx : eval_ctx) : eval_ctx =
(* Sanity check *)
- assert (not (loans_in_value nv));
- assert (not (bottom_in_value ctx.ended_regions nv));
+ exec_assert __FILE__ __LINE__
+ (not (loans_in_value nv))
+ meta "Can not end a borrow because the value to give back contains bottom";
+ exec_assert __FILE__ __LINE__
+ (not (bottom_in_value ctx.ended_regions nv))
+ meta "Can not end a borrow because the value to give back contains bottom";
(* Debug *)
log#ldebug
(lazy
("give_back_value:\n- bid: " ^ BorrowId.to_string bid ^ "\n- value: "
- ^ typed_value_to_string ctx nv
- ^ "\n- context:\n" ^ eval_ctx_to_string ctx ^ "\n"));
+ ^ typed_value_to_string ~meta:(Some meta) ctx nv
+ ^ "\n- context:\n"
+ ^ eval_ctx_to_string ~meta:(Some meta) ctx
+ ^ "\n"));
(* We use a reference to check that we updated exactly one loan *)
let replaced : bool ref = ref false in
let set_replaced () =
- assert (not !replaced);
+ sanity_check __FILE__ __LINE__ (not !replaced) meta;
replaced := true
in
(* Whenever giving back symbolic values, they shouldn't contain already ended regions *)
@@ -266,7 +274,7 @@ let give_back_value (config : config) (bid : BorrowId.id) (nv : typed_value)
(* We sometimes need to reborrow values while giving a value back due: prepare that *)
let allow_reborrows = true in
let fresh_reborrow, apply_registered_reborrows =
- prepare_reborrows config allow_reborrows
+ prepare_reborrows config meta allow_reborrows
in
(* The visitor to give back the values *)
let obj =
@@ -300,7 +308,8 @@ let give_back_value (config : config) (bid : BorrowId.id) (nv : typed_value)
("give_back_value: improper type:\n- expected: "
^ ty_to_string ctx ty ^ "\n- received: "
^ ty_to_string ctx nv.ty);
- raise (Failure "Value given back doesn't have the proper type"));
+ craise __FILE__ __LINE__ meta
+ "Value given back doesn't have the proper type");
(* Replace *)
set_replaced ();
nv.value)
@@ -334,7 +343,7 @@ let give_back_value (config : config) (bid : BorrowId.id) (nv : typed_value)
(* Remember the given back value as a meta-value
* TODO: it is a bit annoying to have to deconstruct
* the value... Think about a more elegant way. *)
- let given_back_meta = as_symbolic nv.value in
+ let given_back_meta = as_symbolic meta nv.value in
(* The loan projector *)
let given_back =
mk_aproj_loans_value_from_symbolic_value abs.regions sv
@@ -345,7 +354,7 @@ let give_back_value (config : config) (bid : BorrowId.id) (nv : typed_value)
ABorrow
(AEndedIgnoredMutBorrow
{ given_back; child; given_back_meta })
- | _ -> raise (Failure "Unreachable")
+ | _ -> craise __FILE__ __LINE__ meta "Unreachable"
else
(* Continue exploring *)
ABorrow (super#visit_AIgnoredMutBorrow opt_abs bid' child)
@@ -360,7 +369,7 @@ let give_back_value (config : config) (bid : BorrowId.id) (nv : typed_value)
(* Preparing a bit *)
let regions, ancestors_regions =
match opt_abs with
- | None -> raise (Failure "Unreachable")
+ | None -> craise __FILE__ __LINE__ meta "Unreachable"
| Some abs -> (abs.regions, abs.ancestors_regions)
in
(* Rk.: there is a small issue with the types of the aloan values.
@@ -381,8 +390,8 @@ let give_back_value (config : config) (bid : BorrowId.id) (nv : typed_value)
let given_back_meta = nv in
(* Apply the projection *)
let given_back =
- apply_proj_borrows check_symbolic_no_ended ctx fresh_reborrow
- regions ancestors_regions nv borrowed_value_aty
+ apply_proj_borrows meta check_symbolic_no_ended ctx
+ fresh_reborrow regions ancestors_regions nv borrowed_value_aty
in
(* Continue giving back in the child value *)
let child = super#visit_typed_avalue opt_abs child in
@@ -408,8 +417,8 @@ let give_back_value (config : config) (bid : BorrowId.id) (nv : typed_value)
* we don't register the fact that we inserted the value somewhere
* (i.e., we don't call {!set_replaced}) *)
let given_back =
- apply_proj_borrows check_symbolic_no_ended ctx fresh_reborrow
- regions ancestors_regions nv borrowed_value_aty
+ apply_proj_borrows meta check_symbolic_no_ended ctx
+ fresh_reborrow regions ancestors_regions nv borrowed_value_aty
in
(* Continue giving back in the child value *)
let child = super#visit_typed_avalue opt_abs child in
@@ -426,7 +435,7 @@ let give_back_value (config : config) (bid : BorrowId.id) (nv : typed_value)
(* We remember in which abstraction we are before diving -
* this is necessary for projecting values: we need to know
* over which regions to project *)
- assert (Option.is_none opt_abs);
+ sanity_check __FILE__ __LINE__ (Option.is_none opt_abs) meta;
super#visit_EAbs (Some abs) abs
end
in
@@ -434,16 +443,18 @@ let give_back_value (config : config) (bid : BorrowId.id) (nv : typed_value)
(* Explore the environment *)
let ctx = obj#visit_eval_ctx None ctx in
(* Check we gave back to exactly one loan *)
- assert !replaced;
+ cassert __FILE__ __LINE__ !replaced meta "No loan updated";
(* Apply the reborrows *)
apply_registered_reborrows ctx
(** Give back a *modified* symbolic value. *)
-let give_back_symbolic_value (_config : config) (proj_regions : RegionId.Set.t)
- (proj_ty : rty) (sv : symbolic_value) (nsv : symbolic_value)
- (ctx : eval_ctx) : eval_ctx =
+let give_back_symbolic_value (_config : config) (meta : Meta.meta)
+ (proj_regions : RegionId.Set.t) (proj_ty : rty) (sv : symbolic_value)
+ (nsv : symbolic_value) (ctx : eval_ctx) : eval_ctx =
(* Sanity checks *)
- assert (sv.sv_id <> nsv.sv_id && ty_is_rty proj_ty);
+ sanity_check __FILE__ __LINE__
+ (sv.sv_id <> nsv.sv_id && ty_is_rty proj_ty)
+ meta;
(* Store the given-back value as a meta-value for synthesis purposes *)
let mv = nsv in
(* Substitution function, to replace the borrow projectors over symbolic values *)
@@ -465,11 +476,11 @@ let give_back_symbolic_value (_config : config) (proj_regions : RegionId.Set.t)
type [T]! We thus *mustn't* introduce a projector here.
*)
(* AProjBorrows (nsv, sv.sv_ty) *)
- raise (Failure "TODO")
+ internal_error __FILE__ __LINE__ meta
in
AProjLoans (sv, (mv, child_proj) :: local_given_back)
in
- update_intersecting_aproj_loans proj_regions proj_ty sv subst ctx
+ update_intersecting_aproj_loans meta proj_regions proj_ty sv subst ctx
(** Auxiliary function to end borrows. See {!give_back}.
@@ -484,12 +495,14 @@ let give_back_symbolic_value (_config : config) (proj_regions : RegionId.Set.t)
end abstraction when ending this abstraction. When doing this, we need
to convert the {!avalue} to a {!type:value} by introducing the proper symbolic values.
*)
-let give_back_avalue_to_same_abstraction (_config : config) (bid : BorrowId.id)
- (nv : typed_avalue) (nsv : typed_value) (ctx : eval_ctx) : eval_ctx =
+let give_back_avalue_to_same_abstraction (_config : config) (meta : Meta.meta)
+ (bid : BorrowId.id) (nv : typed_avalue) (nsv : typed_value) (ctx : eval_ctx)
+ : eval_ctx =
(* We use a reference to check that we updated exactly one loan *)
let replaced : bool ref = ref false in
let set_replaced () =
- assert (not !replaced);
+ cassert __FILE__ __LINE__ (not !replaced) meta
+ "Exacly one loan should be updated";
replaced := true
in
let obj =
@@ -532,7 +545,8 @@ let give_back_avalue_to_same_abstraction (_config : config) (bid : BorrowId.id)
("give_back_avalue_to_same_abstraction: improper type:\n\
- expected: " ^ ty_to_string ctx ty ^ "\n- received: "
^ ty_to_string ctx nv.ty);
- raise (Failure "Value given back doesn't have the proper type"));
+ craise __FILE__ __LINE__ meta
+ "Value given back doesn't have the proper type");
(* This is the loan we are looking for: apply the projection to
* the value we give back and replaced this mutable loan with
* an ended loan *)
@@ -558,7 +572,7 @@ let give_back_avalue_to_same_abstraction (_config : config) (bid : BorrowId.id)
* we don't register the fact that we inserted the value somewhere
* (i.e., we don't call {!set_replaced}) *)
(* Sanity check *)
- assert (nv.ty = ty);
+ sanity_check __FILE__ __LINE__ (nv.ty = ty) meta;
ALoan
(AEndedIgnoredMutLoan
{ given_back = nv; child; given_back_meta = nsv }))
@@ -574,7 +588,7 @@ let give_back_avalue_to_same_abstraction (_config : config) (bid : BorrowId.id)
(* Explore the environment *)
let ctx = obj#visit_eval_ctx None ctx in
(* Check we gave back to exactly one loan *)
- assert !replaced;
+ cassert __FILE__ __LINE__ !replaced meta "No loan updated";
(* Return *)
ctx
@@ -587,11 +601,13 @@ let give_back_avalue_to_same_abstraction (_config : config) (bid : BorrowId.id)
we update.
TODO: this was not the case before, so some sanity checks are not useful anymore.
*)
-let give_back_shared _config (bid : BorrowId.id) (ctx : eval_ctx) : eval_ctx =
+let give_back_shared _config (meta : Meta.meta) (bid : BorrowId.id)
+ (ctx : eval_ctx) : eval_ctx =
(* We use a reference to check that we updated exactly one loan *)
let replaced : bool ref = ref false in
let set_replaced () =
- assert (not !replaced);
+ cassert __FILE__ __LINE__ (not !replaced) meta
+ "Exactly one loan should be updated";
replaced := true
in
let obj =
@@ -656,7 +672,7 @@ let give_back_shared _config (bid : BorrowId.id) (ctx : eval_ctx) : eval_ctx =
(* Explore the environment *)
let ctx = obj#visit_eval_ctx None ctx in
(* Check we gave back to exactly one loan *)
- assert !replaced;
+ cassert __FILE__ __LINE__ !replaced meta "No loan updated";
(* Return *)
ctx
@@ -665,12 +681,12 @@ let give_back_shared _config (bid : BorrowId.id) (ctx : eval_ctx) : eval_ctx =
to an environment by inserting a new borrow id in the set of borrows tracked
by a shared value, referenced by the [original_bid] argument.
*)
-let reborrow_shared (original_bid : BorrowId.id) (new_bid : BorrowId.id)
- (ctx : eval_ctx) : eval_ctx =
+let reborrow_shared (meta : Meta.meta) (original_bid : BorrowId.id)
+ (new_bid : BorrowId.id) (ctx : eval_ctx) : eval_ctx =
(* Keep track of changes *)
let r = ref false in
let set_ref () =
- assert (not !r);
+ sanity_check __FILE__ __LINE__ (not !r) meta;
r := true
in
@@ -700,7 +716,7 @@ let reborrow_shared (original_bid : BorrowId.id) (new_bid : BorrowId.id)
let env = obj#visit_env () ctx.env in
(* Check that we reborrowed once *)
- assert !r;
+ sanity_check __FILE__ __LINE__ !r meta;
{ ctx with env }
(** Convert an {!type:avalue} to a {!type:value}.
@@ -719,8 +735,9 @@ let reborrow_shared (original_bid : BorrowId.id) (new_bid : BorrowId.id)
be expanded (because expanding this symbolic value would require expanding
a reference whose region has already ended).
*)
-let convert_avalue_to_given_back_value (av : typed_avalue) : symbolic_value =
- mk_fresh_symbolic_value av.ty
+let convert_avalue_to_given_back_value (meta : Meta.meta) (av : typed_avalue) :
+ symbolic_value =
+ mk_fresh_symbolic_value meta av.ty
(** Auxiliary function: see {!end_borrow_aux}.
@@ -738,18 +755,20 @@ let convert_avalue_to_given_back_value (av : typed_avalue) : symbolic_value =
borrows. This kind of internal reshuffling. should be similar to ending
abstractions (it is tantamount to ending *sub*-abstractions).
*)
-let give_back (config : config) (l : BorrowId.id) (bc : g_borrow_content)
- (ctx : eval_ctx) : eval_ctx =
+let give_back (config : config) (meta : Meta.meta) (l : BorrowId.id)
+ (bc : g_borrow_content) (ctx : eval_ctx) : eval_ctx =
(* Debug *)
log#ldebug
(lazy
(let bc =
match bc with
- | Concrete bc -> borrow_content_to_string ctx bc
- | Abstract bc -> aborrow_content_to_string ctx bc
+ | Concrete bc -> borrow_content_to_string ~meta:(Some meta) ctx bc
+ | Abstract bc -> aborrow_content_to_string ~meta:(Some meta) ctx bc
in
"give_back:\n- bid: " ^ BorrowId.to_string l ^ "\n- content: " ^ bc
- ^ "\n- context:\n" ^ eval_ctx_to_string ctx ^ "\n"));
+ ^ "\n- context:\n"
+ ^ eval_ctx_to_string ~meta:(Some meta) ctx
+ ^ "\n"));
(* This is used for sanity checks *)
let sanity_ek =
{ enter_shared_loans = true; enter_mut_borrows = true; enter_abs = true }
@@ -757,53 +776,61 @@ let give_back (config : config) (l : BorrowId.id) (bc : g_borrow_content)
match bc with
| Concrete (VMutBorrow (l', tv)) ->
(* Sanity check *)
- assert (l' = l);
- assert (not (loans_in_value tv));
+ sanity_check __FILE__ __LINE__ (l' = l) meta;
+ sanity_check __FILE__ __LINE__ (not (loans_in_value tv)) meta;
(* Check that the corresponding loan is somewhere - purely a sanity check *)
- assert (Option.is_some (lookup_loan_opt sanity_ek l ctx));
+ sanity_check __FILE__ __LINE__
+ (Option.is_some (lookup_loan_opt meta sanity_ek l ctx))
+ meta;
(* Update the context *)
- give_back_value config l tv ctx
+ give_back_value config meta l tv ctx
| Concrete (VSharedBorrow l' | VReservedMutBorrow l') ->
(* Sanity check *)
- assert (l' = l);
+ sanity_check __FILE__ __LINE__ (l' = l) meta;
(* Check that the borrow is somewhere - purely a sanity check *)
- assert (Option.is_some (lookup_loan_opt sanity_ek l ctx));
+ sanity_check __FILE__ __LINE__
+ (Option.is_some (lookup_loan_opt meta sanity_ek l ctx))
+ meta;
(* Update the context *)
- give_back_shared config l ctx
+ give_back_shared config meta l ctx
| Abstract (AMutBorrow (l', av)) ->
(* Sanity check *)
- assert (l' = l);
+ sanity_check __FILE__ __LINE__ (l' = l) meta;
(* Check that the corresponding loan is somewhere - purely a sanity check *)
- assert (Option.is_some (lookup_loan_opt sanity_ek l ctx));
+ sanity_check __FILE__ __LINE__
+ (Option.is_some (lookup_loan_opt meta sanity_ek l ctx))
+ meta;
(* Convert the avalue to a (fresh symbolic) value.
Rem.: we shouldn't do this here. We should do this in a function
which takes care of ending *sub*-abstractions.
*)
- let sv = convert_avalue_to_given_back_value av in
+ let sv = convert_avalue_to_given_back_value meta av in
(* Update the context *)
- give_back_avalue_to_same_abstraction config l av
+ give_back_avalue_to_same_abstraction config meta l av
(mk_typed_value_from_symbolic_value sv)
ctx
| Abstract (ASharedBorrow l') ->
(* Sanity check *)
- assert (l' = l);
+ sanity_check __FILE__ __LINE__ (l' = l) meta;
(* Check that the borrow is somewhere - purely a sanity check *)
- assert (Option.is_some (lookup_loan_opt sanity_ek l ctx));
+ sanity_check __FILE__ __LINE__
+ (Option.is_some (lookup_loan_opt meta sanity_ek l ctx))
+ meta;
(* Update the context *)
- give_back_shared config l ctx
+ give_back_shared config meta l ctx
| Abstract (AProjSharedBorrow asb) ->
(* Sanity check *)
- assert (borrow_in_asb l asb);
+ sanity_check __FILE__ __LINE__ (borrow_in_asb l asb) meta;
(* Update the context *)
- give_back_shared config l ctx
+ give_back_shared config meta l ctx
| Abstract
( AEndedMutBorrow _ | AIgnoredMutBorrow _ | AEndedIgnoredMutBorrow _
| AEndedSharedBorrow ) ->
- raise (Failure "Unreachable")
+ craise __FILE__ __LINE__ meta "Unreachable"
-let check_borrow_disappeared (fun_name : string) (l : BorrowId.id)
- (ctx0 : eval_ctx) : cm_fun =
+let check_borrow_disappeared (meta : Meta.meta) (fun_name : string)
+ (l : BorrowId.id) (ctx0 : eval_ctx) : cm_fun =
let check_disappeared (ctx : eval_ctx) : unit =
let _ =
match lookup_borrow_opt ek_all l ctx with
@@ -813,20 +840,22 @@ let check_borrow_disappeared (fun_name : string) (l : BorrowId.id)
(lazy
(fun_name ^ ": " ^ BorrowId.to_string l
^ ": borrow didn't disappear:\n- original context:\n"
- ^ eval_ctx_to_string ctx0 ^ "\n\n- new context:\n"
- ^ eval_ctx_to_string ctx));
- raise (Failure "Borrow not eliminated")
+ ^ eval_ctx_to_string ~meta:(Some meta) ctx0
+ ^ "\n\n- new context:\n"
+ ^ eval_ctx_to_string ~meta:(Some meta) ctx));
+ craise __FILE__ __LINE__ meta "Borrow not eliminated"
in
- match lookup_loan_opt ek_all l ctx with
+ match lookup_loan_opt meta ek_all l ctx with
| None -> () (* Ok *)
| Some _ ->
log#lerror
(lazy
(fun_name ^ ": " ^ BorrowId.to_string l
^ ": loan didn't disappear:\n- original context:\n"
- ^ eval_ctx_to_string ctx0 ^ "\n\n- new context:\n"
- ^ eval_ctx_to_string ctx));
- raise (Failure "Loan not eliminated")
+ ^ eval_ctx_to_string ~meta:(Some meta) ctx0
+ ^ "\n\n- new context:\n"
+ ^ eval_ctx_to_string ~meta:(Some meta) ctx));
+ craise __FILE__ __LINE__ meta "Loan not eliminated"
in
unit_to_cm_fun check_disappeared
@@ -851,26 +880,27 @@ let check_borrow_disappeared (fun_name : string) (l : BorrowId.id)
perform anything smart and is trusted, and another function for the
book-keeping.
*)
-let rec end_borrow_aux (config : config) (chain : borrow_or_abs_ids)
- (allowed_abs : AbstractionId.id option) (l : BorrowId.id) : cm_fun =
+let rec end_borrow_aux (config : config) (meta : Meta.meta)
+ (chain : borrow_or_abs_ids) (allowed_abs : AbstractionId.id option)
+ (l : BorrowId.id) : cm_fun =
fun cf ctx ->
(* Check that we don't loop *)
let chain0 = chain in
let chain =
- add_borrow_or_abs_id_to_chain "end_borrow_aux: " (BorrowId l) chain
+ add_borrow_or_abs_id_to_chain meta "end_borrow_aux: " (BorrowId l) chain
in
log#ldebug
(lazy
("end borrow: " ^ BorrowId.to_string l ^ ":\n- original context:\n"
- ^ eval_ctx_to_string ctx));
+ ^ eval_ctx_to_string ~meta:(Some meta) ctx));
(* Utility function for the sanity checks: check that the borrow disappeared
* from the context *)
let ctx0 = ctx in
- let cf_check : cm_fun = check_borrow_disappeared "end borrow" l ctx0 in
+ let cf_check : cm_fun = check_borrow_disappeared meta "end borrow" l ctx0 in
(* Start by ending the borrow itself (we lookup it up and replace it with [Bottom] *)
let allow_inner_loans = false in
- match end_borrow_get_borrow allowed_abs allow_inner_loans l ctx with
+ match end_borrow_get_borrow meta allowed_abs allow_inner_loans l ctx with
(* Two cases:
- error: we found outer borrows (the borrow is inside a borrowed value) or
inner loans (the borrow contains loans)
@@ -899,29 +929,29 @@ let rec end_borrow_aux (config : config) (chain : borrow_or_abs_ids)
* inside another borrow *)
let allowed_abs' = None in
(* End the outer borrows *)
- let cc = end_borrows_aux config chain allowed_abs' bids in
+ let cc = end_borrows_aux config meta chain allowed_abs' bids in
(* Retry to end the borrow *)
- let cc = comp cc (end_borrow_aux config chain0 allowed_abs l) in
+ let cc = comp cc (end_borrow_aux config meta chain0 allowed_abs l) in
(* Check and apply *)
comp cc cf_check cf ctx
| OuterBorrows (Borrow bid) | InnerLoans (Borrow bid) ->
let allowed_abs' = None in
(* End the outer borrow *)
- let cc = end_borrow_aux config chain allowed_abs' bid in
+ let cc = end_borrow_aux config meta chain allowed_abs' bid in
(* Retry to end the borrow *)
- let cc = comp cc (end_borrow_aux config chain0 allowed_abs l) in
+ let cc = comp cc (end_borrow_aux config meta chain0 allowed_abs l) in
(* Check and apply *)
comp cc cf_check cf ctx
| OuterAbs abs_id ->
(* The borrow is inside an abstraction: end the whole abstraction *)
- let cf_end_abs = end_abstraction_aux config chain abs_id in
+ let cf_end_abs = end_abstraction_aux config meta chain abs_id in
(* Compose with a sanity check *)
comp cf_end_abs cf_check cf ctx)
| Ok (ctx, None) ->
log#ldebug (lazy "End borrow: borrow not found");
(* It is possible that we can't find a borrow in symbolic mode (ending
* an abstraction may end several borrows at once *)
- assert (config.mode = SymbolicMode);
+ sanity_check __FILE__ __LINE__ (config.mode = SymbolicMode) meta;
(* Do a sanity check and continue *)
cf_check cf ctx
(* We found a borrow and replaced it with [Bottom]: give it back (i.e., update
@@ -930,10 +960,12 @@ let rec end_borrow_aux (config : config) (chain : borrow_or_abs_ids)
(* Sanity check: the borrowed value shouldn't contain loans *)
(match bc with
| Concrete (VMutBorrow (_, bv)) ->
- assert (Option.is_none (get_first_loan_in_value bv))
+ sanity_check __FILE__ __LINE__
+ (Option.is_none (get_first_loan_in_value bv))
+ meta
| _ -> ());
(* Give back the value *)
- let ctx = give_back config l bc ctx in
+ let ctx = give_back config meta l bc ctx in
(* Do a sanity check and continue *)
let cc = cf_check in
(* Save a snapshot of the environment for the name generation *)
@@ -941,23 +973,25 @@ let rec end_borrow_aux (config : config) (chain : borrow_or_abs_ids)
(* Compose *)
cc cf ctx
-and end_borrows_aux (config : config) (chain : borrow_or_abs_ids)
- (allowed_abs : AbstractionId.id option) (lset : BorrowId.Set.t) : cm_fun =
+and end_borrows_aux (config : config) (meta : Meta.meta)
+ (chain : borrow_or_abs_ids) (allowed_abs : AbstractionId.id option)
+ (lset : BorrowId.Set.t) : cm_fun =
fun cf ->
(* This is not necessary, but we prefer to reorder the borrow ids,
* so that we actually end from the smallest id to the highest id - just
* a matter of taste, and may make debugging easier *)
let ids = BorrowId.Set.fold (fun id ids -> id :: ids) lset [] in
List.fold_left
- (fun cf id -> end_borrow_aux config chain allowed_abs id cf)
+ (fun cf id -> end_borrow_aux config meta chain allowed_abs id cf)
cf ids
-and end_abstraction_aux (config : config) (chain : borrow_or_abs_ids)
- (abs_id : AbstractionId.id) : cm_fun =
+and end_abstraction_aux (config : config) (meta : Meta.meta)
+ (chain : borrow_or_abs_ids) (abs_id : AbstractionId.id) : cm_fun =
fun cf ctx ->
(* Check that we don't loop *)
let chain =
- add_borrow_or_abs_id_to_chain "end_abstraction_aux: " (AbsId abs_id) chain
+ add_borrow_or_abs_id_to_chain meta "end_abstraction_aux: " (AbsId abs_id)
+ chain
in
(* Remember the original context for printing purposes *)
let ctx0 = ctx in
@@ -965,7 +999,8 @@ and end_abstraction_aux (config : config) (chain : borrow_or_abs_ids)
(lazy
("end_abstraction_aux: "
^ AbstractionId.to_string abs_id
- ^ "\n- original context:\n" ^ eval_ctx_to_string ctx0));
+ ^ "\n- original context:\n"
+ ^ eval_ctx_to_string ~meta:(Some meta) ctx0));
(* Lookup the abstraction - note that if we end a list of abstractions,
ending one abstraction may lead to the current abstraction having
@@ -983,14 +1018,13 @@ and end_abstraction_aux (config : config) (chain : borrow_or_abs_ids)
(* Check that we can end the abstraction *)
if abs.can_end then ()
else
- raise
- (Failure
- ("Can't end abstraction "
- ^ AbstractionId.to_string abs.abs_id
- ^ " as it is set as non-endable"));
+ craise __FILE__ __LINE__ meta
+ ("Can't end abstraction "
+ ^ AbstractionId.to_string abs.abs_id
+ ^ " as it is set as non-endable");
(* End the parent abstractions first *)
- let cc = end_abstractions_aux config chain abs.parents in
+ let cc = end_abstractions_aux config meta chain abs.parents in
let cc =
comp_unit cc (fun ctx ->
log#ldebug
@@ -998,22 +1032,23 @@ and end_abstraction_aux (config : config) (chain : borrow_or_abs_ids)
("end_abstraction_aux: "
^ AbstractionId.to_string abs_id
^ "\n- context after parent abstractions ended:\n"
- ^ eval_ctx_to_string ctx)))
+ ^ eval_ctx_to_string ~meta:(Some meta) ctx)))
in
(* End the loans inside the abstraction *)
- let cc = comp cc (end_abstraction_loans config chain abs_id) in
+ let cc = comp cc (end_abstraction_loans config meta chain abs_id) in
let cc =
comp_unit cc (fun ctx ->
log#ldebug
(lazy
("end_abstraction_aux: "
^ AbstractionId.to_string abs_id
- ^ "\n- context after loans ended:\n" ^ eval_ctx_to_string ctx)))
+ ^ "\n- context after loans ended:\n"
+ ^ eval_ctx_to_string ~meta:(Some meta) ctx)))
in
(* End the abstraction itself by redistributing the borrows it contains *)
- let cc = comp cc (end_abstraction_borrows config chain abs_id) in
+ let cc = comp cc (end_abstraction_borrows config meta chain abs_id) in
(* End the regions owned by the abstraction - note that we don't need to
* relookup the abstraction: the set of regions in an abstraction never
@@ -1029,7 +1064,9 @@ and end_abstraction_aux (config : config) (chain : borrow_or_abs_ids)
(* Remove all the references to the id of the current abstraction, and remove
* the abstraction itself.
* **Rk.**: this is where we synthesize the updated symbolic AST *)
- let cc = comp cc (end_abstraction_remove_from_context config abs_id) in
+ let cc =
+ comp cc (end_abstraction_remove_from_context config meta abs_id)
+ in
(* Debugging *)
let cc =
@@ -1038,12 +1075,14 @@ and end_abstraction_aux (config : config) (chain : borrow_or_abs_ids)
(lazy
("end_abstraction_aux: "
^ AbstractionId.to_string abs_id
- ^ "\n- original context:\n" ^ eval_ctx_to_string ctx0
- ^ "\n\n- new context:\n" ^ eval_ctx_to_string ctx)))
+ ^ "\n- original context:\n"
+ ^ eval_ctx_to_string ~meta:(Some meta) ctx0
+ ^ "\n\n- new context:\n"
+ ^ eval_ctx_to_string ~meta:(Some meta) ctx)))
in
(* Sanity check: ending an abstraction must preserve the invariants *)
- let cc = comp cc Invariants.cf_check_invariants in
+ let cc = comp cc (Invariants.cf_check_invariants meta) in
(* Save a snapshot of the environment for the name generation *)
let cc = comp cc SynthesizeSymbolic.cf_save_snapshot in
@@ -1051,19 +1090,19 @@ and end_abstraction_aux (config : config) (chain : borrow_or_abs_ids)
(* Apply the continuation *)
cc cf ctx
-and end_abstractions_aux (config : config) (chain : borrow_or_abs_ids)
- (abs_ids : AbstractionId.Set.t) : cm_fun =
+and end_abstractions_aux (config : config) (meta : Meta.meta)
+ (chain : borrow_or_abs_ids) (abs_ids : AbstractionId.Set.t) : cm_fun =
fun cf ->
(* This is not necessary, but we prefer to reorder the abstraction ids,
* so that we actually end from the smallest id to the highest id - just
* a matter of taste, and may make debugging easier *)
let abs_ids = AbstractionId.Set.fold (fun id ids -> id :: ids) abs_ids [] in
List.fold_left
- (fun cf id -> end_abstraction_aux config chain id cf)
+ (fun cf id -> end_abstraction_aux config meta chain id cf)
cf abs_ids
-and end_abstraction_loans (config : config) (chain : borrow_or_abs_ids)
- (abs_id : AbstractionId.id) : cm_fun =
+and end_abstraction_loans (config : config) (meta : Meta.meta)
+ (chain : borrow_or_abs_ids) (abs_id : AbstractionId.id) : cm_fun =
fun cf ctx ->
(* Lookup the abstraction *)
let abs = ctx_lookup_abs ctx abs_id in
@@ -1071,7 +1110,7 @@ and end_abstraction_loans (config : config) (chain : borrow_or_abs_ids)
*
* We ignore the "ignored mut/shared loans": as we should have already ended
* the parent abstractions, they necessarily come from children. *)
- let opt_loan = get_first_non_ignored_aloan_in_abstraction abs in
+ let opt_loan = get_first_non_ignored_aloan_in_abstraction meta abs in
match opt_loan with
| None ->
(* No loans: nothing to update *)
@@ -1080,24 +1119,26 @@ and end_abstraction_loans (config : config) (chain : borrow_or_abs_ids)
(* There are loans: end the corresponding borrows, then recheck *)
let cc : cm_fun =
match bids with
- | Borrow bid -> end_borrow_aux config chain None bid
- | Borrows bids -> end_borrows_aux config chain None bids
+ | Borrow bid -> end_borrow_aux config meta chain None bid
+ | Borrows bids -> end_borrows_aux config meta chain None bids
in
(* Reexplore, looking for loans *)
- let cc = comp cc (end_abstraction_loans config chain abs_id) in
+ let cc = comp cc (end_abstraction_loans config meta chain abs_id) in
(* Continue *)
cc cf ctx
| Some (SymbolicValue sv) ->
(* There is a proj_loans over a symbolic value: end the proj_borrows
* which intersect this proj_loans, then end the proj_loans itself *)
- let cc = end_proj_loans_symbolic config chain abs_id abs.regions sv in
+ let cc =
+ end_proj_loans_symbolic config meta chain abs_id abs.regions sv
+ in
(* Reexplore, looking for loans *)
- let cc = comp cc (end_abstraction_loans config chain abs_id) in
+ let cc = comp cc (end_abstraction_loans config meta chain abs_id) in
(* Continue *)
cc cf ctx
-and end_abstraction_borrows (config : config) (chain : borrow_or_abs_ids)
- (abs_id : AbstractionId.id) : cm_fun =
+and end_abstraction_borrows (config : config) (meta : Meta.meta)
+ (chain : borrow_or_abs_ids) (abs_id : AbstractionId.id) : cm_fun =
fun cf ctx ->
log#ldebug
(lazy
@@ -1147,7 +1188,7 @@ and end_abstraction_borrows (config : config) (chain : borrow_or_abs_ids)
method! visit_aproj env sproj =
(match sproj with
- | AProjLoans _ -> raise (Failure "Unexpected")
+ | AProjLoans _ -> craise __FILE__ __LINE__ meta "Unexpected"
| AProjBorrows (sv, proj_ty) -> raise (FoundAProjBorrows (sv, proj_ty))
| AEndedProjLoans _ | AEndedProjBorrows _ | AIgnoredProjBorrows -> ());
super#visit_aproj env sproj
@@ -1156,7 +1197,7 @@ and end_abstraction_borrows (config : config) (chain : borrow_or_abs_ids)
method! visit_borrow_content _ bc =
match bc with
| VSharedBorrow _ | VMutBorrow (_, _) -> raise (FoundBorrowContent bc)
- | VReservedMutBorrow _ -> raise (Failure "Unreachable")
+ | VReservedMutBorrow _ -> craise __FILE__ __LINE__ meta "Unreachable"
end
in
(* Lookup the abstraction *)
@@ -1172,25 +1213,25 @@ and end_abstraction_borrows (config : config) (chain : borrow_or_abs_ids)
log#ldebug
(lazy
("end_abstraction_borrows: found aborrow content: "
- ^ aborrow_content_to_string ctx bc));
+ ^ aborrow_content_to_string ~meta:(Some meta) ctx bc));
let ctx =
match bc with
| AMutBorrow (bid, av) ->
(* First, convert the avalue to a (fresh symbolic) value *)
- let sv = convert_avalue_to_given_back_value av in
+ let sv = convert_avalue_to_given_back_value meta av in
(* Replace the mut borrow to register the fact that we ended
* it and store with it the freshly generated given back value *)
let ended_borrow = ABorrow (AEndedMutBorrow (sv, av)) in
- let ctx = update_aborrow ek_all bid ended_borrow ctx in
+ let ctx = update_aborrow meta ek_all bid ended_borrow ctx in
(* Give the value back *)
let sv = mk_typed_value_from_symbolic_value sv in
- give_back_value config bid sv ctx
+ give_back_value config meta bid sv ctx
| ASharedBorrow bid ->
(* Replace the shared borrow to account for the fact it ended *)
let ended_borrow = ABorrow AEndedSharedBorrow in
- let ctx = update_aborrow ek_all bid ended_borrow ctx in
+ let ctx = update_aborrow meta ek_all bid ended_borrow ctx in
(* Give back *)
- give_back_shared config bid ctx
+ give_back_shared config meta bid ctx
| AProjSharedBorrow asb ->
(* Retrieve the borrow ids *)
let bids =
@@ -1205,21 +1246,21 @@ and end_abstraction_borrows (config : config) (chain : borrow_or_abs_ids)
* can use to identify the whole set *)
let repr_bid = List.hd bids in
(* Replace the shared borrow with Bottom *)
- let ctx = update_aborrow ek_all repr_bid ABottom ctx in
+ let ctx = update_aborrow meta ek_all repr_bid ABottom ctx in
(* Give back the shared borrows *)
let ctx =
List.fold_left
- (fun ctx bid -> give_back_shared config bid ctx)
+ (fun ctx bid -> give_back_shared config meta bid ctx)
ctx bids
in
(* Continue *)
ctx
| AEndedMutBorrow _ | AIgnoredMutBorrow _ | AEndedIgnoredMutBorrow _
| AEndedSharedBorrow ->
- raise (Failure "Unexpected")
+ craise __FILE__ __LINE__ meta "Unexpected"
in
(* Reexplore *)
- end_abstraction_borrows config chain abs_id cf ctx
+ end_abstraction_borrows config meta chain abs_id cf ctx
(* There are symbolic borrows: end them, then reexplore *)
| FoundAProjBorrows (sv, proj_ty) ->
log#ldebug
@@ -1227,55 +1268,55 @@ and end_abstraction_borrows (config : config) (chain : borrow_or_abs_ids)
("end_abstraction_borrows: found aproj borrows: "
^ aproj_to_string ctx (AProjBorrows (sv, proj_ty))));
(* Generate a fresh symbolic value *)
- let nsv = mk_fresh_symbolic_value proj_ty in
+ let nsv = mk_fresh_symbolic_value meta proj_ty in
(* Replace the proj_borrows - there should be exactly one *)
let ended_borrow = AEndedProjBorrows nsv in
- let ctx = update_aproj_borrows abs.abs_id sv ended_borrow ctx in
+ let ctx = update_aproj_borrows meta abs.abs_id sv ended_borrow ctx in
(* Give back the symbolic value *)
let ctx =
- give_back_symbolic_value config abs.regions proj_ty sv nsv ctx
+ give_back_symbolic_value config meta abs.regions proj_ty sv nsv ctx
in
(* Reexplore *)
- end_abstraction_borrows config chain abs_id cf ctx
+ end_abstraction_borrows config meta chain abs_id cf ctx
(* There are concrete (i.e., not symbolic) borrows in shared values: end them, then reexplore *)
| FoundBorrowContent bc ->
log#ldebug
(lazy
("end_abstraction_borrows: found borrow content: "
- ^ borrow_content_to_string ctx bc));
+ ^ borrow_content_to_string ~meta:(Some meta) ctx bc));
let ctx =
match bc with
| VSharedBorrow bid -> (
(* Replace the shared borrow with bottom *)
let allow_inner_loans = false in
match
- end_borrow_get_borrow (Some abs_id) allow_inner_loans bid ctx
+ end_borrow_get_borrow meta (Some abs_id) allow_inner_loans bid ctx
with
- | Error _ -> raise (Failure "Unreachable")
+ | Error _ -> craise __FILE__ __LINE__ meta "Unreachable"
| Ok (ctx, _) ->
(* Give back *)
- give_back_shared config bid ctx)
+ give_back_shared config meta bid ctx)
| VMutBorrow (bid, v) -> (
(* Replace the mut borrow with bottom *)
let allow_inner_loans = false in
match
- end_borrow_get_borrow (Some abs_id) allow_inner_loans bid ctx
+ end_borrow_get_borrow meta (Some abs_id) allow_inner_loans bid ctx
with
- | Error _ -> raise (Failure "Unreachable")
+ | Error _ -> craise __FILE__ __LINE__ meta "Unreachable"
| Ok (ctx, _) ->
(* Give the value back - note that the mut borrow was below a
* shared borrow: the value is thus unchanged *)
- give_back_value config bid v ctx)
- | VReservedMutBorrow _ -> raise (Failure "Unreachable")
+ give_back_value config meta bid v ctx)
+ | VReservedMutBorrow _ -> craise __FILE__ __LINE__ meta "Unreachable"
in
(* Reexplore *)
- end_abstraction_borrows config chain abs_id cf ctx
+ end_abstraction_borrows config meta chain abs_id cf ctx
(** Remove an abstraction from the context, as well as all its references *)
-and end_abstraction_remove_from_context (_config : config)
+and end_abstraction_remove_from_context (_config : config) (meta : Meta.meta)
(abs_id : AbstractionId.id) : cm_fun =
fun cf ctx ->
- let ctx, abs = ctx_remove_abs ctx abs_id in
+ let ctx, abs = ctx_remove_abs meta ctx abs_id in
let abs = Option.get abs in
(* Apply the continuation *)
let expr = cf ctx in
@@ -1296,12 +1337,12 @@ and end_abstraction_remove_from_context (_config : config)
intersecting proj_borrows, either in the concrete context or in an
abstraction
*)
-and end_proj_loans_symbolic (config : config) (chain : borrow_or_abs_ids)
- (abs_id : AbstractionId.id) (regions : RegionId.Set.t) (sv : symbolic_value)
- : cm_fun =
+and end_proj_loans_symbolic (config : config) (meta : Meta.meta)
+ (chain : borrow_or_abs_ids) (abs_id : AbstractionId.id)
+ (regions : RegionId.Set.t) (sv : symbolic_value) : cm_fun =
fun cf ctx ->
(* Small helpers for sanity checks *)
- let check ctx = no_aproj_over_symbolic_in_context sv ctx in
+ let check ctx = no_aproj_over_symbolic_in_context meta sv ctx in
let cf_check (cf : m_fun) : m_fun =
fun ctx ->
check ctx;
@@ -1309,13 +1350,15 @@ and end_proj_loans_symbolic (config : config) (chain : borrow_or_abs_ids)
in
(* Find the first proj_borrows which intersects the proj_loans *)
let explore_shared = true in
- match lookup_intersecting_aproj_borrows_opt explore_shared regions sv ctx with
+ match
+ lookup_intersecting_aproj_borrows_opt meta explore_shared regions sv ctx
+ with
| None ->
(* We couldn't find any in the context: it means that the symbolic value
* is in the concrete environment (or that we dropped it, in which case
* it is completely absent). We thus simply need to replace the loans
* projector with an ended projector. *)
- let ctx = update_aproj_loans_to_ended abs_id sv ctx in
+ let ctx = update_aproj_loans_to_ended meta abs_id sv ctx in
(* Sanity check *)
check ctx;
(* Continue *)
@@ -1359,15 +1402,17 @@ and end_proj_loans_symbolic (config : config) (chain : borrow_or_abs_ids)
AbstractionId.Set.empty abs_ids
in
(* End the abstractions and continue *)
- end_abstractions_aux config chain abs_ids cf ctx
+ end_abstractions_aux config meta chain abs_ids cf ctx
in
(* End the internal borrows projectors and the loans projector *)
let cf_end_internal : cm_fun =
fun cf ctx ->
(* All the proj_borrows are owned: simply erase them *)
- let ctx = remove_intersecting_aproj_borrows_shared regions sv ctx in
+ let ctx =
+ remove_intersecting_aproj_borrows_shared meta regions sv ctx
+ in
(* End the loan itself *)
- let ctx = update_aproj_loans_to_ended abs_id sv ctx in
+ let ctx = update_aproj_loans_to_ended meta abs_id sv ctx in
(* Sanity check *)
check ctx;
(* Continue *)
@@ -1399,48 +1444,51 @@ and end_proj_loans_symbolic (config : config) (chain : borrow_or_abs_ids)
*)
(* End the projector of borrows - TODO: not completely sure what to
* replace it with... Maybe we should introduce an ABottomProj? *)
- let ctx = update_aproj_borrows abs_id sv AIgnoredProjBorrows ctx in
+ let ctx = update_aproj_borrows meta abs_id sv AIgnoredProjBorrows ctx in
(* Sanity check: no other occurrence of an intersecting projector of borrows *)
- assert (
- Option.is_none
- (lookup_intersecting_aproj_borrows_opt explore_shared regions sv ctx));
+ sanity_check __FILE__ __LINE__
+ (Option.is_none
+ (lookup_intersecting_aproj_borrows_opt meta explore_shared regions
+ sv ctx))
+ meta;
(* End the projector of loans *)
- let ctx = update_aproj_loans_to_ended abs_id sv ctx in
+ let ctx = update_aproj_loans_to_ended meta abs_id sv ctx in
(* Sanity check *)
check ctx;
(* Continue *)
cf ctx)
else
(* The borrows proj comes from a different abstraction: end it. *)
- let cc = end_abstraction_aux config chain abs_id' in
+ let cc = end_abstraction_aux config meta chain abs_id' in
(* Retry ending the projector of loans *)
let cc =
- comp cc (end_proj_loans_symbolic config chain abs_id regions sv)
+ comp cc (end_proj_loans_symbolic config meta chain abs_id regions sv)
in
(* Sanity check *)
let cc = comp cc cf_check in
(* Continue *)
cc cf ctx
-let end_borrow config : BorrowId.id -> cm_fun = end_borrow_aux config [] None
+let end_borrow config (meta : Meta.meta) : BorrowId.id -> cm_fun =
+ end_borrow_aux config meta [] None
-let end_borrows config : BorrowId.Set.t -> cm_fun =
- end_borrows_aux config [] None
+let end_borrows config (meta : Meta.meta) : BorrowId.Set.t -> cm_fun =
+ end_borrows_aux config meta [] None
-let end_abstraction config = end_abstraction_aux config []
-let end_abstractions config = end_abstractions_aux config []
+let end_abstraction config meta = end_abstraction_aux config meta []
+let end_abstractions config meta = end_abstractions_aux config meta []
-let end_borrow_no_synth config id ctx =
- get_cf_ctx_no_synth (end_borrow config id) ctx
+let end_borrow_no_synth config meta id ctx =
+ get_cf_ctx_no_synth meta (end_borrow config meta id) ctx
-let end_borrows_no_synth config ids ctx =
- get_cf_ctx_no_synth (end_borrows config ids) ctx
+let end_borrows_no_synth config meta ids ctx =
+ get_cf_ctx_no_synth meta (end_borrows config meta ids) ctx
-let end_abstraction_no_synth config id ctx =
- get_cf_ctx_no_synth (end_abstraction config id) ctx
+let end_abstraction_no_synth config meta id ctx =
+ get_cf_ctx_no_synth meta (end_abstraction config meta id) ctx
-let end_abstractions_no_synth config ids ctx =
- get_cf_ctx_no_synth (end_abstractions config ids) ctx
+let end_abstractions_no_synth config meta ids ctx =
+ get_cf_ctx_no_synth meta (end_abstractions config meta ids) ctx
(** Helper function: see {!activate_reserved_mut_borrow}.
@@ -1458,14 +1506,16 @@ let end_abstractions_no_synth config ids ctx =
The loan to update mustn't be a borrowed value.
*)
-let promote_shared_loan_to_mut_loan (l : BorrowId.id)
+let promote_shared_loan_to_mut_loan (meta : Meta.meta) (l : BorrowId.id)
(cf : typed_value -> m_fun) : m_fun =
fun ctx ->
(* Debug *)
log#ldebug
(lazy
("promote_shared_loan_to_mut_loan:\n- loan: " ^ BorrowId.to_string l
- ^ "\n- context:\n" ^ eval_ctx_to_string ctx ^ "\n"));
+ ^ "\n- context:\n"
+ ^ eval_ctx_to_string ~meta:(Some meta) ctx
+ ^ "\n"));
(* Lookup the shared loan - note that we can't promote a shared loan
* in a shared value, but we can do it in a mutably borrowed value.
* This is important because we can do: [let y = &two-phase ( *x );]
@@ -1473,39 +1523,44 @@ let promote_shared_loan_to_mut_loan (l : BorrowId.id)
let ek =
{ enter_shared_loans = false; enter_mut_borrows = true; enter_abs = false }
in
- match lookup_loan ek l ctx with
+ match lookup_loan meta ek l ctx with
| _, Concrete (VMutLoan _) ->
- raise (Failure "Expected a shared loan, found a mut loan")
+ craise __FILE__ __LINE__ meta "Expected a shared loan, found a mut loan"
| _, Concrete (VSharedLoan (bids, sv)) ->
(* Check that there is only one borrow id (l) and update the loan *)
- assert (BorrowId.Set.mem l bids && BorrowId.Set.cardinal bids = 1);
+ cassert __FILE__ __LINE__
+ (BorrowId.Set.mem l bids && BorrowId.Set.cardinal bids = 1)
+ meta "There should only be one borrow id";
(* We need to check that there aren't any loans in the value:
we should have gotten rid of those already, but it is better
to do a sanity check. *)
- assert (not (loans_in_value sv));
+ sanity_check __FILE__ __LINE__ (not (loans_in_value sv)) meta;
(* Check there isn't {!Bottom} (this is actually an invariant *)
- assert (not (bottom_in_value ctx.ended_regions sv));
+ cassert __FILE__ __LINE__
+ (not (bottom_in_value ctx.ended_regions sv))
+ meta "There shouldn't be a bottom";
(* Check there aren't reserved borrows *)
- assert (not (reserved_in_value sv));
+ cassert __FILE__ __LINE__
+ (not (reserved_in_value sv))
+ meta "There shouldn't be reserved borrows";
(* Update the loan content *)
- let ctx = update_loan ek l (VMutLoan l) ctx in
+ let ctx = update_loan meta ek l (VMutLoan l) ctx in
(* Continue *)
cf sv ctx
| _, Abstract _ ->
(* I don't think it is possible to have two-phase borrows involving borrows
* returned by abstractions. I'm not sure how we could handle that anyway. *)
- raise
- (Failure
- "Can't promote a shared loan to a mutable loan if the loan is \
- inside an abstraction")
+ craise __FILE__ __LINE__ meta
+ "Can't promote a shared loan to a mutable loan if the loan is inside a \
+ region abstraction"
(** Helper function: see {!activate_reserved_mut_borrow}.
This function updates a shared borrow to a mutable borrow (and that is
all: it doesn't touch the corresponding loan).
*)
-let replace_reserved_borrow_with_mut_borrow (l : BorrowId.id) (cf : m_fun)
- (borrowed_value : typed_value) : m_fun =
+let replace_reserved_borrow_with_mut_borrow (meta : Meta.meta) (l : BorrowId.id)
+ (cf : m_fun) (borrowed_value : typed_value) : m_fun =
fun ctx ->
(* Lookup the reserved borrow - note that we don't go inside borrows/loans:
there can't be reserved borrows inside other borrows/loans
@@ -1514,32 +1569,31 @@ let replace_reserved_borrow_with_mut_borrow (l : BorrowId.id) (cf : m_fun)
{ enter_shared_loans = false; enter_mut_borrows = false; enter_abs = false }
in
let ctx =
- match lookup_borrow ek l ctx with
+ match lookup_borrow meta ek l ctx with
| Concrete (VSharedBorrow _ | VMutBorrow (_, _)) ->
- raise (Failure "Expected a reserved mutable borrow")
+ craise __FILE__ __LINE__ meta "Expected a reserved mutable borrow"
| Concrete (VReservedMutBorrow _) ->
(* Update it *)
- update_borrow ek l (VMutBorrow (l, borrowed_value)) ctx
+ update_borrow meta ek l (VMutBorrow (l, borrowed_value)) ctx
| Abstract _ ->
(* This can't happen for sure *)
- raise
- (Failure
- "Can't promote a shared borrow to a mutable borrow if the borrow \
- is inside an abstraction")
+ craise __FILE__ __LINE__ meta
+ "Can't promote a shared borrow to a mutable borrow if the borrow is \
+ inside a region abstraction"
in
(* Continue *)
cf ctx
(** Promote a reserved mut borrow to a mut borrow. *)
-let rec promote_reserved_mut_borrow (config : config) (l : BorrowId.id) : cm_fun
- =
+let rec promote_reserved_mut_borrow (config : config) (meta : Meta.meta)
+ (l : BorrowId.id) : cm_fun =
fun cf ctx ->
(* Lookup the value *)
let ek =
{ enter_shared_loans = false; enter_mut_borrows = true; enter_abs = false }
in
- match lookup_loan ek l ctx with
- | _, Concrete (VMutLoan _) -> raise (Failure "Unreachable")
+ match lookup_loan meta ek l ctx with
+ | _, Concrete (VMutLoan _) -> craise __FILE__ __LINE__ meta "Unreachable"
| _, Concrete (VSharedLoan (bids, sv)) -> (
(* If there are loans inside the value, end them. Note that there can't be
reserved borrows inside the value.
@@ -1549,11 +1603,11 @@ let rec promote_reserved_mut_borrow (config : config) (l : BorrowId.id) : cm_fun
(* End the loans *)
let cc =
match lc with
- | VSharedLoan (bids, _) -> end_borrows config bids
- | VMutLoan bid -> end_borrow config bid
+ | VSharedLoan (bids, _) -> end_borrows config meta bids
+ | VMutLoan bid -> end_borrow config meta bid
in
(* Recursive call *)
- let cc = comp cc (promote_reserved_mut_borrow config l) in
+ let cc = comp cc (promote_reserved_mut_borrow config meta l) in
(* Continue *)
cc cf ctx
| None ->
@@ -1562,37 +1616,38 @@ let rec promote_reserved_mut_borrow (config : config) (l : BorrowId.id) : cm_fun
log#ldebug
(lazy
("activate_reserved_mut_borrow: resulting value:\n"
- ^ typed_value_to_string ctx sv));
- assert (not (loans_in_value sv));
- assert (not (bottom_in_value ctx.ended_regions sv));
- assert (not (reserved_in_value sv));
+ ^ typed_value_to_string ~meta:(Some meta) ctx sv));
+ sanity_check __FILE__ __LINE__ (not (loans_in_value sv)) meta;
+ sanity_check __FILE__ __LINE__
+ (not (bottom_in_value ctx.ended_regions sv))
+ meta;
+ sanity_check __FILE__ __LINE__ (not (reserved_in_value sv)) meta;
(* End the borrows which borrow from the value, at the exception of
the borrow we want to promote *)
let bids = BorrowId.Set.remove l bids in
- let cc = end_borrows config bids in
+ let cc = end_borrows config meta bids in
(* Promote the loan - TODO: this will fail if the value contains
* any loans. In practice, it shouldn't, but we could also
* look for loans inside the value and end them before promoting
* the borrow. *)
- let cc = comp cc (promote_shared_loan_to_mut_loan l) in
+ let cc = comp cc (promote_shared_loan_to_mut_loan meta l) in
(* Promote the borrow - the value should have been checked by
{!promote_shared_loan_to_mut_loan}
*)
let cc =
comp cc (fun cf borrowed_value ->
- replace_reserved_borrow_with_mut_borrow l cf borrowed_value)
+ replace_reserved_borrow_with_mut_borrow meta l cf borrowed_value)
in
(* Continue *)
cc cf ctx)
| _, Abstract _ ->
(* I don't think it is possible to have two-phase borrows involving borrows
* returned by abstractions. I'm not sure how we could handle that anyway. *)
- raise
- (Failure
- "Can't activate a reserved mutable borrow referencing a loan inside\n\
- \ an abstraction")
+ craise __FILE__ __LINE__ meta
+ "Can't activate a reserved mutable borrow referencing a loan inside\n\
+ \ a region abstraction"
-let destructure_abs (abs_kind : abs_kind) (can_end : bool)
+let destructure_abs (meta : Meta.meta) (abs_kind : abs_kind) (can_end : bool)
(destructure_shared_values : bool) (ctx : eval_ctx) (abs0 : abs) : abs =
(* Accumulator to store the destructured values *)
let avalues = ref [] in
@@ -1605,7 +1660,7 @@ let destructure_abs (abs_kind : abs_kind) (can_end : bool)
ignore the children altogether. Instead, we explore them and make sure
we don't register values while doing so.
*)
- let push_fail _ = raise (Failure "Unreachable") in
+ let push_fail _ = craise __FILE__ __LINE__ meta "Unreachable" in
(* Function to explore an avalue and destructure it *)
let rec list_avalues (allow_borrows : bool) (push : typed_avalue -> unit)
(av : typed_avalue) : unit =
@@ -1620,13 +1675,15 @@ let destructure_abs (abs_kind : abs_kind) (can_end : bool)
match lc with
| ASharedLoan (bids, sv, child_av) ->
(* We don't support nested borrows for now *)
- assert (not (value_has_borrows ctx sv.value));
+ cassert __FILE__ __LINE__
+ (not (value_has_borrows ctx sv.value))
+ meta "Nested borrows are not supported yet";
(* Destructure the shared value *)
let avl, sv =
if destructure_shared_values then list_values sv else ([], sv)
in
(* Push a value *)
- let ignored = mk_aignored child_av.ty in
+ let ignored = mk_aignored meta child_av.ty in
let value = ALoan (ASharedLoan (bids, sv, ignored)) in
push { value; ty };
(* Explore the child *)
@@ -1642,13 +1699,15 @@ let destructure_abs (abs_kind : abs_kind) (can_end : bool)
(* Explore the child *)
list_avalues false push_fail child_av;
(* Explore the whole loan *)
- let ignored = mk_aignored child_av.ty in
+ let ignored = mk_aignored meta child_av.ty in
let value = ALoan (AMutLoan (bid, ignored)) in
push { value; ty }
| AIgnoredMutLoan (opt_bid, child_av) ->
(* We don't support nested borrows for now *)
- assert (not (ty_has_borrows ctx.type_ctx.type_infos child_av.ty));
- assert (opt_bid = None);
+ cassert __FILE__ __LINE__
+ (not (ty_has_borrows ctx.type_ctx.type_infos child_av.ty))
+ meta "Nested borrows are not supported yet";
+ sanity_check __FILE__ __LINE__ (opt_bid = None) meta;
(* Simply explore the child *)
list_avalues false push_fail child_av
| AEndedMutLoan
@@ -1658,19 +1717,21 @@ let destructure_abs (abs_kind : abs_kind) (can_end : bool)
{ child = child_av; given_back = _; given_back_meta = _ }
| AIgnoredSharedLoan child_av ->
(* We don't support nested borrows for now *)
- assert (not (ty_has_borrows ctx.type_ctx.type_infos child_av.ty));
+ cassert __FILE__ __LINE__
+ (not (ty_has_borrows ctx.type_ctx.type_infos child_av.ty))
+ meta "Nested borrows are not supported yet";
(* Simply explore the child *)
list_avalues false push_fail child_av)
| ABorrow bc -> (
(* Sanity check - rem.: may be redundant with [push_fail] *)
- assert allow_borrows;
+ sanity_check __FILE__ __LINE__ allow_borrows meta;
(* Explore the borrow content *)
match bc with
| AMutBorrow (bid, child_av) ->
(* Explore the child *)
list_avalues false push_fail child_av;
(* Explore the borrow *)
- let ignored = mk_aignored child_av.ty in
+ let ignored = mk_aignored meta child_av.ty in
let value = ABorrow (AMutBorrow (bid, ignored)) in
push { value; ty }
| ASharedBorrow _ ->
@@ -1678,19 +1739,24 @@ let destructure_abs (abs_kind : abs_kind) (can_end : bool)
push av
| AIgnoredMutBorrow (opt_bid, child_av) ->
(* We don't support nested borrows for now *)
- assert (not (ty_has_borrows ctx.type_ctx.type_infos child_av.ty));
- assert (opt_bid = None);
+ cassert __FILE__ __LINE__
+ (not (ty_has_borrows ctx.type_ctx.type_infos child_av.ty))
+ meta "Nested borrows are not supported yet";
+ sanity_check __FILE__ __LINE__ (opt_bid = None) meta;
(* Just explore the child *)
list_avalues false push_fail child_av
| AEndedIgnoredMutBorrow
{ child = child_av; given_back = _; given_back_meta = _ } ->
(* We don't support nested borrows for now *)
- assert (not (ty_has_borrows ctx.type_ctx.type_infos child_av.ty));
+ cassert __FILE__ __LINE__
+ (not (ty_has_borrows ctx.type_ctx.type_infos child_av.ty))
+ meta "Nested borrows are not supported yet";
(* Just explore the child *)
list_avalues false push_fail child_av
| AProjSharedBorrow asb ->
(* We don't support nested borrows *)
- assert (asb = []);
+ cassert __FILE__ __LINE__ (asb = []) meta
+ "Nested borrows are not supported yet";
(* Nothing specific to do *)
()
| AEndedMutBorrow _ | AEndedSharedBorrow ->
@@ -1698,11 +1764,13 @@ let destructure_abs (abs_kind : abs_kind) (can_end : bool)
be in the context anymore (if we end *one* borrow in an abstraction,
we have to end them all and remove the abstraction from the context)
*)
- raise (Failure "Unreachable"))
+ craise __FILE__ __LINE__ meta "Unreachable")
| ASymbolic _ ->
(* For now, we fore all symbolic values containing borrows to be eagerly
expanded *)
- assert (not (ty_has_borrows ctx.type_ctx.type_infos ty))
+ sanity_check __FILE__ __LINE__
+ (not (ty_has_borrows ctx.type_ctx.type_infos ty))
+ meta
and list_values (v : typed_value) : typed_avalue list * typed_value =
let ty = v.ty in
match v.value with
@@ -1714,19 +1782,22 @@ let destructure_abs (abs_kind : abs_kind) (can_end : bool)
let avl = List.concat avll in
let adt = { adt with field_values } in
(avl, { v with value = VAdt adt })
- | VBottom -> raise (Failure "Unreachable")
+ | VBottom -> craise __FILE__ __LINE__ meta "Unreachable"
| VBorrow _ ->
(* We don't support nested borrows for now *)
- raise (Failure "Unreachable")
+ craise __FILE__ __LINE__ meta "Unreachable"
| VLoan lc -> (
match lc with
| VSharedLoan (bids, sv) ->
let avl, sv = list_values sv in
if destructure_shared_values then (
(* Rem.: the shared value can't contain loans nor borrows *)
- assert (ty_no_regions ty);
+ cassert __FILE__ __LINE__ (ty_no_regions ty) meta
+ "Nested borrows are not supported yet";
let av : typed_avalue =
- assert (not (value_has_loans_or_borrows ctx sv.value));
+ sanity_check __FILE__ __LINE__
+ (not (value_has_loans_or_borrows ctx sv.value))
+ meta;
(* We introduce fresh ids for the symbolic values *)
let mk_value_with_fresh_sids (v : typed_value) : typed_value =
let visitor =
@@ -1741,17 +1812,21 @@ let destructure_abs (abs_kind : abs_kind) (can_end : bool)
in
let sv = mk_value_with_fresh_sids sv in
(* Create the new avalue *)
- let value = ALoan (ASharedLoan (bids, sv, mk_aignored ty)) in
+ let value =
+ ALoan (ASharedLoan (bids, sv, mk_aignored meta ty))
+ in
{ value; ty }
in
let avl = List.append [ av ] avl in
(avl, sv))
else (avl, { v with value = VLoan (VSharedLoan (bids, sv)) })
- | VMutLoan _ -> raise (Failure "Unreachable"))
+ | VMutLoan _ -> craise __FILE__ __LINE__ meta "Unreachable")
| VSymbolic _ ->
(* For now, we fore all symbolic values containing borrows to be eagerly
expanded *)
- assert (not (ty_has_borrows ctx.type_ctx.type_infos ty));
+ sanity_check __FILE__ __LINE__
+ (not (ty_has_borrows ctx.type_ctx.type_infos ty))
+ meta;
([], v)
in
@@ -1761,16 +1836,16 @@ let destructure_abs (abs_kind : abs_kind) (can_end : bool)
(* Update *)
{ abs0 with avalues; kind = abs_kind; can_end }
-let abs_is_destructured (destructure_shared_values : bool) (ctx : eval_ctx)
- (abs : abs) : bool =
+let abs_is_destructured (meta : Meta.meta) (destructure_shared_values : bool)
+ (ctx : eval_ctx) (abs : abs) : bool =
let abs' =
- destructure_abs abs.kind abs.can_end destructure_shared_values ctx abs
+ destructure_abs meta abs.kind abs.can_end destructure_shared_values ctx abs
in
abs = abs'
-let convert_value_to_abstractions (abs_kind : abs_kind) (can_end : bool)
- (destructure_shared_values : bool) (ctx : eval_ctx) (v : typed_value) :
- abs list =
+let convert_value_to_abstractions (meta : Meta.meta) (abs_kind : abs_kind)
+ (can_end : bool) (destructure_shared_values : bool) (ctx : eval_ctx)
+ (v : typed_value) : abs list =
(* Convert the value to a list of avalues *)
let absl = ref [] in
let push_abs (r_id : RegionId.id) (avalues : typed_avalue list) : unit =
@@ -1807,7 +1882,7 @@ let convert_value_to_abstractions (abs_kind : abs_kind) (can_end : bool)
log#ldebug
(lazy
("convert_value_to_abstractions: to_avalues:\n- value: "
- ^ typed_value_to_string ctx v));
+ ^ typed_value_to_string ~meta:(Some meta) ctx v));
let ty = v.ty in
match v.value with
@@ -1851,23 +1926,27 @@ let convert_value_to_abstractions (abs_kind : abs_kind) (can_end : bool)
(avl, { v with value = VAdt adt })
| VBorrow bc -> (
let _, ref_ty, kind = ty_as_ref ty in
- assert (ty_no_regions ref_ty);
+ cassert __FILE__ __LINE__ (ty_no_regions ref_ty) meta
+ "Nested borrows are not supported yet";
(* Sanity check *)
- assert allow_borrows;
+ sanity_check __FILE__ __LINE__ allow_borrows meta;
(* Convert the borrow content *)
match bc with
| VSharedBorrow bid ->
- assert (ty_no_regions ref_ty);
+ cassert __FILE__ __LINE__ (ty_no_regions ref_ty) meta
+ "Nested borrows are not supported yet";
let ty = TRef (RFVar r_id, ref_ty, kind) in
let value = ABorrow (ASharedBorrow bid) in
([ { value; ty } ], v)
| VMutBorrow (bid, bv) ->
let r_id = if group then r_id else fresh_region_id () in
(* We don't support nested borrows for now *)
- assert (not (value_has_borrows ctx bv.value));
+ cassert __FILE__ __LINE__
+ (not (value_has_borrows ctx bv.value))
+ meta "Nested borrows are not supported yet";
(* Create an avalue to push - note that we use [AIgnore] for the inner avalue *)
let ty = TRef (RFVar r_id, ref_ty, kind) in
- let ignored = mk_aignored ref_ty in
+ let ignored = mk_aignored meta ref_ty in
let av = ABorrow (AMutBorrow (bid, ignored)) in
let av = { value = av; ty } in
(* Continue exploring, looking for loans (and forbidding borrows,
@@ -1877,18 +1956,21 @@ let convert_value_to_abstractions (abs_kind : abs_kind) (can_end : bool)
(av :: avl, value)
| VReservedMutBorrow _ ->
(* This borrow should have been activated *)
- raise (Failure "Unexpected"))
+ craise __FILE__ __LINE__ meta "Unexpected")
| VLoan lc -> (
match lc with
| VSharedLoan (bids, sv) ->
let r_id = if group then r_id else fresh_region_id () in
(* We don't support nested borrows for now *)
- assert (not (value_has_borrows ctx sv.value));
+ cassert __FILE__ __LINE__
+ (not (value_has_borrows ctx sv.value))
+ meta "Nested borrows are not supported yet";
(* Push the avalue - note that we use [AIgnore] for the inner avalue *)
(* For avalues, a loan has the borrow type *)
- assert (ty_no_regions ty);
+ cassert __FILE__ __LINE__ (ty_no_regions ty) meta
+ "Nested borrows are not supported yet";
let ty = mk_ref_ty (RFVar r_id) ty RShared in
- let ignored = mk_aignored ty in
+ let ignored = mk_aignored meta ty in
(* Rem.: the shared value might contain loans *)
let avl, sv = to_avalues false true true r_id sv in
let av = ALoan (ASharedLoan (bids, sv, ignored)) in
@@ -1904,16 +1986,19 @@ let convert_value_to_abstractions (abs_kind : abs_kind) (can_end : bool)
| VMutLoan bid ->
(* Push the avalue - note that we use [AIgnore] for the inner avalue *)
(* For avalues, a loan has the borrow type *)
- assert (ty_no_regions ty);
+ cassert __FILE__ __LINE__ (ty_no_regions ty) meta
+ "Nested borrows are not supported yet";
let ty = mk_ref_ty (RFVar r_id) ty RMut in
- let ignored = mk_aignored ty in
+ let ignored = mk_aignored meta ty in
let av = ALoan (AMutLoan (bid, ignored)) in
let av = { value = av; ty } in
([ av ], v))
| VSymbolic _ ->
(* For now, we force all the symbolic values containing borrows to
be eagerly expanded, and we don't support nested borrows *)
- assert (not (value_has_borrows ctx v.value));
+ cassert __FILE__ __LINE__
+ (not (value_has_borrows ctx v.value))
+ meta "Nested borrows are not supported yet";
(* Return nothing *)
([], v)
in
@@ -1954,8 +2039,8 @@ type merge_abstraction_info = {
- all the borrows are destructured (for instance, shared loans can't
contain shared loans).
*)
-let compute_merge_abstraction_info (ctx : eval_ctx) (abs : abs) :
- merge_abstraction_info =
+let compute_merge_abstraction_info (meta : Meta.meta) (ctx : eval_ctx)
+ (abs : abs) : merge_abstraction_info =
let loans : loan_id_set ref = ref BorrowId.Set.empty in
let borrows : borrow_id_set ref = ref BorrowId.Set.empty in
let borrows_loans : borrow_or_loan_id list ref = ref [] in
@@ -1967,26 +2052,32 @@ let compute_merge_abstraction_info (ctx : eval_ctx) (abs : abs) :
in
let push_loans ids (lc : g_loan_content_with_ty) : unit =
- assert (BorrowId.Set.disjoint !loans ids);
+ sanity_check __FILE__ __LINE__ (BorrowId.Set.disjoint !loans ids) meta;
loans := BorrowId.Set.union !loans ids;
BorrowId.Set.iter
(fun id ->
- assert (not (BorrowId.Map.mem id !loan_to_content));
+ sanity_check __FILE__ __LINE__
+ (not (BorrowId.Map.mem id !loan_to_content))
+ meta;
loan_to_content := BorrowId.Map.add id lc !loan_to_content;
borrows_loans := LoanId id :: !borrows_loans)
ids
in
let push_loan id (lc : g_loan_content_with_ty) : unit =
- assert (not (BorrowId.Set.mem id !loans));
+ sanity_check __FILE__ __LINE__ (not (BorrowId.Set.mem id !loans)) meta;
loans := BorrowId.Set.add id !loans;
- assert (not (BorrowId.Map.mem id !loan_to_content));
+ sanity_check __FILE__ __LINE__
+ (not (BorrowId.Map.mem id !loan_to_content))
+ meta;
loan_to_content := BorrowId.Map.add id lc !loan_to_content;
borrows_loans := LoanId id :: !borrows_loans
in
let push_borrow id (bc : g_borrow_content_with_ty) : unit =
- assert (not (BorrowId.Set.mem id !borrows));
+ sanity_check __FILE__ __LINE__ (not (BorrowId.Set.mem id !borrows)) meta;
borrows := BorrowId.Set.add id !borrows;
- assert (not (BorrowId.Map.mem id !borrow_to_content));
+ sanity_check __FILE__ __LINE__
+ (not (BorrowId.Map.mem id !borrow_to_content))
+ meta;
borrow_to_content := BorrowId.Map.add id bc !borrow_to_content;
borrows_loans := BorrowId id :: !borrows_loans
in
@@ -2009,23 +2100,23 @@ let compute_merge_abstraction_info (ctx : eval_ctx) (abs : abs) :
let ty =
match Option.get env with
| Concrete ty -> ty
- | Abstract _ -> raise (Failure "Unreachable")
+ | Abstract _ -> craise __FILE__ __LINE__ meta "Unreachable"
in
(match lc with
| VSharedLoan (bids, _) -> push_loans bids (Concrete (ty, lc))
- | VMutLoan _ -> raise (Failure "Unreachable"));
+ | VMutLoan _ -> craise __FILE__ __LINE__ meta "Unreachable");
(* Continue *)
super#visit_loan_content env lc
method! visit_borrow_content _ _ =
(* Can happen if we explore shared values which contain borrows -
i.e., if we have nested borrows (we forbid this for now) *)
- raise (Failure "Unreachable")
+ craise __FILE__ __LINE__ meta "Unreachable"
method! visit_aloan_content env lc =
let ty =
match Option.get env with
- | Concrete _ -> raise (Failure "Unreachable")
+ | Concrete _ -> craise __FILE__ __LINE__ meta "Unreachable"
| Abstract ty -> ty
in
(* Register the loans *)
@@ -2035,14 +2126,14 @@ let compute_merge_abstraction_info (ctx : eval_ctx) (abs : abs) :
| AEndedMutLoan _ | AEndedSharedLoan _ | AIgnoredMutLoan _
| AEndedIgnoredMutLoan _ | AIgnoredSharedLoan _ ->
(* The abstraction has been destructured, so those shouldn't appear *)
- raise (Failure "Unreachable"));
+ craise __FILE__ __LINE__ meta "Unreachable");
(* Continue *)
super#visit_aloan_content env lc
method! visit_aborrow_content env bc =
let ty =
match Option.get env with
- | Concrete _ -> raise (Failure "Unreachable")
+ | Concrete _ -> craise __FILE__ __LINE__ meta "Unreachable"
| Abstract ty -> ty
in
(* Explore the borrow content *)
@@ -2056,18 +2147,20 @@ let compute_merge_abstraction_info (ctx : eval_ctx) (abs : abs) :
| AsbProjReborrows _ ->
(* Can only happen if the symbolic value (potentially) contains
borrows - i.e., we have nested borrows *)
- raise (Failure "Unreachable")
+ craise __FILE__ __LINE__ meta "Unreachable"
in
List.iter register asb
| AIgnoredMutBorrow _ | AEndedIgnoredMutBorrow _ | AEndedMutBorrow _
| AEndedSharedBorrow ->
(* The abstraction has been destructured, so those shouldn't appear *)
- raise (Failure "Unreachable"));
+ craise __FILE__ __LINE__ meta "Unreachable");
super#visit_aborrow_content env bc
method! visit_symbolic_value _ sv =
(* Sanity check: no borrows *)
- assert (not (symbolic_value_has_borrows ctx sv))
+ sanity_check __FILE__ __LINE__
+ (not (symbolic_value_has_borrows ctx sv))
+ meta
end
in
@@ -2134,19 +2227,25 @@ type merge_duplicates_funcs = {
Merge two abstractions into one, without updating the context.
*)
-let merge_into_abstraction_aux (abs_kind : abs_kind) (can_end : bool)
- (merge_funs : merge_duplicates_funcs option) (ctx : eval_ctx) (abs0 : abs)
- (abs1 : abs) : abs =
+let merge_into_abstraction_aux (meta : Meta.meta) (abs_kind : abs_kind)
+ (can_end : bool) (merge_funs : merge_duplicates_funcs option)
+ (ctx : eval_ctx) (abs0 : abs) (abs1 : abs) : abs =
log#ldebug
(lazy
- ("merge_into_abstraction_aux:\n- abs0:\n" ^ abs_to_string ctx abs0
- ^ "\n\n- abs1:\n" ^ abs_to_string ctx abs1));
+ ("merge_into_abstraction_aux:\n- abs0:\n"
+ ^ abs_to_string meta ctx abs0
+ ^ "\n\n- abs1:\n"
+ ^ abs_to_string meta ctx abs1));
(* Check that the abstractions are destructured *)
if !Config.sanity_checks then (
let destructure_shared_values = true in
- assert (abs_is_destructured destructure_shared_values ctx abs0);
- assert (abs_is_destructured destructure_shared_values ctx abs1));
+ sanity_check __FILE__ __LINE__
+ (abs_is_destructured meta destructure_shared_values ctx abs0)
+ meta;
+ sanity_check __FILE__ __LINE__
+ (abs_is_destructured meta destructure_shared_values ctx abs1)
+ meta);
(* Compute the relevant information *)
let {
@@ -2156,7 +2255,7 @@ let merge_into_abstraction_aux (abs_kind : abs_kind) (can_end : bool)
loan_to_content = loan_to_content0;
borrow_to_content = borrow_to_content0;
} =
- compute_merge_abstraction_info ctx abs0
+ compute_merge_abstraction_info meta ctx abs0
in
let {
@@ -2166,14 +2265,16 @@ let merge_into_abstraction_aux (abs_kind : abs_kind) (can_end : bool)
loan_to_content = loan_to_content1;
borrow_to_content = borrow_to_content1;
} =
- compute_merge_abstraction_info ctx abs1
+ compute_merge_abstraction_info meta ctx abs1
in
(* Sanity check: there is no loan/borrows which appears in both abstractions,
unless we allow to merge duplicates *)
if merge_funs = None then (
- assert (BorrowId.Set.disjoint borrows0 borrows1);
- assert (BorrowId.Set.disjoint loans0 loans1));
+ sanity_check __FILE__ __LINE__
+ (BorrowId.Set.disjoint borrows0 borrows1)
+ meta;
+ sanity_check __FILE__ __LINE__ (BorrowId.Set.disjoint loans0 loans1) meta);
(* Merge.
There are several cases:
@@ -2200,7 +2301,7 @@ let merge_into_abstraction_aux (abs_kind : abs_kind) (can_end : bool)
log#ldebug
(lazy
("merge_into_abstraction_aux: push_avalue: "
- ^ typed_avalue_to_string ctx av));
+ ^ typed_avalue_to_string ~meta:(Some meta) ctx av));
avalues := av :: !avalues
in
let push_opt_avalue av =
@@ -2214,7 +2315,7 @@ let merge_into_abstraction_aux (abs_kind : abs_kind) (can_end : bool)
in
let filter_bids (bids : BorrowId.Set.t) : BorrowId.Set.t =
let bids = BorrowId.Set.diff bids intersect in
- assert (not (BorrowId.Set.is_empty bids));
+ sanity_check __FILE__ __LINE__ (not (BorrowId.Set.is_empty bids)) meta;
bids
in
let filter_bid (bid : BorrowId.id) : BorrowId.id option =
@@ -2242,11 +2343,11 @@ let merge_into_abstraction_aux (abs_kind : abs_kind) (can_end : bool)
(Option.get merge_funs).merge_ashared_borrows id ty0 ty1
| AProjSharedBorrow _, AProjSharedBorrow _ ->
(* Unreachable because requires nested borrows *)
- raise (Failure "Unreachable")
+ craise __FILE__ __LINE__ meta "Unreachable"
| _ ->
(* Unreachable because those cases are ignored (ended/ignored borrows)
or inconsistent *)
- raise (Failure "Unreachable")
+ craise __FILE__ __LINE__ meta "Unreachable"
in
let merge_g_borrow_contents (bc0 : g_borrow_content_with_ty)
@@ -2254,12 +2355,12 @@ let merge_into_abstraction_aux (abs_kind : abs_kind) (can_end : bool)
match (bc0, bc1) with
| Concrete _, Concrete _ ->
(* This can happen only in case of nested borrows *)
- raise (Failure "Unreachable")
+ craise __FILE__ __LINE__ meta "Unreachable"
| Abstract (ty0, bc0), Abstract (ty1, bc1) ->
merge_aborrow_contents ty0 bc0 ty1 bc1
| Concrete _, Abstract _ | Abstract _, Concrete _ ->
(* TODO: is it really unreachable? *)
- raise (Failure "Unreachable")
+ craise __FILE__ __LINE__ meta "Unreachable"
in
let merge_aloan_contents (ty0 : rty) (lc0 : aloan_content) (ty1 : rty)
@@ -2277,7 +2378,7 @@ let merge_into_abstraction_aux (abs_kind : abs_kind) (can_end : bool)
(* Check that the sets of ids are the same - if it is not the case, it
means we actually need to merge more than 2 avalues: we ignore this
case for now *)
- assert (BorrowId.Set.equal ids0 ids1);
+ sanity_check __FILE__ __LINE__ (BorrowId.Set.equal ids0 ids1) meta;
let ids = ids0 in
if BorrowId.Set.is_empty ids then (
(* If the set of ids is empty, we can eliminate this shared loan.
@@ -2289,10 +2390,14 @@ let merge_into_abstraction_aux (abs_kind : abs_kind) (can_end : bool)
to preserve (in practice it works because we destructure the
shared values in the abstractions, and forbid nested borrows).
*)
- assert (not (value_has_loans_or_borrows ctx sv0.value));
- assert (not (value_has_loans_or_borrows ctx sv0.value));
- assert (is_aignored child0.value);
- assert (is_aignored child1.value);
+ sanity_check __FILE__ __LINE__
+ (not (value_has_loans_or_borrows ctx sv0.value))
+ meta;
+ sanity_check __FILE__ __LINE__
+ (not (value_has_loans_or_borrows ctx sv0.value))
+ meta;
+ sanity_check __FILE__ __LINE__ (is_aignored child0.value) meta;
+ sanity_check __FILE__ __LINE__ (is_aignored child1.value) meta;
None)
else (
(* Register the loan ids *)
@@ -2304,7 +2409,7 @@ let merge_into_abstraction_aux (abs_kind : abs_kind) (can_end : bool)
| _ ->
(* Unreachable because those cases are ignored (ended/ignored borrows)
or inconsistent *)
- raise (Failure "Unreachable")
+ craise __FILE__ __LINE__ meta "Unreachable"
in
(* Note that because we may filter ids from a set of id, this function has
@@ -2315,12 +2420,12 @@ let merge_into_abstraction_aux (abs_kind : abs_kind) (can_end : bool)
match (lc0, lc1) with
| Concrete _, Concrete _ ->
(* This can not happen: the values should have been destructured *)
- raise (Failure "Unreachable")
+ craise __FILE__ __LINE__ meta "Unreachable"
| Abstract (ty0, lc0), Abstract (ty1, lc1) ->
merge_aloan_contents ty0 lc0 ty1 lc1
| Concrete _, Abstract _ | Abstract _, Concrete _ ->
(* TODO: is it really unreachable? *)
- raise (Failure "Unreachable")
+ craise __FILE__ __LINE__ meta "Unreachable"
in
(* Note that we first explore the borrows/loans of [abs1], because we
@@ -2361,12 +2466,12 @@ let merge_into_abstraction_aux (abs_kind : abs_kind) (can_end : bool)
a concrete borrow can only happen inside a shared
loan
*)
- raise (Failure "Unreachable")
+ craise __FILE__ __LINE__ meta "Unreachable"
| Abstract (ty, bc) -> { value = ABorrow bc; ty })
| Some bc0, Some bc1 ->
- assert (merge_funs <> None);
+ sanity_check __FILE__ __LINE__ (merge_funs <> None) meta;
merge_g_borrow_contents bc0 bc1
- | None, None -> raise (Failure "Unreachable")
+ | None, None -> craise __FILE__ __LINE__ meta "Unreachable"
in
push_avalue av)
| LoanId bid ->
@@ -2399,15 +2504,19 @@ let merge_into_abstraction_aux (abs_kind : abs_kind) (can_end : bool)
| Concrete _ ->
(* This shouldn't happen because the avalues should
have been destructured. *)
- raise (Failure "Unreachable")
+ craise __FILE__ __LINE__ meta "Unreachable"
| Abstract (ty, lc) -> (
match lc with
| ASharedLoan (bids, sv, child) ->
let bids = filter_bids bids in
- assert (not (BorrowId.Set.is_empty bids));
- assert (is_aignored child.value);
- assert (
- not (value_has_loans_or_borrows ctx sv.value));
+ sanity_check __FILE__ __LINE__
+ (not (BorrowId.Set.is_empty bids))
+ meta;
+ sanity_check __FILE__ __LINE__
+ (is_aignored child.value) meta;
+ sanity_check __FILE__ __LINE__
+ (not (value_has_loans_or_borrows ctx sv.value))
+ meta;
let lc = ASharedLoan (bids, sv, child) in
set_loans_as_merged bids;
Some { value = ALoan lc; ty }
@@ -2418,11 +2527,11 @@ let merge_into_abstraction_aux (abs_kind : abs_kind) (can_end : bool)
| AIgnoredMutLoan _ | AEndedIgnoredMutLoan _
| AIgnoredSharedLoan _ ->
(* The abstraction has been destructured, so those shouldn't appear *)
- raise (Failure "Unreachable")))
+ craise __FILE__ __LINE__ meta "Unreachable"))
| Some lc0, Some lc1 ->
- assert (merge_funs <> None);
+ sanity_check __FILE__ __LINE__ (merge_funs <> None) meta;
merge_g_loan_contents lc0 lc1
- | None, None -> raise (Failure "Unreachable")
+ | None, None -> craise __FILE__ __LINE__ meta "Unreachable"
in
push_opt_avalue av))
borrows_loans;
@@ -2440,7 +2549,7 @@ let merge_into_abstraction_aux (abs_kind : abs_kind) (can_end : bool)
match av.value with
| ABorrow _ -> true
| ALoan _ -> false
- | _ -> raise (Failure "Unexpected")
+ | _ -> craise __FILE__ __LINE__ meta "Unexpected"
in
let aborrows, aloans = List.partition is_borrow avalues in
List.append aborrows aloans
@@ -2475,7 +2584,7 @@ let merge_into_abstraction_aux (abs_kind : abs_kind) (can_end : bool)
in
(* Sanity check *)
- if !Config.sanity_checks then assert (abs_is_destructured true ctx abs);
+ sanity_check __FILE__ __LINE__ (abs_is_destructured meta true ctx abs) meta;
(* Return *)
abs
@@ -2486,9 +2595,9 @@ let ctx_merge_regions (ctx : eval_ctx) (rid : RegionId.id)
let env = Substitute.env_subst_rids rsubst ctx.env in
{ ctx with env }
-let merge_into_abstraction (abs_kind : abs_kind) (can_end : bool)
- (merge_funs : merge_duplicates_funcs option) (ctx : eval_ctx)
- (abs_id0 : AbstractionId.id) (abs_id1 : AbstractionId.id) :
+let merge_into_abstraction (meta : Meta.meta) (abs_kind : abs_kind)
+ (can_end : bool) (merge_funs : merge_duplicates_funcs option)
+ (ctx : eval_ctx) (abs_id0 : AbstractionId.id) (abs_id1 : AbstractionId.id) :
eval_ctx * AbstractionId.id =
(* Lookup the abstractions *)
let abs0 = ctx_lookup_abs ctx abs_id0 in
@@ -2496,13 +2605,13 @@ let merge_into_abstraction (abs_kind : abs_kind) (can_end : bool)
(* Merge them *)
let nabs =
- merge_into_abstraction_aux abs_kind can_end merge_funs ctx abs0 abs1
+ merge_into_abstraction_aux meta abs_kind can_end merge_funs ctx abs0 abs1
in
(* Update the environment: replace the abstraction 1 with the result of the merge,
remove the abstraction 0 *)
- let ctx = fst (ctx_subst_abs ctx abs_id1 nabs) in
- let ctx = fst (ctx_remove_abs ctx abs_id0) in
+ let ctx = fst (ctx_subst_abs meta ctx abs_id1 nabs) in
+ let ctx = fst (ctx_remove_abs meta ctx abs_id0) in
(* Merge all the regions from the abstraction into one (the first - i.e., the
one with the smallest id). Note that we need to do this in the whole
diff --git a/compiler/InterpreterBorrows.mli b/compiler/InterpreterBorrows.mli
index e47ba82d..30b75790 100644
--- a/compiler/InterpreterBorrows.mli
+++ b/compiler/InterpreterBorrows.mli
@@ -8,37 +8,40 @@ open Cps
applies this change to an environment [ctx] by inserting a new borrow id in
the set of borrows tracked by a shared value, referenced by the
[original_bid] argument. *)
-val reborrow_shared : BorrowId.id -> BorrowId.id -> eval_ctx -> eval_ctx
+val reborrow_shared :
+ Meta.meta -> BorrowId.id -> BorrowId.id -> eval_ctx -> eval_ctx
(** End a borrow identified by its id, while preserving the invariants.
If the borrow is inside another borrow/an abstraction or contains loans,
[end_borrow] will end those borrows/abstractions/loans first.
*)
-val end_borrow : config -> BorrowId.id -> cm_fun
+val end_borrow : config -> Meta.meta -> BorrowId.id -> cm_fun
(** End a set of borrows identified by their ids, while preserving the invariants. *)
-val end_borrows : config -> BorrowId.Set.t -> cm_fun
+val end_borrows : config -> Meta.meta -> BorrowId.Set.t -> cm_fun
(** End an abstraction while preserving the invariants. *)
-val end_abstraction : config -> AbstractionId.id -> cm_fun
+val end_abstraction : config -> Meta.meta -> AbstractionId.id -> cm_fun
(** End a set of abstractions while preserving the invariants. *)
-val end_abstractions : config -> AbstractionId.Set.t -> cm_fun
+val end_abstractions : config -> Meta.meta -> AbstractionId.Set.t -> cm_fun
(** End a borrow and return the resulting environment, ignoring synthesis *)
-val end_borrow_no_synth : config -> BorrowId.id -> eval_ctx -> eval_ctx
+val end_borrow_no_synth :
+ config -> Meta.meta -> BorrowId.id -> eval_ctx -> eval_ctx
(** End a set of borrows and return the resulting environment, ignoring synthesis *)
-val end_borrows_no_synth : config -> BorrowId.Set.t -> eval_ctx -> eval_ctx
+val end_borrows_no_synth :
+ config -> Meta.meta -> BorrowId.Set.t -> eval_ctx -> eval_ctx
(** End an abstraction and return the resulting environment, ignoring synthesis *)
val end_abstraction_no_synth :
- config -> AbstractionId.id -> eval_ctx -> eval_ctx
+ config -> Meta.meta -> AbstractionId.id -> eval_ctx -> eval_ctx
(** End a set of abstractions and return the resulting environment, ignoring synthesis *)
val end_abstractions_no_synth :
- config -> AbstractionId.Set.t -> eval_ctx -> eval_ctx
+ config -> Meta.meta -> AbstractionId.Set.t -> eval_ctx -> eval_ctx
(** Promote a reserved mut borrow to a mut borrow, while preserving the invariants.
@@ -49,7 +52,7 @@ val end_abstractions_no_synth :
the corresponding shared loan with a mutable loan (after having ended the
other shared borrows which point to this loan).
*)
-val promote_reserved_mut_borrow : config -> BorrowId.id -> cm_fun
+val promote_reserved_mut_borrow : config -> Meta.meta -> BorrowId.id -> cm_fun
(** Transform an abstraction to an abstraction where the values are not
structured.
@@ -91,7 +94,8 @@ val promote_reserved_mut_borrow : config -> BorrowId.id -> cm_fun
- [ctx]
- [abs]
*)
-val destructure_abs : abs_kind -> bool -> bool -> eval_ctx -> abs -> abs
+val destructure_abs :
+ Meta.meta -> abs_kind -> bool -> bool -> eval_ctx -> abs -> abs
(** Return [true] if the values in an abstraction are destructured.
@@ -99,7 +103,7 @@ val destructure_abs : abs_kind -> bool -> bool -> eval_ctx -> abs -> abs
The input boolean is [destructure_shared_value]. See {!destructure_abs}.
*)
-val abs_is_destructured : bool -> eval_ctx -> abs -> bool
+val abs_is_destructured : Meta.meta -> bool -> eval_ctx -> abs -> bool
(** Turn a value into a abstractions.
@@ -125,7 +129,7 @@ val abs_is_destructured : bool -> eval_ctx -> abs -> bool
- [v]
*)
val convert_value_to_abstractions :
- abs_kind -> bool -> bool -> eval_ctx -> typed_value -> abs list
+ Meta.meta -> abs_kind -> bool -> bool -> eval_ctx -> typed_value -> abs list
(** See {!merge_into_abstraction}.
@@ -232,6 +236,7 @@ type merge_duplicates_funcs = {
results from the merge.
*)
val merge_into_abstraction :
+ Meta.meta ->
abs_kind ->
bool ->
merge_duplicates_funcs option ->