-
Notifications
You must be signed in to change notification settings - Fork 41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Challenge 4: Memory safety of BTreeMap's btree::node
module
#77
Comments
Anyone looking into this might be puzzled initially by the ValMut borrow type. The description says there may be any number of outstanding mutable references to values, but if you just look at the API of node.rs, you would think the |
I've started looking into this challenge. I've made a first stab at a separation logic predicate (plus supporting definitions) defining what it means to own a NodeRef. Note: for now, this is completely untested; I have not yet attempted to use it to verify any code. |
OK, I've looked some more at the codebase. If I'm not mistaken, borrow type ValMut is being used (only) to implement IterMut, and borrow type Dying is used (only) to implement IntoIter. In both cases, two NodeRef values of this type are used, to point to the start and end of the iterator, which is a DoubleEndedIterator and can therefore be consumed from both ends. Any given key-value pair can be returned from either end, depending on which end reaches that pair first. Therefore, it does not work to assign ownership of a given key-value pair to one of these NodeRefs. My idea for how these iterators could perhaps be verified is then that, when in rest, ownership of the not-yet-consumed part of the tree is held just once by the iterator, separately from the two NodeRefs, which themselves are in a kind of dormant state. When I have improved my NodeRef predicate to take this new insight into account. The predicate now asserts ownership of only the part of the tree between two leaf edges. When the borrow type is Immut, Mut, or Owned, that range is in fact the full range, i.e. the entire tree. Only with borrow type ValMut or Dying could the range be less. The node.rs functions that are polymorphic over the borrow type, mostly navigation functions, will need to take a precondition saying that the navigation does not exit the "active" range. Even the non- Note: the doc comment for NodeRef says that ValMut is like a shared reference as far as the tree structure is concerned. But as far as I can tell, it is only used in IterMut, where always only these exactly two NodeRefs exist, so there is not really any arbitrary sharing going on. Therefore, it seemed more logical to have ValMut own a full borrow of the tree and the keys rather than a fractured borrow. (This also jives better with the fact that node.rs implements Send for |
Tracking issue for Challenge 4: Memory safety of BTreeMap's btree::node module.
The text was updated successfully, but these errors were encountered: