Mercurial > public > mercurial-scm > hg-stable
annotate rust/hg-core/src/dirstate_tree/owning.rs @ 48605:a809f1465a76
filemerge: set default labels a little earlier
By setting the default labels a little earlier, we can rely on them
always being set, as far as I can tell. It may actually even be fine
to rely on that even if we don't set them earlier, but it makes more
sense to me to do it.
Differential Revision: https://phab.mercurial-scm.org/D12015
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Thu, 20 Jan 2022 13:43:43 -0800 |
parents | d1210d56008b |
children | cfd270d83169 |
rev | line source |
---|---|
47982
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
1 use super::dirstate_map::DirstateMap; |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
2 use stable_deref_trait::StableDeref; |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
3 use std::ops::Deref; |
47137
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
4 |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
5 /// Keep a `DirstateMap<'on_disk>` next to the `on_disk` buffer that it |
47982
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
6 /// borrows. |
47137
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
7 /// |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
8 /// This is similar to [`OwningRef`] which is more limited because it |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
9 /// represents exactly one `&T` reference next to the value it borrows, as |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
10 /// opposed to a struct that may contain an arbitrary number of references in |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
11 /// arbitrarily-nested data structures. |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
12 /// |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
13 /// [`OwningRef`]: https://docs.rs/owning_ref/0.4.1/owning_ref/struct.OwningRef.html |
47982
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
14 pub struct OwningDirstateMap { |
47137
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
15 /// Owned handle to a bytes buffer with a stable address. |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
16 /// |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
17 /// See <https://docs.rs/owning_ref/0.4.1/owning_ref/trait.StableAddress.html>. |
47982
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
18 on_disk: Box<dyn Deref<Target = [u8]> + Send>, |
47137
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
19 |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
20 /// Pointer for `Box<DirstateMap<'on_disk>>`, typed-erased because the |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
21 /// language cannot represent a lifetime referencing a sibling field. |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
22 /// This is not quite a self-referencial struct (moving this struct is not |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
23 /// a problem as it doesn’t change the address of the bytes buffer owned |
48595
d1210d56008b
rust: Fix outdated comments in OwningDirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
48084
diff
changeset
|
24 /// by `on_disk`) but touches similar borrow-checker limitations. |
47137
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
25 ptr: *mut (), |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
26 } |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
27 |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
28 impl OwningDirstateMap { |
47982
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
29 pub fn new_empty<OnDisk>(on_disk: OnDisk) -> Self |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
30 where |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
31 OnDisk: Deref<Target = [u8]> + StableDeref + Send + 'static, |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
32 { |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
33 let on_disk = Box::new(on_disk); |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
34 let bytes: &'_ [u8] = &on_disk; |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
35 let map = DirstateMap::empty(bytes); |
47137
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
36 |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
37 // Like in `bytes` above, this `'_` lifetime parameter borrows from |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
38 // the bytes buffer owned by `on_disk`. |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
39 let ptr: *mut DirstateMap<'_> = Box::into_raw(Box::new(map)); |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
40 |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
41 // Erase the pointed type entirely in order to erase the lifetime. |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
42 let ptr: *mut () = ptr.cast(); |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
43 |
47982
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
44 Self { on_disk, ptr } |
47137
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
45 } |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
46 |
48084
3d0a9c6e614d
dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents:
48056
diff
changeset
|
47 pub fn get_pair_mut<'a>( |
47982
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
48 &'a mut self, |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
49 ) -> (&'a [u8], &'a mut DirstateMap<'a>) { |
47137
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
50 // SAFETY: We cast the type-erased pointer back to the same type it had |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
51 // in `new`, except with a different lifetime parameter. This time we |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
52 // connect the lifetime to that of `self`. This cast is valid because |
48595
d1210d56008b
rust: Fix outdated comments in OwningDirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
48084
diff
changeset
|
53 // `self` owns the same `on_disk` whose buffer `DirstateMap` |
d1210d56008b
rust: Fix outdated comments in OwningDirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
48084
diff
changeset
|
54 // references. That buffer has a stable memory address because our |
d1210d56008b
rust: Fix outdated comments in OwningDirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
48084
diff
changeset
|
55 // `Self::new_empty` counstructor requires `StableDeref`. |
47137
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
56 let ptr: *mut DirstateMap<'a> = self.ptr.cast(); |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
57 // SAFETY: we dereference that pointer, connecting the lifetime of the |
48595
d1210d56008b
rust: Fix outdated comments in OwningDirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
48084
diff
changeset
|
58 // new `&mut` to that of `self`. This is valid because the |
d1210d56008b
rust: Fix outdated comments in OwningDirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
48084
diff
changeset
|
59 // raw pointer is to a boxed value, and `self` owns that box. |
47982
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
60 (&self.on_disk, unsafe { &mut *ptr }) |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
61 } |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
62 |
48084
3d0a9c6e614d
dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents:
48056
diff
changeset
|
63 pub fn get_map_mut<'a>(&'a mut self) -> &'a mut DirstateMap<'a> { |
3d0a9c6e614d
dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents:
48056
diff
changeset
|
64 self.get_pair_mut().1 |
47137
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
65 } |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
66 |
48084
3d0a9c6e614d
dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents:
48056
diff
changeset
|
67 pub fn get_map<'a>(&'a self) -> &'a DirstateMap<'a> { |
48595
d1210d56008b
rust: Fix outdated comments in OwningDirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
48084
diff
changeset
|
68 // SAFETY: same reasoning as in `get_pair_mut` above. |
47137
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
69 let ptr: *mut DirstateMap<'a> = self.ptr.cast(); |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
70 unsafe { &*ptr } |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
71 } |
47982
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
72 |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
73 pub fn on_disk<'a>(&'a self) -> &'a [u8] { |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
74 &self.on_disk |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
75 } |
47137
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
76 } |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
77 |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
78 impl Drop for OwningDirstateMap { |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
79 fn drop(&mut self) { |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
80 // Silence a "field is never read" warning, and demonstrate that this |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
81 // value is still alive. |
48595
d1210d56008b
rust: Fix outdated comments in OwningDirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
48084
diff
changeset
|
82 let _: &Box<dyn Deref<Target = [u8]> + Send> = &self.on_disk; |
47137
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
83 // SAFETY: this cast is the same as in `get_mut`, and is valid for the |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
84 // same reason. `self.on_disk` still exists at this point, drop glue |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
85 // will drop it implicitly after this `drop` method returns. |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
86 let ptr: *mut DirstateMap<'_> = self.ptr.cast(); |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
87 // SAFETY: `Box::from_raw` takes ownership of the box away from `self`. |
48595
d1210d56008b
rust: Fix outdated comments in OwningDirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
48084
diff
changeset
|
88 // This is fine because drop glue does nothing for `*mut ()` and we’re |
47137
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
89 // in `drop`, so `get` and `get_mut` cannot be called again. |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
90 unsafe { drop(Box::from_raw(ptr)) } |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
91 } |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
92 } |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
93 |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
94 fn _static_assert_is_send<T: Send>() {} |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
95 |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
96 fn _static_assert_fields_are_send() { |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
97 _static_assert_is_send::<Box<DirstateMap<'_>>>(); |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
98 } |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
99 |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
100 // SAFETY: we don’t get this impl implicitly because `*mut (): !Send` because |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
101 // thread-safety of raw pointers is unknown in the general case. However this |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
102 // particular raw pointer represents a `Box<DirstateMap<'on_disk>>` that we |
47982
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
103 // own. Since that `Box` is `Send` as shown in above, it is sound to mark |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
104 // this struct as `Send` too. |
47137
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
105 unsafe impl Send for OwningDirstateMap {} |