Mercurial > public > mercurial-scm > hg
annotate rust/hg-core/src/dirstate_tree/owning.rs @ 48999:cfd270d83169 stable
rust: explain why the current `OwningDirstateMap` is unsound
See inline comments.
Differential Revision: https://phab.mercurial-scm.org/D12428
author | Rapha?l Gom?s <rgomes@octobus.net> |
---|---|
date | Tue, 05 Apr 2022 10:55:27 +0200 |
parents | d1210d56008b |
children | dd6b67d5c256 |
rev | line source |
---|---|
47954
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; |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
4 |
48999
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
5 /* |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
6 // /!\ This is unsound and can cause use after free. It will be fixed in the |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
7 // next patch |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
8 |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
9 // If we change `value` from its current use of `HgPathBuf` to `&HgPath`, |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
10 // nothing here tells that `value` will outlive `OwningDirstateMap` |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
11 pub fn copy_map_insert<'a,'owned>( |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
12 &'owned mut self, |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
13 key: &HgPath, |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
14 value: &'a HgPath, |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
15 ) -> Result<Option<HgPathBuf>, DirstateV2ParseError> { |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
16 // `'local` is smaller than `'a` here |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
17 let map: &'local mut DirstateMap<'local> = self.get_map_mut(); |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
18 let node: &'local mut Node<'local> = DirstateMap::get_or_insert_node( |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
19 map.on_disk, |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
20 &mut map.unreachable_bytes, |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
21 &mut map.root, |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
22 &key, |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
23 WithBasename::to_cow_owned, |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
24 |_ancestor| {}, |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
25 )?; |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
26 if node.copy_source.is_none() { |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
27 map.nodes_with_copy_source_count += 1 |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
28 } |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
29 Ok(node.copy_source.replace(value.into()).map(Cow::into_owned)) |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
30 // and right here ----------^^^^^^^^^^^^ |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
31 // we are storing `&'a HgPath` in `Node<'local>` which is possible |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
32 // because to the compiler, `'a` is longer than ``local`. |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
33 // It is wrong because nothing proves that `&'a HgPath` will outlive `self`. |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
34 } |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
35 |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
36 // All of this is caused by the wrong cast of the DirstateMap pointer that |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
37 // fakes the lifetime of `DirstateMap` and ensures the compiler that it lives |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
38 // as long as `on_disk`, which is only true for its immutable data. |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
39 // This will be fixed in the next commit. |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
40 */ |
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48567
diff
changeset
|
41 |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
42 /// Keep a `DirstateMap<'on_disk>` next to the `on_disk` buffer that it |
47954
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
43 /// borrows. |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
44 /// |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
45 /// 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
|
46 /// 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
|
47 /// 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
|
48 /// arbitrarily-nested data structures. |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
49 /// |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
50 /// [`OwningRef`]: https://docs.rs/owning_ref/0.4.1/owning_ref/struct.OwningRef.html |
47954
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
51 pub struct OwningDirstateMap { |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
52 /// 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
|
53 /// |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
54 /// See <https://docs.rs/owning_ref/0.4.1/owning_ref/trait.StableAddress.html>. |
47954
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
55 on_disk: Box<dyn Deref<Target = [u8]> + Send>, |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
56 |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
57 /// 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
|
58 /// 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
|
59 /// 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
|
60 /// a problem as it doesn’t change the address of the bytes buffer owned |
48567
d1210d56008b
rust: Fix outdated comments in OwningDirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
48069
diff
changeset
|
61 /// by `on_disk`) but touches similar borrow-checker limitations. |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
62 ptr: *mut (), |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
63 } |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
64 |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
65 impl OwningDirstateMap { |
47954
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
66 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
|
67 where |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
68 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
|
69 { |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
70 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
|
71 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
|
72 let map = DirstateMap::empty(bytes); |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
73 |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
74 // 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
|
75 // 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
|
76 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
|
77 |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
78 // 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
|
79 let ptr: *mut () = ptr.cast(); |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
80 |
47954
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
81 Self { on_disk, ptr } |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
82 } |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
83 |
48069
3d0a9c6e614d
dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents:
48041
diff
changeset
|
84 pub fn get_pair_mut<'a>( |
47954
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
85 &'a mut self, |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
86 ) -> (&'a [u8], &'a mut DirstateMap<'a>) { |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
87 // 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
|
88 // 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
|
89 // connect the lifetime to that of `self`. This cast is valid because |
48567
d1210d56008b
rust: Fix outdated comments in OwningDirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
48069
diff
changeset
|
90 // `self` owns the same `on_disk` whose buffer `DirstateMap` |
d1210d56008b
rust: Fix outdated comments in OwningDirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
48069
diff
changeset
|
91 // references. That buffer has a stable memory address because our |
d1210d56008b
rust: Fix outdated comments in OwningDirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
48069
diff
changeset
|
92 // `Self::new_empty` counstructor requires `StableDeref`. |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
93 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
|
94 // SAFETY: we dereference that pointer, connecting the lifetime of the |
48567
d1210d56008b
rust: Fix outdated comments in OwningDirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
48069
diff
changeset
|
95 // 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:
48069
diff
changeset
|
96 // raw pointer is to a boxed value, and `self` owns that box. |
47954
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
97 (&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
|
98 } |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
99 |
48069
3d0a9c6e614d
dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents:
48041
diff
changeset
|
100 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:
48041
diff
changeset
|
101 self.get_pair_mut().1 |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
102 } |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
103 |
48069
3d0a9c6e614d
dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents:
48041
diff
changeset
|
104 pub fn get_map<'a>(&'a self) -> &'a DirstateMap<'a> { |
48567
d1210d56008b
rust: Fix outdated comments in OwningDirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
48069
diff
changeset
|
105 // SAFETY: same reasoning as in `get_pair_mut` above. |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
106 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
|
107 unsafe { &*ptr } |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
108 } |
47954
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
109 |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
110 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
|
111 &self.on_disk |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
112 } |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
113 } |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
114 |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
115 impl Drop for OwningDirstateMap { |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
116 fn drop(&mut self) { |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
117 // 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
|
118 // value is still alive. |
48567
d1210d56008b
rust: Fix outdated comments in OwningDirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
48069
diff
changeset
|
119 let _: &Box<dyn Deref<Target = [u8]> + Send> = &self.on_disk; |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
120 // 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
|
121 // 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
|
122 // 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
|
123 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
|
124 // SAFETY: `Box::from_raw` takes ownership of the box away from `self`. |
48567
d1210d56008b
rust: Fix outdated comments in OwningDirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
48069
diff
changeset
|
125 // This is fine because drop glue does nothing for `*mut ()` and we’re |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
126 // 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
|
127 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
|
128 } |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
129 } |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
130 |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
131 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
|
132 |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
133 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
|
134 _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
|
135 } |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
136 |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
137 // 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
|
138 // 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
|
139 // particular raw pointer represents a `Box<DirstateMap<'on_disk>>` that we |
47954
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
140 // 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
|
141 // this struct as `Send` too. |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
142 unsafe impl Send for OwningDirstateMap {} |