Skip to main content

_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}