summaryrefslogtreecommitdiff
path: root/src/InterpreterBorrows.ml
diff options
context:
space:
mode:
Diffstat (limited to 'src/InterpreterBorrows.ml')
-rw-r--r--src/InterpreterBorrows.ml309
1 files changed, 156 insertions, 153 deletions
diff --git a/src/InterpreterBorrows.ml b/src/InterpreterBorrows.ml
index 6f469044..e64dbe77 100644
--- a/src/InterpreterBorrows.ml
+++ b/src/InterpreterBorrows.ml
@@ -118,9 +118,9 @@ let end_borrow_get_borrow (allowed_abs : V.AbstractionId.id option)
* need it to properly instantiate the backward functions when generating
* the pure translation. *)
match lc with
- | V.AMutLoan (bid, av) ->
+ | V.AMutLoan (_, _) ->
(* Nothing special to do *)
- V.ALoan (super#visit_AMutLoan outer bid av)
+ super#visit_ALoan outer lc
| V.ASharedLoan (bids, v, av) ->
(* Explore the shared value - we need to update the outer borrows *)
let souter = update_outer_borrows outer (Borrows bids) in
@@ -129,27 +129,22 @@ let end_borrow_get_borrow (allowed_abs : V.AbstractionId.id option)
let av = super#visit_typed_avalue outer av in
(* Reconstruct *)
V.ALoan (V.ASharedLoan (bids, v, av))
- | V.AEndedMutLoan { given_back; child } ->
- (* The loan has ended, so no need to update the outer borrows *)
- V.ALoan (super#visit_AEndedMutLoan outer given_back child)
- | V.AEndedSharedLoan (v, av) ->
- (* The loan has ended, so no need to update the outer borrows *)
- V.ALoan (super#visit_AEndedSharedLoan outer v av)
- | V.AIgnoredMutLoan (bid, av) ->
- (* Nothing special to do *)
- V.ALoan (super#visit_AIgnoredMutLoan outer bid av)
- | V.AEndedIgnoredMutLoan { given_back; child } ->
- (* Nothing special to do *)
- V.ALoan (super#visit_AEndedIgnoredMutLoan outer given_back child)
- | V.AIgnoredSharedLoan av ->
+ | V.AEndedMutLoan { given_back = _; child = _; given_back_meta = _ }
+ | V.AEndedSharedLoan _
+ (* The loan has ended, so no need to update the outer borrows *)
+ | V.AIgnoredMutLoan _ (* Nothing special to do *)
+ | V.AEndedIgnoredMutLoan
+ { given_back = _; child = _; given_back_meta = _ }
+ (* Nothing special to do *)
+ | V.AIgnoredSharedLoan _ ->
(* Nothing special to do *)
- V.ALoan (super#visit_AIgnoredSharedLoan outer av)
+ super#visit_ALoan outer lc
(** We reimplement [visit_ALoan] because we may have to update the
outer borrows *)
method! visit_ABorrow outer bc =
match bc with
- | V.AMutBorrow (bid, av) ->
+ | V.AMutBorrow (_, bid, _) ->
(* Check if this is the borrow we are looking for *)
if bid = l then (
(* When ending a mut borrow, there are two cases:
@@ -166,12 +161,15 @@ let end_borrow_get_borrow (allowed_abs : V.AbstractionId.id option)
(* Register the update *)
set_replaced_bc (Abstract bc);
(* Update the value - note that we are necessarily in the second
- * of the two cases described above *)
+ * of the two cases described above.
+ * 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] *)
V.ABottom)
else
(* Update the outer borrows before diving into the child avalue *)
let outer = update_outer_borrows outer (Borrow bid) in
- V.ABorrow (super#visit_AMutBorrow outer bid av)
+ super#visit_ABorrow outer bc
| V.ASharedBorrow bid ->
(* Check if this is the borrow we are looking for *)
if bid = l then (
@@ -183,15 +181,13 @@ let end_borrow_get_borrow (allowed_abs : V.AbstractionId.id option)
(* Update the value - note that we are necessarily in the second
* of the two cases described above *)
V.ABottom)
- else V.ABorrow (super#visit_ASharedBorrow outer bid)
- | V.AIgnoredMutBorrow (opt_bid, av) ->
- (* Nothing special to do *)
- V.ABorrow (super#visit_AIgnoredMutBorrow outer opt_bid av)
- | V.AEndedIgnoredMutBorrow { given_back_loans_proj; child } ->
+ else super#visit_ABorrow outer bc
+ | V.AIgnoredMutBorrow (_, _)
+ | V.AEndedMutBorrow _
+ | V.AEndedIgnoredMutBorrow
+ { given_back_loans_proj = _; child = _; given_back_meta = _ } ->
(* Nothing special to do *)
- V.ABorrow
- (super#visit_AEndedIgnoredMutBorrow outer given_back_loans_proj
- child)
+ super#visit_ABorrow outer bc
| V.AProjSharedBorrow asb ->
(* Check if the borrow we are looking for is in the asb *)
if borrow_in_asb l asb then (
@@ -204,9 +200,8 @@ let end_borrow_get_borrow (allowed_abs : V.AbstractionId.id option)
* of the two cases described above *)
let asb = remove_borrow_from_asb l asb in
V.ABorrow (V.AProjSharedBorrow asb))
- else
- (* Nothing special to do *)
- V.ABorrow (super#visit_AProjSharedBorrow outer asb)
+ else (* Nothing special to do *)
+ super#visit_ABorrow outer bc
method! visit_abs outer abs =
(* Update the outer abs *)
@@ -317,6 +312,8 @@ let give_back_value (config : C.config) (bid : V.BorrowId.id)
match nv.V.value with
| V.Symbolic sv ->
let abs = Option.get opt_abs in
+ (* Remember the given back value as a meta-value *)
+ let given_back_meta = nv in
(* The loan projector *)
let given_back_loans_proj =
mk_aproj_loans_value_from_symbolic_value abs.regions sv
@@ -325,7 +322,8 @@ let give_back_value (config : C.config) (bid : V.BorrowId.id)
let child = super#visit_typed_avalue opt_abs child in
(* Return *)
V.ABorrow
- (V.AEndedIgnoredMutBorrow { given_back_loans_proj; child })
+ (V.AEndedIgnoredMutBorrow
+ { given_back_loans_proj; child; given_back_meta })
| _ -> failwith "Unreachable"
else
(* Continue exploring *)
@@ -359,6 +357,8 @@ let give_back_value (config : C.config) (bid : V.BorrowId.id)
* an ended loan *)
(* Register the insertion *)
set_replaced ();
+ (* Remember the given back value as a meta-value *)
+ let given_back_meta = nv in
(* Apply the projection *)
let given_back =
apply_proj_borrows check_symbolic_no_ended ctx fresh_reborrow
@@ -367,23 +367,22 @@ let give_back_value (config : C.config) (bid : V.BorrowId.id)
(* Continue giving back in the child value *)
let child = super#visit_typed_avalue opt_abs child in
(* Return the new value *)
- V.ALoan (V.AEndedMutLoan { given_back; child }))
- else
- (* Continue exploring *)
- V.ALoan (super#visit_AMutLoan opt_abs bid' child)
- | V.ASharedLoan (bids, v, av) ->
+ V.ALoan (V.AEndedMutLoan { child; given_back; given_back_meta }))
+ else (* Continue exploring *)
+ super#visit_ALoan opt_abs lc
+ | V.ASharedLoan (_, _, _) ->
(* We are giving back a value to a *mutable* loan: nothing special to do *)
- V.ALoan (super#visit_ASharedLoan opt_abs bids v av)
- | V.AEndedMutLoan { given_back; child } ->
- (* Nothing special to do *)
- V.ALoan (super#visit_AEndedMutLoan opt_abs given_back child)
- | V.AEndedSharedLoan (v, av) ->
+ super#visit_ALoan opt_abs lc
+ | V.AEndedMutLoan { child = _; given_back = _; given_back_meta = _ }
+ | V.AEndedSharedLoan (_, _) ->
(* Nothing special to do *)
- V.ALoan (super#visit_AEndedSharedLoan opt_abs v av)
+ super#visit_ALoan opt_abs lc
| V.AIgnoredMutLoan (bid', child) ->
(* This loan is ignored, but we may have to project on a subvalue
* of the value which is given back *)
if bid' = bid then
+ (* Remember the given back value as a meta-value *)
+ let given_back_meta = nv in
(* Note that we replace the ignored mut loan by an *ended* ignored
* mut loan. Also, this is not the loan we are looking for *per se*:
* we don't register the fact that we inserted the value somewhere
@@ -394,14 +393,14 @@ let give_back_value (config : C.config) (bid : V.BorrowId.id)
in
(* Continue giving back in the child value *)
let child = super#visit_typed_avalue opt_abs child in
- V.ALoan (V.AEndedIgnoredMutLoan { given_back; child })
- else V.ALoan (super#visit_AIgnoredMutLoan opt_abs bid' child)
- | V.AEndedIgnoredMutLoan { given_back; child } ->
+ V.ALoan
+ (V.AEndedIgnoredMutLoan { given_back; child; given_back_meta })
+ else super#visit_ALoan opt_abs lc
+ | V.AEndedIgnoredMutLoan
+ { given_back = _; child = _; given_back_meta = _ }
+ | V.AIgnoredSharedLoan _ ->
(* Nothing special to do *)
- V.ALoan (super#visit_AEndedIgnoredMutLoan opt_abs given_back child)
- | V.AIgnoredSharedLoan av ->
- (* Nothing special to do *)
- V.ALoan (super#visit_AIgnoredSharedLoan opt_abs av)
+ super#visit_ALoan opt_abs lc
(** We are not specializing an already existing method, but adding a
new method (for projections, we need type information) *)
@@ -432,6 +431,9 @@ let give_back_value (config : C.config) (bid : V.BorrowId.id)
let give_back_symbolic_value (_config : C.config)
(proj_regions : T.RegionId.Set.t) (proj_ty : T.rty) (sv : V.symbolic_value)
(nsv : V.symbolic_value) (ctx : C.eval_ctx) : C.eval_ctx =
+ (* Store the given-back value as a meta-value for synthesis purposes *)
+ let mv = mk_typed_value_from_symbolic_value nsv in
+ (* Substitution function, to replace the borrow projectors over symbolic values *)
let subst (_abs : V.abs) _abs_proj_ty =
(* Compute the projection over the given back value *)
let child_proj =
@@ -466,7 +468,7 @@ let give_back_symbolic_value (_config : C.config)
None
| _ -> failwith "Unreachable")
in
- V.AEndedProjLoans child_proj
+ V.AEndedProjLoans (mv, child_proj)
in
update_intersecting_aproj_loans proj_regions proj_ty sv subst ctx
@@ -484,8 +486,8 @@ let give_back_symbolic_value (_config : C.config)
to convert the [avalue] to a [value] by introducing the proper symbolic values.
*)
let give_back_avalue_to_same_abstraction (_config : C.config)
- (bid : V.BorrowId.id) (nv : V.typed_avalue) (ctx : C.eval_ctx) : C.eval_ctx
- =
+ (bid : V.BorrowId.id) (mv : V.mvalue) (nv : V.typed_avalue)
+ (ctx : C.eval_ctx) : C.eval_ctx =
(* We use a reference to check that we updated exactly one loan *)
let replaced : bool ref = ref false in
let set_replaced () =
@@ -530,19 +532,17 @@ let give_back_avalue_to_same_abstraction (_config : C.config)
(* Register the insertion *)
set_replaced ();
(* Return the new value *)
- V.ALoan (V.AEndedMutLoan { given_back = nv; child }))
- else
- (* Continue exploring *)
- V.ALoan (super#visit_AMutLoan opt_abs bid' child)
- | V.ASharedLoan (bids, v, av) ->
- (* We are giving back a value to a *mutable* loan: nothing special to do *)
- V.ALoan (super#visit_ASharedLoan opt_abs bids v av)
- | V.AEndedMutLoan { given_back; child } ->
- (* Nothing special to do *)
- V.ALoan (super#visit_AEndedMutLoan opt_abs given_back child)
- | V.AEndedSharedLoan (v, av) ->
+ V.ALoan
+ (V.AEndedMutLoan
+ { given_back = nv; child; given_back_meta = mv }))
+ else (* Continue exploring *)
+ super#visit_ALoan opt_abs lc
+ | V.ASharedLoan (_, _, _)
+ (* We are giving back a value to a *mutable* loan: nothing special to do *)
+ | V.AEndedMutLoan { given_back = _; child = _; given_back_meta = _ }
+ | V.AEndedSharedLoan (_, _) ->
(* Nothing special to do *)
- V.ALoan (super#visit_AEndedSharedLoan opt_abs v av)
+ super#visit_ALoan opt_abs lc
| V.AIgnoredMutLoan (bid', child) ->
(* This loan is ignored, but we may have to project on a subvalue
* of the value which is given back *)
@@ -553,14 +553,15 @@ let give_back_avalue_to_same_abstraction (_config : C.config)
* (i.e., we don't call [set_replaced]) *)
(* Sanity check *)
assert (nv.V.ty = ty);
- V.ALoan (V.AEndedIgnoredMutLoan { given_back = nv; child }))
- else V.ALoan (super#visit_AIgnoredMutLoan opt_abs bid' child)
- | V.AEndedIgnoredMutLoan { given_back; child } ->
- (* Nothing special to do *)
- V.ALoan (super#visit_AEndedIgnoredMutLoan opt_abs given_back child)
- | V.AIgnoredSharedLoan av ->
+ V.ALoan
+ (V.AEndedIgnoredMutLoan
+ { given_back = nv; child; given_back_meta = mv }))
+ else super#visit_ALoan opt_abs lc
+ | V.AEndedIgnoredMutLoan
+ { given_back = _; child = _; given_back_meta = _ }
+ | V.AIgnoredSharedLoan _ ->
(* Nothing special to do *)
- V.ALoan (super#visit_AIgnoredSharedLoan opt_abs av)
+ super#visit_ALoan opt_abs lc
(** We are not specializing an already existing method, but adding a
new method (for projections, we need type information) *)
end
@@ -634,22 +635,19 @@ let give_back_shared _config (bid : V.BorrowId.id) (ctx : C.eval_ctx) :
(V.BorrowId.Set.remove bid bids, shared_value, child)))
else
(* Not the loan we are looking for: continue exploring *)
- V.ALoan (super#visit_ASharedLoan opt_abs bids shared_value child)
- | V.AEndedMutLoan { given_back; child } ->
- (* Nothing special to do (the loan has ended) *)
- V.ALoan (super#visit_AEndedMutLoan opt_abs given_back child)
- | V.AEndedSharedLoan (v, av) ->
- (* Nothing special to do (the loan has ended) *)
- V.ALoan (super#visit_AEndedSharedLoan opt_abs v av)
- | V.AIgnoredMutLoan (bid, av) ->
- (* Nothing special to do (we are giving back a *shared* borrow) *)
- V.ALoan (super#visit_AIgnoredMutLoan opt_abs bid av)
- | V.AEndedIgnoredMutLoan { given_back; child } ->
- (* Nothing special to do *)
- V.ALoan (super#visit_AEndedIgnoredMutLoan opt_abs given_back child)
- | V.AIgnoredSharedLoan av ->
+ super#visit_ALoan opt_abs lc
+ | V.AEndedMutLoan { given_back = _; child = _; given_back_meta = _ }
+ (* Nothing special to do (the loan has ended) *)
+ | V.AEndedSharedLoan (_, _)
+ (* Nothing special to do (the loan has ended) *)
+ | V.AIgnoredMutLoan (_, _)
+ (* Nothing special to do (we are giving back a *shared* borrow) *)
+ | V.AEndedIgnoredMutLoan
+ { given_back = _; child = _; given_back_meta = _ }
+ (* Nothing special to do *)
+ | V.AIgnoredSharedLoan _ ->
(* Nothing special to do *)
- V.ALoan (super#visit_AIgnoredSharedLoan opt_abs av)
+ super#visit_ALoan opt_abs lc
end
in
@@ -736,13 +734,13 @@ let give_back (config : C.config) (l : V.BorrowId.id) (bc : g_borrow_content)
assert (Option.is_some (lookup_loan_opt sanity_ek l ctx));
(* Update the context *)
give_back_shared config l ctx
- | Abstract (V.AMutBorrow (l', av)) ->
+ | Abstract (V.AMutBorrow (mv, l', av)) ->
(* Sanity check *)
assert (l' = l);
(* Check that the corresponding loan is somewhere - purely a sanity check *)
assert (Option.is_some (lookup_loan_opt sanity_ek l ctx));
(* Update the context *)
- give_back_avalue_to_same_abstraction config l av ctx
+ give_back_avalue_to_same_abstraction config l mv av ctx
| Abstract (V.ASharedBorrow l') ->
(* Sanity check *)
assert (l' = l);
@@ -755,7 +753,9 @@ let give_back (config : C.config) (l : V.BorrowId.id) (bc : g_borrow_content)
assert (borrow_in_asb l asb);
(* Update the context *)
give_back_shared config l ctx
- | Abstract (V.AIgnoredMutBorrow _ | V.AEndedIgnoredMutBorrow _) ->
+ | Abstract
+ (V.AEndedMutBorrow _ | V.AIgnoredMutBorrow _ | V.AEndedIgnoredMutBorrow _)
+ ->
failwith "Unreachable"
(** Convert an [avalue] to a [value].
@@ -1017,21 +1017,22 @@ and end_abstraction_loans (config : C.config) (chain : borrow_or_abs_ids)
match lc with
| V.AMutLoan (bid, _) -> raise (FoundBorrowIds (Borrow bid))
| V.ASharedLoan (bids, _, _) -> raise (FoundBorrowIds (Borrows bids))
- | V.AEndedMutLoan { given_back; child } ->
- super#visit_AEndedMutLoan env given_back child
- | V.AEndedSharedLoan (v, av) -> super#visit_AEndedSharedLoan env v av
- | V.AIgnoredMutLoan (bid, av) ->
+ | V.AEndedMutLoan { given_back = _; child = _; given_back_meta = _ }
+ | V.AEndedSharedLoan (_, _) ->
+ super#visit_aloan_content env lc
+ | V.AIgnoredMutLoan (_, _) ->
(* Note that this loan can't come from a parent abstraction, because
* we should have ended them already) *)
- super#visit_AIgnoredMutLoan env bid av
- | V.AEndedIgnoredMutLoan { given_back; child } ->
- super#visit_AEndedIgnoredMutLoan env given_back child
- | V.AIgnoredSharedLoan av -> super#visit_AIgnoredSharedLoan env av
+ super#visit_aloan_content env lc
+ | V.AEndedIgnoredMutLoan
+ { given_back = _; child = _; given_back_meta = _ }
+ | V.AIgnoredSharedLoan _ ->
+ super#visit_aloan_content env lc
method! visit_aproj env sproj =
(match sproj with
| V.AProjBorrows (_, _)
- | V.AEndedProjLoans _ | V.AEndedProjBorrows | V.AIgnoredProjBorrows ->
+ | V.AEndedProjLoans _ | V.AEndedProjBorrows _ | V.AIgnoredProjBorrows ->
()
| V.AProjLoans sv -> raise (FoundSymbolicValue sv));
super#visit_aproj env sproj
@@ -1062,28 +1063,11 @@ and end_abstraction_borrows (config : C.config) (chain : borrow_or_abs_ids)
(* Note that the abstraction mustn't contain any loans *)
(* We end the borrows, starting with the *inner* ones. This is important
when considering nested borrows which have the same lifetime.
- TODO: is that really important?
-
- For instance:
- ```
- x -> mut_loan l1
- px -> mut_loan l0
- abs0 { a_mut_borrow l0 (a_mut_borrow l1 (U32 3)) }
- ```
-
- becomes (`U32 3` doesn't contain ⊥, so we give back a symbolic value):
- ```
- x -> @s0
- px -> mut_loan l0
- abs0 { a_mut_borrow l0 ⊥ }
- ```
-
- then (the borrowed value contains ⊥, we give back ⊥):
- ```
- x -> @s0
- px -> ⊥
- abs0 { ⊥ }
- ```
+ TODO: is that really important? Initially, there was a concern about
+ whether we should give back ⊥ or not, but everything is handled by
+ the symbolic value expansion... Also, now we use the AEndedMutBorrow
+ values to store the children avalues (which was not the case before - we
+ initially replaced the ended mut borrows with ⊥).
*)
(* We explore in-depth and use exceptions. When exploring a borrow, if
* the exploration didn't trigger an exception, it means there are no
@@ -1099,7 +1083,7 @@ and end_abstraction_borrows (config : C.config) (chain : borrow_or_abs_ids)
(* No exception was raise: we can raise an exception for the
* current borrow *)
match bc with
- | V.AMutBorrow (_, _) | V.ASharedBorrow _ ->
+ | V.AMutBorrow (_, _, _) | V.ASharedBorrow _ ->
(* Raise an exception *)
raise (FoundABorrowContent bc)
| V.AProjSharedBorrow asb ->
@@ -1110,7 +1094,8 @@ and end_abstraction_borrows (config : C.config) (chain : borrow_or_abs_ids)
asb
then raise (FoundABorrowContent bc)
else ()
- | V.AIgnoredMutBorrow _ | V.AEndedIgnoredMutBorrow _ ->
+ | V.AEndedMutBorrow _ | V.AIgnoredMutBorrow _
+ | V.AEndedIgnoredMutBorrow _ ->
(* Nothing to do for ignored borrows *)
()
@@ -1119,7 +1104,7 @@ and end_abstraction_borrows (config : C.config) (chain : borrow_or_abs_ids)
| V.AProjLoans _ -> failwith "Unexpected"
| V.AProjBorrows (sv, proj_ty) ->
raise (FoundAProjBorrows (sv, proj_ty))
- | V.AEndedProjLoans _ | V.AEndedProjBorrows | V.AIgnoredProjBorrows ->
+ | V.AEndedProjLoans _ | V.AEndedProjBorrows _ | V.AIgnoredProjBorrows ->
());
super#visit_aproj env sproj
end
@@ -1134,49 +1119,64 @@ and end_abstraction_borrows (config : C.config) (chain : borrow_or_abs_ids)
with
(* There are concrete borrows: end them, then reexplore *)
| FoundABorrowContent bc ->
- (* First, replace the borrow by ⊥ *)
- let bid =
- match bc with
- | V.AMutBorrow (bid, _) | V.ASharedBorrow bid -> bid
- | V.AProjSharedBorrow asb -> (
- (* There should be at least one borrow identifier in the set, which we
- * can use to identify the whole set *)
- match
- List.find
- (fun x -> match x with V.AsbBorrow _ -> true | _ -> false)
- asb
- with
- | V.AsbBorrow bid -> bid
- | _ -> failwith "Unexpected")
- | V.AIgnoredMutBorrow _ | V.AEndedIgnoredMutBorrow _ ->
- failwith "Unexpected"
- in
- let ctx = update_aborrow ek_all bid V.ABottom ctx in
- (* Then give back the value *)
let ctx =
match bc with
- | V.AMutBorrow (bid, av) ->
+ | V.AMutBorrow (_, bid, av) ->
(* First, convert the avalue to a (fresh symbolic) value *)
let v = convert_avalue_to_given_back_value 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 = V.ABorrow (V.AEndedMutBorrow (v, av)) in
+ let ctx = update_aborrow ek_all bid ended_borrow ctx in
+ (* Give the value back *)
give_back_value config bid v ctx
- | V.ASharedBorrow bid -> give_back_shared config bid ctx
- | V.AProjSharedBorrow _ ->
- (* Nothing to do *)
+ | V.ASharedBorrow bid ->
+ (* Replace the shared borrow with bottom *)
+ let ctx = update_aborrow ek_all bid V.ABottom ctx in
+ (* Give back *)
+ give_back_shared config bid ctx
+ | V.AProjSharedBorrow asb ->
+ (* Retrieve the borrow ids *)
+ let bids =
+ List.filter_map
+ (fun asb ->
+ match asb with
+ | V.AsbBorrow bid -> Some bid
+ | V.AsbProjReborrows (_, _) -> None)
+ asb
+ in
+ (* There should be at least one borrow identifier in the set, which we
+ * 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 V.ABottom ctx in
+ (* Give back the shared borrows *)
+ let ctx =
+ List.fold_left
+ (fun ctx bid -> give_back_shared config bid ctx)
+ ctx bids
+ in
+ (* Continue *)
ctx
- | V.AIgnoredMutBorrow _ | V.AEndedIgnoredMutBorrow _ ->
+ | V.AEndedMutBorrow _ | V.AIgnoredMutBorrow _
+ | V.AEndedIgnoredMutBorrow _ ->
failwith "Unexpected"
in
(* Reexplore *)
end_abstraction_borrows config chain abs_id ctx
(* There are symbolic borrows: end them, then reexplore *)
| FoundAProjBorrows (sv, proj_ty) ->
+ (* Generate a fresh symbolic value *)
+ let nsv = mk_fresh_symbolic_value V.FunCallGivenBack proj_ty in
(* Replace the proj_borrows - there should be exactly one *)
+ let ended_borrow =
+ V.AEndedProjBorrows (mk_typed_value_from_symbolic_value nsv)
+ in
let ctx =
- update_intersecting_aproj_borrows_non_shared abs.regions sv
- V.AEndedProjBorrows ctx
+ update_intersecting_aproj_borrows_non_shared abs.regions sv ended_borrow
+ ctx
in
- (* Give back a fresh symbolic value *)
- let nsv = mk_fresh_symbolic_value V.FunCallGivenBack proj_ty in
+ (* Give back the symbolic value *)
let ctx =
give_back_symbolic_value config abs.regions proj_ty sv nsv ctx
in
@@ -1257,14 +1257,17 @@ and end_proj_loans_symbolic (config : C.config) (chain : borrow_or_abs_ids)
* end it directly, otherwise we need to end the abstraction where it
* came from first *)
if abs_id' = abs_id then
+ (* As the symbolic value was left unchanged, we give it back *)
+ let given_back_sv = sv in
(* Replace the proj_borrows *)
- let npb = V.AEndedProjBorrows in
+ let given_back = mk_typed_value_from_symbolic_value given_back_sv in
+ let npb = V.AEndedProjBorrows given_back in
let ctx =
update_intersecting_aproj_borrows_non_shared regions sv npb ctx
in
(* Replace the proj_loans - note that the loaned (symbolic) value
* was left unchanged *)
- give_back_symbolic_value config regions sv.V.sv_ty sv sv ctx
+ give_back_symbolic_value config regions sv.V.sv_ty sv given_back_sv ctx
else
(* End the abstraction.
* Don't retry ending the current proj_loans after ending the abstraction: