_01_places/place_ops.rs
1use crate::*;
2
3pub trait HasPlace {
4 type Target: ?Sized;
5}
6
7/// Borrow a subplace.
8pub unsafe trait PlaceBorrow<'a, P, X>
9where
10 P: Projection + ?Sized,
11 Self: HasPlace<Target = P::Source>,
12 X: HasPlace<Target = P::Target>,
13{
14 /// Tells the borrow-checker what other simultaneous and subsequent
15 /// borrows are allowed.
16 const BORROW_KIND: BorrowKind;
17
18 unsafe fn borrow(ptr: *const Self, p: &P) -> X;
19}
20
21#[non_exhaustive]
22pub enum BorrowKind {
23 /// Other borrows are allowed (like `*mut T` and `RcRef<T>`).
24 Untracked,
25 /// Other `Shared` simultaneous borrows are allowed (like `&T`).
26 Shared,
27 /// No other simultaneous tracked borrows are allowed (like `&mut T`).
28 Unique,
29 /// No other simultaneous or subsequent borrows are allowed (like `&own T`).
30 Owning,
31 /// No other simultaneous tracked borrows are allowed and `drop` must be
32 /// called before the underlying memory is reclaimed (like `&pin mut T`).
33 UniquePinning,
34 // maybe other things?
35}
36
37/// Read a value from a subplace.
38pub unsafe trait PlaceRead<P>
39where
40 P: Projection + ?Sized,
41 Self: HasPlace<Target = P::Source>,
42{
43 unsafe fn read(ptr: *const Self, p: &P) -> P::Target
44 where
45 P::Target: Sized;
46}
47
48/// Write to a subplace.
49pub unsafe trait PlaceWrite<P>
50where
51 P: Projection + ?Sized,
52 Self: HasPlace<Target = P::Source>,
53{
54 unsafe fn write(ptr: *mut Self, p: &P, x: P::Target)
55 where
56 P::Target: Sized;
57}
58
59/// Allows moving a value out of a subplace. This uses `PlaceRead::read` to read
60/// the value.
61pub unsafe trait PlaceMove<P>: PlaceRead<P>
62where
63 P: Projection + ?Sized,
64{
65}
66
67/// Allows dereferencing a subplace that contains a pointer. The returned
68/// pointer will only be used for further place operations.
69pub unsafe trait PlaceDeref<P>
70where
71 P: Projection + ?Sized,
72 P::Target: HasPlace,
73 Self: HasPlace<Target = P::Source>,
74{
75 unsafe fn double_deref(ptr: *mut Self, p: &P) -> *const P::Target;
76}
77
78/// Drop the contents of a subplace.
79pub unsafe trait PlaceDrop<P>
80where
81 P: Projection + ?Sized,
82 P::Target: HasPlace,
83 Self: HasPlace<Target = P::Source>,
84{
85 /// Should call `drop_in_place` on the subplace.
86 unsafe fn drop(ptr: *mut Self, p: &P);
87}
88
89/// Clean up a pointer whose contained place has been moved out of/dropped.
90pub unsafe trait DropHusk: HasPlace {
91 /// Drop the pointer but not the contents of the place (borrowck takes care
92 /// of that).
93 unsafe fn drop_husk(ptr: *mut Self);
94}
95
96/// If at a coercion site an expression `e` has type `T` but type `U` was
97/// expected, and `T: HasPlace` and `T::Target: PlaceCoerce<T>`, then we replace
98/// `e` with `@T::Target::Output **e` and repeat this until types match and
99/// raise an error otherwise.
100pub unsafe trait PlaceCoerce<From>: HasPlace
101where
102 From: HasPlace<Target = Self>,
103 From: PlaceDeref<NoopProj<Self>>,
104{
105 type Output: HasPlace<Target = Self::Target>;
106}
107
108/// If `X: PlaceWrap` and `X::Target` has a field `field`, then `X` itself
109/// acquires a virtual field named `field` as well. That field has type `<X as
110/// PlaceWrap<proj_ty!(X::Target.field)>>::WrappedProj::Target`, and
111/// `WrappedProj` is the projection used when we refer to that field.
112pub unsafe trait PlaceWrap<P: Projection<Source = Self::Target>>:
113 HasPlace
114{
115 type WrappedProj: Projection<Source = Self>;
116 fn wrap_proj(p: &P) -> Self::WrappedProj;
117}