summaryrefslogtreecommitdiff
path: root/src/Values.ml
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Values.ml56
1 files changed, 50 insertions, 6 deletions
diff --git a/src/Values.ml b/src/Values.ml
index b6bb414b..bcb08dc8 100644
--- a/src/Values.ml
+++ b/src/Values.ml
@@ -195,6 +195,8 @@ class ['self] iter_typed_avalue_base =
object (_self : 'self)
inherit [_] iter_typed_value
+ method visit_id : 'env -> BorrowId.id -> unit = fun _ _ -> ()
+
method visit_region : 'env -> region -> unit = fun _ _ -> ()
method visit_aproj : 'env -> aproj -> unit = fun _ _ -> ()
@@ -211,6 +213,8 @@ class ['self] map_typed_avalue_base =
object (_self : 'self)
inherit [_] map_typed_value
+ method visit_id : 'env -> BorrowId.id -> BorrowId.id = fun _ id -> id
+
method visit_region : 'env -> region -> region = fun _ r -> r
method visit_aproj : 'env -> aproj -> aproj = fun _ p -> p
@@ -421,11 +425,15 @@ and aborrow_content =
> abs0 { a_shared_bororw l0 }
```
*)
- | AIgnoredMutBorrow of typed_avalue
+ | AIgnoredMutBorrow of BorrowId.id option * typed_avalue
(** An ignored mutable borrow.
-
- This is mostly useful for typing concerns: when a borrow doesn't
- belong to an abstraction, it would be weird to ignore it altogether.
+
+ We need to keep track of ignored mut borrows because when ending such
+ borrows, we need to project the loans of the given back value to
+ insert them in the proper abstractions.
+
+ Note that we need to do so only for borrows consumed by parent
+ abstractions (hence the optional borrow id).
Example:
========
@@ -441,9 +449,38 @@ and aborrow_content =
> x -> mut_loan l0
> px -> mut_loan l1
> ppx -> ⊥
- > abs'a { a_mut_borrow l1 (a_ignored_mut_borrow (U32 0)) } // TODO: duplication
- > abs'b { a_ignored_mut_borrow (a_mut_borrow l0 (U32 0)) }
+ > abs'a { a_mut_borrow l1 (a_ignored_mut_borrow None (U32 0)) } // TODO: duplication
+ > abs'b {parents={abs'a}} { a_ignored_mut_borrow (Some l1) (a_mut_borrow l0 (U32 0)) }
+
+ ... // abs'a ends
+
+ > x -> mut_loan l0
+ > px -> @s0
+ > ppx -> ⊥
+ > abs'b {
+ > a_ended_ignored_mut_borrow (a_proj_loans (@s0 <: &'b mut u32)) // <-- loan projector
+ > (a_mut_borrow l0 (U32 0))
+ > }
+
+ ... // `@s0` gets expanded to `&mut l2 @s1`
+
+ > x -> mut_loan l0
+ > px -> &mut l2 @s1
+ > ppx -> ⊥
+ > abs'b {
+ > a_ended_ignored_mut_borrow (a_mut_loan l2) // <-- loan l2 is here
+ > (a_mut_borrow l0 (U32 0))
+ > }
+
```
+
+ Note that we could use AIgnoredMutLoan in the case the borrow id is not
+ None, which would allow us to simplify the rules (to not have rules
+ to specifically handle the case of AIgnoredMutBorrow with Some borrow
+ id) and also remove the AEndedIgnoredMutBorrow variant.
+ For now, the rules are implemented and it allows us to make the avalues
+ more precise and clearer, so we will keep it that way.
+
TODO: this is annoying, we are duplicating information. Maybe we
could introduce an "Ignored" value? We have to pay attention to
two things:
@@ -460,6 +497,10 @@ and aborrow_content =
abstraction so that we can properly call the backward functions
when generating the pure translation.
*)
+ | AEndedIgnoredMutBorrow of {
+ given_back_loans_proj : typed_avalue;
+ child : typed_avalue;
+ } (** See the explanations for [AIgnoredMutBorrow] *)
| AProjSharedBorrow of abstract_shared_borrows
(** A projected shared borrow.
@@ -522,6 +563,9 @@ type abs = {
abs_id : (AbstractionId.id[@opaque]);
parents : (AbstractionId.set_t[@opaque]); (** The parent abstractions *)
regions : (RegionId.set_t[@opaque]); (** Regions owned by this abstraction *)
+ ancestors_regions : (RegionId.set_t[@opaque]);
+ (** Union of the regions owned by this abstraction's ancestors (not
+ including the regions of this abstraction itself) *)
avalues : typed_avalue list; (** The values in this abstraction *)
}
[@@deriving